diff --git a/.gitignore b/.gitignore index d77203170ab..1a645d9fac8 100644 --- a/.gitignore +++ b/.gitignore @@ -45,13 +45,18 @@ deps/awsapi-lib/ git-remote-https.exe.stackdump *.swp tools/devcloud/devcloudbox/.vagrant -deps/*.jar -deps/*.war -deps/*.mar *.jar +*.war +*.mar +*.zip +*.iso +*.tar.gz +*.tgz awsapi/modules/* !.gitignore .classpath .project .settings.xml .settings/ +db.properties.override +awsapi/overlays/ diff --git a/CHANGES b/CHANGES new file mode 100644 index 00000000000..a745a467c3b --- /dev/null +++ b/CHANGES @@ -0,0 +1,37 @@ +Apache CloudStack (Incubating) CHANGES +====================================== + +Full release notes for each release are located in the project's documentation website: http://incubator.apache.org/cloudstack/docs + +Version 4.0.0-incubating +------------------------ + +This is the first release of CloudStack from within the Apache Software Foundation. + +Build Tool Changes: + + * The project now uses a combination of maven3 and ant for building + * License header auditing is now implemented via the Apache RAT Maven plugin + * Some integrations have been disabled in the default build, due to the license types of our dependencies (See README.md for details on how to build with the optional capabilities) + +New Features: + + * Inter-VLAN Routing (VPC) + * Site-to-Site VPN + * Local Storage Support for Data Volumes + * Virtual Resource Tagging + * Secure Console Access on XenServer + * Added the ability to create a VM without immediately starting it (via API) + * Upload an Existing Volume to a Virtual Machine + * Dedicated High-Availability Hosts + * Support for Amazon Web Services API (formerly a separate package) + * AWS API Extensions to include Tagging + * Support for Nicira NVP (L2) + * Ceph RBD Support for KVM + * Support for Caringo as Secondary Storage + * KVM Hypervisor support upgraded to work with Ubuntu 12.04 and RHEL 6.3 + +Security Fixes: + + * CVE-2012-4501: Apache CloudStack configuration vulnerability + diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000000..61ebadfdc3d --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,226 @@ +This document describes how to develop, build, package and install Apache CloudStack +(Incubating). For more information please refer to the project's website: + + http://incubator.apache.org/cloudstack + +Apache CloudStack developers use various platforms for development, this guide +was tested against a CentOS 6.2 x86_64 setup. + +Refer to the [wiki](http://cwiki.apache.org/confluence/display/CLOUDSTACK/Index) +for the latest information, especially: + + - [Setting up development environment](https://cwiki.apache.org/confluence/display/CLOUDSTACK/Setting+up+CloudStack+Development+Environment) for Apache CloudStack. + - [Building](https://cwiki.apache.org/confluence/display/CLOUDSTACK/Building) Apache CloudStack. + +## Setting up Development Environment + +### Installing Tools and Dependencies + +Install tools and dependencies used for development: + + $ yum install git ant ant-devel java-1.6.0-openjdk java-1.6.0-openjdk-devel + mysql mysql-server tomcat6 mkisofs gcc python MySQL-python openssh-clients wget + +Set up Maven (3.0.4): + + $ wget http://www.us.apache.org/dist/maven/maven-3/3.0.4/binaries/apache-maven-3.0.4-bin.tar.gz + $ cd /usr/local/ # or any path + $ tar -zxvf apache-maven-3.0.4-bin.tar.gz + $ echo export M2_HOME=/usr/local/apache-maven-3.0.4 >> ~/.bashrc # or .zshrc or .profile + $ echo export PATH=${M2_HOME}/bin:${PATH} >> ~/.bashrc # or .zshrc or .profile + +Note: Tomcat 6.0.35 has some known issue with Apache CloudStack, please use Tomcat +6.0.33 from http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.33/bin + +### Configure Environment + +Set CATALINA_HOME to path where you extract/install tomcat, put them in your +.bashrc or .zshrc or .profile: + + $ echo export CATALINA_HOME=/usr/share/tomcat6/ >> ~/.bashrc + +Fix permissions on CATALINA_HOME: + + $ chown -R : $CATALINA_HOME + +Generate you ssh keys, useful for ssh-ing to your hosts and vm etc.: + + $ ssh-keygen -t rsa -q + +Apache CloudStack uses some ports, make sure at least those used by the management +server are available and not blocked by any local firewall. Following ports are +used by Apache CloudStack and its entities: + + 8787: Apache CloudStack (Tomcat) debug socket + 9090, 8250: Apache CloudStack Management Server, User/Client API + 8096: User/Client to CloudStack Management Server (unauthenticated) + 3306: MySQL Server + 3922, 8250, 80/443, 111/2049, 53: Secondary Storage VM + 3922, 8250, 53: Console Proxy VM + 3922, 8250, 53: Virtual Router + 22, 80, 443: XenServer, XAPI + 22: KVM + 443: vCenter + DNS: 53 + NFS: 111/2049 + +### Configuring MySQL Server + +Start the MySQL service: + + $ service mysqld start + +### Getting the Source Code + +You may get the source code from the repository hosted on Apache: + + $ git clone https://git-wip-us.apache.org/repos/asf/incubator-cloudstack.git + +Or, you may fork a repository from the official Apache CloudStack mirror by +Apache on [Github](https://github.com/apache/incubator-cloudstack) + +To keep yourself updated on a branch, do: + + $ git pull + +For example, for master: + + $ git pull origin master + +## Building + + +Clean and build: + + $ mvn clean + $ mvn install + +In case you want support for VMWare, SRX and other non-Apache (referred to as nonoss) +compliant libs, you may download the following jar artifacts from respective vendors: + + deps/cloud-iControl.jar + deps/cloud-manageontap.jar + deps/cloud-netscaler-sdx.jar + deps/cloud-netscaler.jar + deps/vmware-apputils.jar + deps/vmware-vim.jar + deps/vmware-vim25.jar + +Install them to ~/.m2 so maven can get them as dependencies: + + $ cd deps + $ ./install-non-oss.sh + +And build them with the nonoss flag: + + $ mvn install -Dnonoss + +Clear old database (if any) and deploy the database schema: + + $ mvn -P developer -pl developer -Ddeploydb + +Export the following variable if you need to run and debug the management server: + + $ export MAVEN_OPTS="-Xmx1024m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n" + +Start the management server: + + $ mvn -pl :cloud-client-ui jetty:run + +If this works, you've successfully setup a single server Apache CloudStack installation. + +Open the following URL on your browser to access the Management Server UI: + + http://localhost:8080/client/ + +Or, + + http://management-server-ip-address:8080/client + +The default credentials are; user: admin, password: password and the domain +field should be left blank which is defaulted to the ROOT domain. + +If you want to contribute your changes, send your [git formatted patch](https://cwiki.apache.org/confluence/display/CLOUDSTACK/Git) to: +https://reviews.apache.org/groups/cloudstack or contact on the developer mailing list. + +## Packaging and Installation + +Before packaging, please make sure you go through the "Building" section above. +This section describes packaging and installation. + +### Debian/Ubuntu + +To create debs: + + $ mvn -P deps # -D nonoss, for nonoss as described in the "Building" section above + $ dpkg-buildpackage + +All the deb packages will be created in ../$PWD + +To create an apt repo: (assuming appropriate user privileges) + + $ path=/path/to/your/webserver/cloudstack + $ mv ../*.deb $path + $ dpkg-scanpackages $path /dev/null | gzip -9c > $path/Packages.gz + +Configure your system to use your new apt repo: + + $ echo "deb $path ./" >> /etc/apt/sources.list.d/cloudstack.list + +Installation: + +Install needed packages, apt-get upgrade for upgrading: + + $ apt-get update + $ apt-get install cloud-client # management server + $ apt-get install mysql-server # mysql server + $ apt-get install cloud-agent cloud-system-iso # agent (kvm) + $ apt-get install cloud-awsapi # awsapi server + $ apt-get install cloud-usage # usage server + +### RHEL/CentOS + +To create rpms: + + $ mvn -P deps # -D nonoss, for nonoss as described in the "Building" section above + $ ./waf rpm + +All the rpm packages will be create in artifacts/rpmbuild/RPMS/x86_64 + +To create a yum repo: (assuming appropriate user privileges) + + $ path=/path/to/your/webserver/cloudstack + $ cd artifacts/rpmbuild/RPMS/x86_64 + $ mv *.rpm $path + $ createrepo $path + +Configure your system to use your new yum repo, add the following to /etc/yum.repos.d/cloudstack.repo: + + [apache-cloudstack] + name=Apache CloudStack + baseurl=http://webserver.tld/path/to/repo + enabled=1 + gpgcheck=0 + +Installation: + +Install needed packages: + + $ yum update + $ yum install cloud-client # management server + $ yum install mysql-server # mysql server + $ yum install cloud-agent # agent (kvm) + $ yum install cloud-usage # usage server + +## Notes + +If you will be using Xen as your hypervisor, please download [vhd-util](http://download.cloud.com.s3.amazonaws.com/tools/vhd-util) + +If management server is installed on RHEL/CentOS, then copy vhd-util into: +/usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/ + +If management server is installed on Ubuntu, then put vhd-util into: +/usr/lib/cloud/common/scripts/vm/hypervisor/xenserver/vhd-util + +Once, you've successfully installed Apache CloudStack you may read the user manuals +and guides which contains technical documentation for Apache CloudStack. diff --git a/INSTALL.txt b/INSTALL.txt deleted file mode 100644 index 87404780e06..00000000000 --- a/INSTALL.txt +++ /dev/null @@ -1,70 +0,0 @@ -This document describes how to set up and configure a single server CloudStack development environment. If you aren't looking for a development environment The easiest way is to deploy CloudStack from RPM package, building CloudStack from source is for developers. This guide is all about building CloudStack from the source and installing directly from there . This guide is suitable for you if you want to develop the CloudStack. - -I have tested this procedure on Fedora Core 14 - -Step 1: Install the tools and dependencies: -For fedora the package names are ant ant-devel, openjdk, openjdk-devel - -Tools: -yum install ant ant-devel openjdk openjdk-devel mysql mysql-server tomcat - -Dependencies: -yum install jakarta-commons-collections jakarta-commons-dbcp.noarch apache-commons-logging.noarch jakarta-commons-pool jakarta-commons-httpclient.noarch ws-commons-util.noarch glibc-devel gcc python MySQL-python openssh-clients - -Tomcat: -Download tomcat6.0.33 from http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.33/bin/ instead of using distribution's default tomcat. Set CATALINA_HOME and CATALINA_BASE to path where you extract tomcat in environment variable, it would be better off setting them in .bashrc as it will take effect every time you log in. - -Note: Tomcat6.0.35 has some known issue with CloudStack, please avoid it - -SSHKEY: -Run: -sh-keygen -t rsa -q -to create sshkey for your account if you don't have one - -Step 2: Configuration - -Start the MySQL service : - -# service mysqld start - -Step 3: Get the source - -$ git clone https://github.com/CloudStack/CloudStack.git - -For subsequent pulls, do: -$ git pull - -Step 4: Building, testing, and deploying CloudStack using Ant : - -Ant is a Java-based build tool designed to be cross-platform, easy to use, extensible, and scalable. Ant is controlled by providing a text file that tells how to perform all the stages of building, testing, and deploying a project. These files are build files, and every project that uses Ant must have at least one named as build.xml. You can see build.xml in your CloudStack source. - -Type to build CloudStack : -$ ant clean-all build-all - -Type to deploy mgt server : -$ ant deploy-server - -Type to deploy database : -$ ant deploydb - -Type to run mgt server: -$ ant debug - -If all of the above process is successful. You are done the single server CloudStack installation.Now your CloudStack Management Server is running. - -Open your browser and type the bellow url in address bar: - -http://localhost:8080/client/ - -OR - -http://management-server-ip-address:8080/client - -You can see CloudStack Management Console page via a web browser. It will show you management consle login page. You can use the default username and password and leave domain as blank. - -The default credentials are “admin” for user and “password” for password. The domain field should be left blank. A blank -domain field is defaulted to the ROOT domain. - -NOTE : This document is very basic CloudStack development installation. If you are very new to CloudStack and want to feel the power of CloudStack very quickly in RPM based distro, this document will guide very clear step to get it done. Since I am new to CloudStack, I doing this documentation by learning from community. I will keet update new information in this guide to make it more valuable resource. - - diff --git a/KEYS b/KEYS deleted file mode 100644 index b399d9cb662..00000000000 --- a/KEYS +++ /dev/null @@ -1,288 +0,0 @@ -This file contains the PGP keys of various developers. - -Users: pgp < KEYS - gpg --import KEYS -Developers: - pgp -kxa and append it to this file. - (pgpk -ll && pgpk -xa ) - >> this file. - (gpg --list-sigs - && gpg --armor --export ) >> - this file. -Type Bits/KeyID Date User ID -pub 4096R/CC56CEA8 2012-08-06 [expires: 2016-08-06] -uid Chip Childers -sig 3 CC56CEA8 2012-08-06 Chip Childers -sub 4096R/A99A5D58 2012-08-06 [expires: 2016-08-06] -sig CC56CEA8 2012-08-06 Chip Childers - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG/MacGPG2 v2.0.18 (Darwin) -Comment: GPGTools - http://gpgtools.org - -mQINBFAgC58BEADAGUUl5EP3pNsVbZMHejGbImIDvbNCkuGCmiVoC154k7FO7YjH -PnbB7kyzfyfsj8eA+mgHHvbzOTk/7dDeaudL561FfsTSxyeVt1ctzBYh9z2V2EMa -9mv48c226QXRf/GInzLS1iD1bOPq9H5RywW4h1u/JqT9KiuBuwowliDlHRornQRg -dhxnjITO6xOhQajqfVXQ1Kz3DcbU9OydfPLKshbfRJC6U5dhGk4AGWKsAJHJDlzj -SPswcJrkuDo0GB9o+nPYrKFRJZy5AyDtr7gmRz6EiGjlZWIf38KxfeNcE6oQPP+7 -9Exlx1ZnWT5Uv/8yU2lgtzhi7/zHw+uB6Ujh0+zCcVgS2Y9ldsA7T0b/Tvlp/Yz4 -hYUMVI6tPPSgehIzRMT4Ym4AcOG/0h5YtecSrOdHIl00htfr1Nj9vIAv8FurebVR -fnfaYbJNKgN3MJLdMSvmlaxvZipIZ6EbWU2BUl7mtZR8zsIoMJedxx9w38UBwdhp -jlxtH5ibZP/WKmIf2hqB4sYrwDioZailjRreNlC5drkljcOGoofXgu/Ahu6dZGHu -4sVH/g+8YhQt7zVs6ytaGLTud33NAELSn15DRrfxQm2sEFhHFKW8Lg0LvjB1RtiM -l2CmFCXk0MMi9IrU4/7q9E7teatztPBcF6Y+Afs16MqUfR81elyPF7YQlQARAQAB -tCdDaGlwIENoaWxkZXJzIDxjaGlwY2hpbGRlcnNAYXBhY2hlLm9yZz6JAj0EEwEC -ACcCGy8FCQeGH4ACHgECF4AFAlAgEF0FCwkIBwMFFQoJCAsFFgIDAQAACgkQw6OS -dcxWzqg0eBAAoHiNFFPNR0zdOELqz0luaTaNNUEit+LBHB1eA63hwY4PplfkOCg+ -UT2lojkZtsiNYuPi++Sub11+HQpVf4uDAGy5VtyIUl/tO3qRmULcJJwoXrYqHxd9 -xrrWYRhasKGNqPEB873UxMPgWVZYcKPRgwZKXUgLl7Dub5iCSVN/lCto5D45R8jA -RzeTjkNvyA+ZPUiblCuKZPSqd4WCN5MRG4muN3+5hwCL6xyrXIvsPkaZXQqhjw0Q -89PUSHhruoHzAi41lscXPF1ap93qvJ4QO12YM9GCQxLRyUOJStLj2OugOjVN/d0q -1ryuBo8ND/W/gYjzIPAQ2U5qkQEjQB/vfuIGl8Gn8s5XA9KtXHqVwz2hbGMpIoCM -0+27JEikrQOitfw86f0aWT1kaceMti7N2ECDEwjsnFf0Uz8dEJ2eInKZrlwgmM0S -/K2gf8/9pbhZ1X9LDYkATCqPzFRLyOuJeHNwcxSDPiWAALoPN57jLJ1702XjGcQt -NBf1p+ylXmdzZjcUz9mKHIEEX7unwp74AVEOyIXuLlyScDR9qTSHhVzCpWQntl6u -0WQmbaoLdAfhu5b80raMdnAbyGQIVtNV4RU0dP8IowkE7cHekHb3NE12K7n3Yx+d -msIXAMsvWx5scfS0HAqIauaA/Sg26lXwj6w60KB+wE1xA2VAWGunSP25Ag0EUCAL -nwEQAOQptLWHnr8uzTZlaRr1N6Aabvz3cLFXf4HCJdWMx9vShPuwWZqrJw4CAnVj -hZA/7NgyBXfBVfcW4Yno0KkHkpKsYy1pYUXIeBDX1FTLZ5H4o7Yv79RaHNl3kgX8 -OodIMGvAee2z4twkniO/u9mnjy1i56hoeQLRVfZZ25Rnlr5PnRdFcqBjMC91i6nr -XdS47Lb1Ttln0yPYtN9j5sD09HZiuCY/b685nB/UlxKhTsE2XfPjZFuBznnOl01/ -FLX8Nn/SeEySdI0gOlzLXU3EAnp0k1OLDXMXC8/EQ/bB4VIwuS4Vu3RmKA0kikgm -nKeuPOTfCpBzzyo/NXCop1Ik/iKgVkp12wRwMp/K5fDg88ib+A8Naxdu25dQCUxH -pJJJ+KwhNf/UKVGpUZOMDAYmUCfisNbulOeS0RMKNzwMXaZzQSvquO8GSlnQ0aal -7Jjl/X/x1boS1dfMAlEeC7jQOm4O4HqSGPEIdoyNbUKupFjytYq3HZ/WMF79kyFh -Xx7khOjiCtopc/sAasFCMa+55/OBN6FThQ4f97UdlyEVxnMADnqOH5uQH5oJ5Vck -k35JOAXWY2fbZSkvKLj7hUZhIx5ja7l4uEnAkM2SxXS+mW9oRfX+pxRAEziUMSaZ -VuGcHkiO/E8viWxtKWbkQw5Ii6OpNLy9wF7YiVSXr7b27lm5ABEBAAGJBEQEGAEC -AA8FAlAgC58CGy4FCQeGH4ACKQkQw6OSdcxWzqjBXSAEGQECAAYFAlAgC58ACgkQ -lD2YH6maXVgyUhAAhWGhG52edHVMELz4wWaqiMKKNPM6GKsI0ZvmaroF0EWt1n9U -TGDyXK+VX/7WXIhqWPdsT390zmwV0bAdXdziPoeQ7DlEz74IRzMBsyEZwMtZ5Q83 -JGDmhjCr3NBVgckzZOl0JXtzyQovtLvCN88WCUIuNaZ2GI6VG8wS3prsKOL9hRNx -y4NNPpCW/QB1/N4A3QlBdKSGyTKCg9VsMwvtZmBdupRipzj2X2DsTOr16TGU4OVW -GNkZ8rUIC6vG7iQctLO8efml3heQU06HJoT+uTZMfXyd7wxHc6SOAENy4ezF62Fd -O9+rtZkE3u0oiW5HUEO4DcE+ufA+Rz/pK6RV65AArb3j6yeX7/VefTGev4SyV+dU -9gplLiXgNEgTfr70uBg+cGV5nxUp0O7ooHMn1g2CnVIkBdPts2rU0wwI5JipsJJ0 -DpK+1x51D7cpUcQ4u/oWtUGHPMVIxXjDWVfwzs9QGy4H0/lqD8LOStuWkeY2IC08 -1ErnY/1TWhmXX7pieh0Zjn1uxi49nxJ9qW0u70CTSzJzz+/17G+f1n9rauKJqVOy -HIGU1TgJ7DjPiwvmMllfQFpRNf/5SV0/tjvsnjzN5YCjN4YaEbVajc9H/Wi8bVNg -ANb5v5FLuhAi04DO0k3bWewd9KE3H7I2uQNaNck/iuYEL6ImAPMA0GUzIbbkxA/+ -Mp4fBbo/i4JpDXEvg8Umeg0wx+otI2ogYFREZjYBWH8txMfGXKVjIfBsFclCm47v -H9wDJ7ISeOR1atWDjHYBE4J2JNqJJREIecztFPQBTo+YUgP6/zDO2RxeZRGYP1rO -+Eld5++kbFEWgi1kWxTKwMlomcoP6hdabA8v8KNZLxRGrKYfE+JMU+PHrfBvO2Ql -4BZ1kmmTaWmGXrgQgpJeWiirF8Ptg2Mq8rCfXnFbOp89ZRNyFDV2Fgyw3BPbPPXE -aygCwpRgHgUrp32gBAGdsdghNn8kN0DFygZKE0kRc6hR7ALiQWoTbA/G/BJjpJQt -RhR4k58e2kWh1uuyFaxcB+Vp/6HXYIe6o8fhX8jwVM47WbINFGbvaz1gGpGzJCY1 -HJBwTMu5IgQ8n69Gs7DCDTVqBOqiDKtdQyZBheWCsIJUkvBHtxkUb7K0kcIA3Fet -46k2GFOEkHCxbKpjeFhcW4atmEShOViiGKVR+g689feVQB6+mI9O4fXmsGO4Zq/k -mEku0Eg95q3+ugVpz8DLctnlvIHVdf6RPieojBKbqPu/34iJqenHmeQUy1TkRKIx -ZEX2mjtW/Tz5VnUX/MUFA67sGIpGJMsvr2sk3Zyovl7GVfsq5K2UqK5pRc2rO8zt -QHVJ58ybqkmx2NgDgmi1gvsoV51mn6TTVs1S/stCtW4= -=eCNG ------END PGP PUBLIC KEY BLOCK----- - -Type Bits/KeyID Date User ID -pub 4096R/DB3ECA42 2012-08-07 [expires: 2017-08-06] -uid Wido den Hollander -sig 3 DB3ECA42 2012-08-07 Wido den Hollander -sub 4096R/50E9D98F 2012-08-07 -sig DB3ECA42 2012-08-07 Wido den Hollander - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.11 (GNU/Linux) - -mQINBFAg4ogBEADPUAOmj/KdLjp5Wz8oW5+fnx3gnhVABh1Xg5Uf36tDCLogSMya -Y9S8lZb8PgvtkK6fOqUCoViUvXAWM5/k7JbIv70cWGc+M4XgZTnI6GWlz08EkzNT -/DX4Y+OAks602KYLXVepI4SdpCKaZJK14Az48cfzFEZDmzMuNtS/sQhXQZSXe7pu -7pBPpQ2GP1aYqGRBYTkMD9fjQAM2U3qJ/5K0AzeIciOI6QxD+h2fIBMnu+XV0g0C -2SG6UVy1RBVYzylWZ1p63brFtskjDnPoXrjXOx3iUxV/pEH7nKziHDolMShp+bni -Cnw5QcrqkBQls84d+cdteJ40ZzoyiWg0isIsxLMA2L71WkziJZkigqqQ8O/HI4Dl -3/mz1I5R2hphorkBPVc5ZAirhB38FqLgW1eH0rd/TJR428APYkbh6QnWRCLfGl7C -UsdYmpUaNjFZFrHCBoyA9p8pNzsJuZBVIBa+xheJk71HT5zeAk+uDPuNJH0Tc5qc -E7XRxaaj0QQxBlmkgdW0kMIO93jjrCTuzmgJMAEym1KSPiQTJmr0fUuxLEL7gTy3 -a0I9sEnhbyn+yl6KZp0Ey/pZ8UOLD4TBwx1r1kXWXD7evTs0CCoPeyP0GRyjlhqH -WLlhEH2MtSWn+0SQIHiGh8XNh7ToySCquk1jslV89aX/sezRLJuly0k2hwARAQAB -tCNXaWRvIGRlbiBIb2xsYW5kZXIgPHdpZG9Ad2lkb2RoLm5sPokCPgQTAQIAKAIb -AwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AFAlAg6F4FCQlmrtgACgkQAZtYLds+ -ykLICxAAlSVW5i3yIuBhnjIpCPPkOtABJEz2zImyl3VNJ/JuRT1nOmcvsu39MALj -m93qsVvZOulyiYHMKg61QWHRXHimqdJe7wUH64Fm/Gf85jqzf6Db0HFCyR4ADHKH -8XFNNiGctutPAwDeUaUGFYE3RtDEU105z/SovfzFrLOSLQ9o1+48T0Dm5iCezHr1 -3AF7HJpbQ9D0ng5CTEK2YhYHAS6rPf48MJ949WQoSrLt1X3WEu62Bgcuwa8Ph9AM -7Y4K+uVNWNft+xK+SJml0pkYBTwc+tIXhT6tirnFa731g5wKDLIpTc5OWYvirO3w -EO+G0kuZsDRyQTqCo1DBax30xVazNKQ1/OTDZpVAkkejCqrh7UY4tc2C2FL+9V0b -I6oeysYZpO23CC92Qe5NESavWOUGl9v3rzRCON2rkkDEi8jFCKGsJIoL8S6LjeDn -b0JASbXhYhZMmZY1QwSKvlbnhQkxPb0Ww3jALQV31AWTwN9ACS0/gwh1+gCE+zvm -paoD3yGyZZbTOUx4jQq0diMpDRsxboqsKzPpUMCL7w1YNQpPH4KHNiFGJzLsL1LF -+kwXVLq0hJjblKr0H5hfbBLODG1ZgOC5GkkcMcM73PDq4zOKgGW8O+yrkPc2Rx0/ -ZAP117yP5RlgL2LLA1H0EgS2TKZanM9MxwBhS+YAV/e+hWEPpCa5Ag0EUCDiiAEQ -AKnpED7QljHFLNrzftOF67EOcCeu/tew+gaok135taDgsKW7FMfjF+uQje0nloM8 -482TSFRJAp74fFiKjNUPXcGNaUU2XwDiSDsnuzqRStzJ58jxVcGbnV8nHCw4X+0w -BQVo+PCaj5f8HAFdiZ4EHRC/P3BuH9QLNEY9zziPw0LG5vn+0Lr0DTsdWQl2vWWc -SIUNd+QnQ0icnSY3FLdxyscqHkUCOtu7NxI5WzdjtaFvgxZbPYJQHfm7B3OAJmg7 -/Gn4YSbN2p78sYLKfKu7YoYG1+wP8cJMHgYM03b7WQgHqII/v6RCNRDtT1k1Hfw2 -Dxid3IWkd8JUlwJFvnAL2sBgHqAt4xtooRkHcAnbcH9cO88ULgqWIfIEYosd/3/v -qvWTKZb/9B0p61gq6yOGOs1swAEWDdkkAAZJK6O0O5x/7J005uX3W9H8J2DqJQYK -jvp8Fph1sv0HVb+AfxhEtS/wfw34iaebNANMy5e369kt9oBXISubksQwgKFqPcsE -xteeyEhZ3qZUBmcTjl9PjrgFn2fMXoMRF9DB19dDFXISvg3tyJ+FCe+/Kppn6u+a -X7e0AltGLMBmfs1rcTPkmAFJglL5zi994iIXDv7/KWxX9QQC5BRICm5pSL8inWoO -6mU0cD5F9FrmkrfEVV+Ajmy/cH9UIiOJijdK7e/ImxShABEBAAGJAh8EGAECAAkF -AlAg4ogCGwwACgkQAZtYLds+ykI73Q//fYNKhEAvrFyF2d8OwVqHhzifIqsRycOg -D0Ib3tOkeNgwZYI+x6QIiYFHQalcMUFhwUea7RKYkW17Rhpj6W5hj7ie5x6cvtzI -5CeArcvoBj0KIRGUvsRl9XplXdaBhmBGibvEQBac2oCIVCBtTbsjkQlXPs+Q2SaJ -kyL8rbdmt06Tsc3iwN+ZjPGIluifaacvurJH8tntCWdhnFKwSwfsa3ZfJwuf3O2Q -J1q7JwYOwQbTR3K5CAyZ0HVYksiIoUqy6IzYvNmilAx2hkVCm2HjWXEvTwjSd709 -yXBbm7X9JkB0RYSzpHEBqL1aB7GMe/pCeGLgcGRoA0ZyYXMoM7/gnE/ZCDG2fWGm -JZZ0LJ8QVlZq4nG4lkco7mZqDOycyA68nfbpGaSXhJ7iKbdk4DT0OMr//RlHsiif -AZFM2ppJ5cOmJ9USMkgyHziS6zexM0bYzzPJsLgoq2rjelmzE0pu7NoIcOu3KlkS -HCLDLqIZEYg7EySBVgqJ67FlnpAMY1IaUJN4rYQ4LQEq0uUfmmhZnlp4qQQnZjFR -MrkLZNjHiv8v6JGklVurAQstvZBQXrUUH+/JhJM0U6gsPzgsn4DlpxFyr3nM1aaJ -uHR4OoUFg2G1Hbm7k4eb1SFT1jPEe3is4Oc8t1ORRfSBIH0FfLF1ylLFpSma5q+3 -HpWraBFdP78= -=I9dG ------END PGP PUBLIC KEY BLOCK----- -pub 4096R/2908DED2 2012-06-29 -uid John Kinsella -sig 3 2908DED2 2012-08-07 John Kinsella -sub 4096R/26F845B7 2012-06-29 -sig 2908DED2 2012-08-07 John Kinsella - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG/MacGPG2 v2.0.17 (Darwin) -Comment: GPGTools - http://gpgtools.org - -mQINBE/uBAgBEAC9f6Cjh4vS1eY8g5O9rX1P6qhUWfoh8e1stAuKWVUsNfR3C4w3 -BZef4dDTMMHaXfJnZ7oFsMUghjzKI1/Fy2rhJ99ZEf8NgxYyy5nR4TUfHdlXAat0 -tF3amfGzruJoVorybFEiGVIsYcuDPVxC7jVXGgkaMZ9PD1pyD4cSGYafObDuVr5z -MM0P6X1C4dT/pShiKOBhuX4XJdGk910uEtniWHWaIHIN3KBCQL7xgw0GxRPAmoTY -GPmt1Ee2N8E+o2UzgvqAc+iQH6z1iqHakCCkH/707XscpUrr00bPHk92lgQrzGOw -kmXUdTipAM9wqzPZ6EmtT3WV9uT8HV608VTEvZSHuuYpZdFW4IwWXziZUqx6z8EX -miKlFChHIkeARZgmxdIB3m4r05yU2MG/A4VaixcNGOXAjSaV+EyWXqecMlGJXLbF -rnaGfRshOo3mLG2UE/LI/y/4S0RYVlky0LzWZqihcfL/sT2Tc4OLAN8wKOXhlwd2 -s/68wmzOq+67KT84YTxsixUbS2yBg8nfS6SMz5irWvlELQyeiPkDttuzDxSC8Koz -jR28az1VVkqT88VrRtb3oVyV2T7Za/yYHO/IsrjimgvIA1BKnq6E+0uXZbI5HKkA -/FGTP9N9J3YwW4eFBilXIt47OIkuBgHUwZsBMpLZfWNktLgB2nAIcz2VFQARAQAB -tCBKb2huIEtpbnNlbGxhIDxqbGtAc3RyYXRvc2VjLmNvPokCNwQTAQIAIQIbAwIe -AQIXgAULCQgHAwUVCgkICwUWAgMBAAUCUCCB1QAKCRDqJvTdKQje0hoMD/9Ssbjf -XF3V6of8563Ro961TrU38E7CLjrA8mrwVHllz9ikoXDhXgMfFg7WrtzEs/EHw7xW -iYwJxS2R1mKyu4zP4Qx38TnH++DsLx6n8m5L2uhaMlZCdqaaXm0nWgu1L4ZQv6OR -6BmVnEged98rsIuOfdXqxbe+vxx7kmXxQnBnRIGOfCKce5kqr/uLKFCBTQdKo0Va -WxXwa/2b0MpN7XEollY1O20185wQXxpe7/6k55wi6ZDUiIw7pollMnSNAj/Ic4Cr -CGj5MGzc4uLnRpIjjbfUif0CRfQ8x3s++IR4KDGZbLfLkUAcHrKGV720TEmf3Ym5 -EvSg20M6mbyOGNUlXdZ69aQAkhCTVwbYNC0E83KsV0K48o538SyhnYzQvSnyqHNv -AMYwRXu+9m3lRmO9FqZ69Qm+fap+QUWlEmYZFNzmhH8F5WWC6EqN0e6JDt4RwDlc -taHF9mSpQYLipsD3yfr5tzd4J9AIWItfEcuaKG2r5kVTyUZMp1yu2+ByvnfGna2R -dHJLwCKGvowlTfrcQ/+ic56YEQrIe4Sy7zbsFbKlOzVNoQyk9814kF4My7nzDPwg -M9qwfcW84kQZzh47uYFVz6BDNcDcIUlo6ODGMHs2MM6Oqxo+NfruXwfKZeHIWsvw -CDuqPNRN5oIUK6txqrYr7nj0GUj04W5LltztvbkCDQRP7gQIARAAykm2inv3OUIX -/3KnGeQYluoYa8cWv4lBV/F1x19qcCgpn2GtZFrwm8/1lLUIRHBsxardE36sMCme -bGilXSyH/Him8gHTn3t/i4jy0EWNcBU5B6C0hfG0DZBGvYjxWA22wRxr0x5CReoa -nZYq3lfLSzHjRbbAlZo9hYp2PpOrsPGGYSMWasANIODQ5Ium97TEWm8NyVBX8tdO -jYz3SCR27I1UTPII7iOhrDuWVqV2orBgDcOlMrIdHN1vg5YKWTU4VqTn0gr2Py02 -iB+bW2eENnG8BYNeL+CBrG7guwsvFvNWlN3KbiSdN360qzYmLly5jmIH6baLIGS/ -nCgKPo91r5YY59fM9OxiT8hi/5nidfyy/HrqAp5IO5E9WdjTrBrMpDAm/oWfy/He -8gHjbcuX2bUp0UFgA4bo7ElTEN7clCU6AjX+g+mvGAvzJZOZ/t6jf8bfsd8G1FgU -ND47WPCCKfJyrnbaqAh4chnzsuh2L5Ujrk8l4Y8X50zstybwpPqk60Rednw0N2kh -tcLnMkvNqy6Vmvi0uBkxVonVJi3S/FOc+DJreQwqkc/+vrY+zW0+F3qrtTeP+uWQ -IyeW0wMuZPqXrnfRkoui5BVDzI/CEoWyyTKa2j6CtDGWnUqtIig2BHk0Ux80L0Gy -fBqqeuE5qVnjmPHBagOUsX1qwJ45/+8AEQEAAYkCHwQYAQIACQIbDAUCUCCELgAK -CRDqJvTdKQje0rfmEACqzADegNqY3ds2yyWz2SO/3Ihwsq8UX7n2WHPJdVhcAyzw -Xn463n+5iXYdIGhSeNd14hIHVyab3nZVY2C4Cd1IAK5QUSVkK8tcwKlPM8gHUVSu -ZUx1FBjjDBz5/EThV/f7N9bBrKtJN0DkzzqnGoNbpSsoP+CTk7kxeRmhXlK8lrr/ -ekVt6gtqi2y+sqwWfJXN955oy5aT2c+bQFsBOoKMt/bpLEDD7giVXgKfKJ6+X/Qe -3jW36aPxtW26TTXUBZr6FmhBwmXyCt6tv+/5VeP5R68CK8q10EYDGgjcWmsa8wrr -Xe2ILFA3oUMytXGp3+WbT1MUXDaHUhE+PCugGwyMPw+pXf+ADZMIjESa2lk+mmE4 -Worss4fFHIpXICMkJKRo7P9NAPUMC6u34EMuNEv4XfBd/zalTpAq/vvy6cMPaeAa -Iik1ML6E8YZ3TeKbQoZ++ZQT/MEwSOjrsx61a4yf/bzLvcqppKBxVdtCBsePPgHA -bOXIAKv3iqD9Cq5GxLpSAH9E+KlQpJmVDsR1b15G6jceGyZ20NP2Mf6O8pqY1qfC -p7S7eSiSwAZT56oHx9ULzBAKYvwyyoIVOnc0ddwhLeGq2flP7xSo54oDw4KRlFuu -rHMalutU5/Bc0tFZtdm6DnSnwtg3fBnwgFBeINJCc31xuX474+071mfaQUVO7g== -=BzOC ------END PGP PUBLIC KEY BLOCK----- -pub 4096R/6FE50F1C 2012-05-11 [expires: 2017-05-10] -uid David Nalley (Code signing key) -sig 3 6FE50F1C 2012-05-11 David Nalley (Code signing key) -sig F2EFD0F0 2012-05-21 Christopher David Schultz (Christopher David Schultz) -sig A67F707E 2012-05-21 Christopher Schultz -sig 4C75EA05 2012-05-31 Kevin A. McGrail (CODE SIGNING KEY) -sig E70D2357 2012-08-09 David Nalley -sub 4096R/1E5F6D9D 2012-05-11 [expires: 2017-05-10] -sig 6FE50F1C 2012-05-11 David Nalley (Code signing key) - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -mQINBE+tml4BEADjjxemcIdmFj4CuJYCpHBldoot3oF0Dqvez8ok7KnmNc/jrbgH -rZ6/DYq8SzebTbQSel4bCkLLnaI4Yu3C4Rd2uYPF6EHjs+kM4etKJLOiwfv5/EA9 -l0TYwNldkZaE7Y/B+XDrzQIxCWiWeH8O01EKJxZhjtcmeZYS3n1/gozQmDxNcbaW -QJJn6Vktqek6n30fPGsQl7tZyfnoSTvjDblze/dFSmyJaCeGDfljlwhXfNBFhJct -LxjmbiD21kRZvs9dWJZRFDQhw6g2HZIQ8MXAC6PUhoJgvqeBDUGUr6B7lb1IfTrl -CKBQLKAURZXKmLlRzh3IMTEyKpmV2D80erRf39S3CiRNEYlnn1fHovmnkiV9QLvG -rgjwDcvuw3Y2lBNaQRuSLm55sBmPBVDSU3aABbZfupOntlnV/oIyl32fiF7MAHT9 -8mV4c58urjbJKkq9R/0U/pZxqWOQfnnt/t66hdOe1p5O29c7nW5V0rlNDFAm2GXL -OKhvS/crBfz4gpI7U7KAq5aMA1F0ZgGJwGVs7Lv6uvl9O/4M7/3g5b390yuRzJzw -ZXF41wJC8Zwlw+KJcrcTkzbUjpGoNoblfAOV/YV3WNnJGOs3hL12vktsgADcjl2R -T6x7QAayZQyfaSD1UwXSHBHi7Lh6ABj6zQnlcan/8/j0mEVMe+q/5CkGPQARAQAB -tDNEYXZpZCBOYWxsZXkgKENvZGUgc2lnbmluZyBrZXkpIDxrZTRxcXFAYXBhY2hl -Lm9yZz6JAj4EEwECACgFAk+tml4CGwMFCQlmAYAGCwkIBwMCBhUIAgkKCwQWAgMB -Ah4BAheAAAoJEExw8Ghv5Q8c2kEP/RhSY6cuypHNTFsVWYm6eaxHR5z1duPvwAhf -7LG4QoqaEJwGJSlrDScQA/sAJZli0eswsIDho8e9iywrREWCrsUKnNcZNaw1y36q -vCTwuAvtfW1H6/fNFwErzYHSIOUxYwRoylxVhYSW5renheeHmxsLtKqLavo+MDV+ -Shr/CGcnVypbW8MrcL0q6OWb+eCJUsB0JIotXRitTGrCV6ulyOWSnq0CXT3EkrT4 -rkXf9dINoAKzqoF5UE+9oGFJxQFFEY3ppgh9p1qaDHTzoKwrVxp+ssBNm7N1CAff -JIb4b2MoWeNuK6lZPR24dGhsxBIZPn9Nlxzczuvbb+lUDvvA8gedYcSTOe5x/7k8 -J3Niu7S50HP7Y2II2RS5zqTMbJJRVu7nZKQYXjM8pItuTiZqaEwl1QyIfuSfXTbf -i35IWO+ZHpMYqUGeAlugIquFRmF50YBMnqm104Gft1DUm92eb5si3gXRNxrH2t0Z -+yHb1iD2873WrhMatgSmpcRYZyWsYTUEUhGT2P2+oo3c7YjfqyJ1rx6ilIhvRLao -ooJ83iobbaDGy0C+jQMvIh9jgJ8Ca9Fy6m3jPjxDke9DlSh4P4o0yct8JGHF334Y -6AMk84+FvFh5AiZHqnP/sXdp8NW59sNJPUWSunjrQ1iRSJv0goMso6sjks6w1Hfs -JxpmWXjJiEYEEBEIAAYFAk+6TxgACgkQ9CaO5/Lv0PAGTQCgjR9jnKgClMp5lhY+ -vmeOWrAmTlEAn3aJ/RWKj9OfO98ERRJ/HGcKL010iQIcBBABCAAGBQJPuk86AAoJ -EPOtXJSmf3B+p3MP+wSU/CeCdXuvKTEBj6JtB+GAi7zSFNrBkuu5s7wCnEhr1BQ8 -u6LcP9beLFZstMbouyz6EZU0CdSkxURXZtsVJrDR1hJYuZ8uPSA+gldCmvoU6ECj -xIUIsq2W2fTG5UTSwQ3JXa+mZS+bRByFeCBCSrMxgqlRooRJ9PDOfJyZ6N/RUTpZ -SzhhgSKFs/Uv8xu/as4b2Ec32jpOmZcF5RiKMkp3zYenW01l/E1KM1PRfKTZRv4j -tTqqJELVqoBRM1Z/H/in7VIdSBDoI4K3W9BbDyvaUh5GgzLgwRkc94PTJ2mMEgA/ -EBsKi2VDWU4AZ/CLjlqunqqLfEzdekHF9HC4iZsqjuodWOYzc/ECLE07w1/WAxOG -wR0Kevyf+GdQ6Nq4DfhwGRzNwhsGJBoqLu785kUZ9w9wbv6aGq9/AYtGVAt7g3IA -S/5H6QQZLic3MswAZHDg1dtBgO6Q32UTl0AcZ7qRBRfnhrhqC71rhMAhlGdzld82 -MzFPQbCqAM8dUqIY67Hoyn0c0P+kw73QGcG/MDyIvYrBuu7fmCEq8V4fHaY38awJ -ydlIyhZhrrpW+o10BlbEuoBgDgFkDeynK0lUbusqrhCE/oAUHXfqXfzZ0Chx5EKK -jAcM1Q2/t3WnIPkXn3CAJRTnz7WJ0dN/OETJEvlDAhulUVzRbGCPXJBaxBKMiQIc -BBABAgAGBQJPx/i4AAoJECFN/YxMdeoFCywP/3AmFE+8tDj0VGrosKO7oRXCP6Dk -krfhezVQjDHAuvTMCJpYc71uvBOLOf6jSrSWcmJJXz89LBWRjLl5QpuHpYOLgn7j -90NXmW5tJY3lladQovMhmbnJehgK6POj8glq8jn8fAeKMM3npHxNcvoQ2ivXB0IL -1B0foM/RdyBgFjjFiISZwkDQRXcfaK9lQgQlIWu5Wts+YCMTR5aBrvVYchZAdKaB -q/gtmFjeCGy/d8Pch/hgevQLngap3X4pkldpHy1NtRNg/MqzTP7FjiinNJYUBga8 -rTSeBLhk+X8bfL6FttiruVNTr8oX5RBNJlceV4l06vvvczJtTH/ROj8Vr/Lw4xTB -RKCWmAEzEYwITjpVDK/4U6NeZbIp1Srbi8IHPKHq9IYWiSZLP/fbtBSK418AiECw -A88CS3MA64f3X5i8AkDHV9fMccftTSzt4ovkTm3wrbDiqjfNzi6tfl9wt1Mc1fYh -krIO+OMZoQrI3+7kw52HHoXWs2w28CGYlH16foo/PdylSVTf09MV1uLmYOS/6A8l -1AYAxI6DDORz9qMIvj+jlHeJKDsUrIs2n2OEWnbe1jCJFsVlEHUWLqqBbfdIne8P -T9NX+mJzWhrxfm8XVHQpK8KxITej8Uuigj8W3Od1J/OJ3FfQ2Xzm8pOn0764cSKB -Deu05Hw2S4WgZ82DiEYEEBECAAYFAlAjB7oACgkQkZOYj+cNI1eTIgCfSPvYLhnh -CQXpYDeWn5QsUKO44eEAni3xVhrnCOrpBGWHu5QUX9cJx0yduQINBE+tml4BEADV -omhZSUujC2B/e6ghmTM7p9W4xVkP/OQVWzrNe7JaCkw1KOHeU5pWyQsxYV20jA6g -LZLIDbH3Wf2wWpyOMrvRR8T2ChxLe3IuFY3qMTGeldU5cYDrBRgQ8XDeVGp5qHee -2cbqWTxmSCgf+ux8vdAfw+d1LtyFQT08E7Q3fLLlZ5t1MxfwCl58SqwjyF7IwMvh -vLqDkqS0lcAj7uK8CspUQur7xnfZhB77mjAayPZyZxkZXcJ6ujJzwH1VRoslzQw0 -RjSEOCewQ082PdEcZ/TxRMKKbheKsIRlMmJlP5bQd+bICivGR6JDOyRXNhx8BPhX -jeSiaYjdgLx+LqVzRFkMhQzzD4TdB6EuBgAUo+Qz8hMvXqw64NH2kXA9OsEq2yQn -+RLRTX3Eo9KwNMIwlmqRip+l6MUH+7zHILFohkBDgFAKyL6ExMbNOKts/kmsVQlk -5pznm3+ofZ1zDGeF5072JMLPJQn0cyg3UfGR+raSnn1+Zal6yGwqgZkfm5aGvEzG -jC2hj+Jfl1oGy5cnCk5Jia1wboG3wkxwNRN8sNLjSmv7sdJ87LyHYollvNGUayzt -PwdAlDHQqPEurzO0uy2WSjdEc6ZdBNYNJzDBJhHIy4kET1TxPWpfaHt35slT6tTK -7hvQ7VC1VwwSnqlDcw5VJTjIb9ue5KM5c4XhUgPXsQARAQABiQIlBBgBAgAPBQJP -rZpeAhsMBQkJZgGAAAoJEExw8Ghv5Q8cIAMP/jzbOVGNz/Uuzf/GKCQ4CudS5Ada -RjNHI4ATAcdGqXCKMzPGVVFDdxJF6yGPyq3wQD0FIwmpJGppjNuHk5eJ8UafqAHe -oynr7izB80o2CdYVMoMVa9Um0lALdCigAJQbu6sjQm5mN3qDVBpEcRzffchb/de8 -GcbH2I/iEZ7L+Og73bw3yFXKwGS/vZ/8ZLEh20cqHzwB/4JjnnCLASgpPsaCGrXF -y0NW+Yo0HrN5deEMexYADDGPE2MQAWC5QjEvxm24yiO2q//xAtUUNVrKDXXbnwaN -BvlNzqNc1iCKcXghV8euwNyTF++UwDCT1x5bcAntl3wYHSHKasae3omvmja+Wdfs -iFZHQtzZXgFjPm0C1Y5v1uG+YmzLa0gDX3Lol0n+ANzZNKFSw/zXacyl9wavnUjh -ITiT9WbmXiEc575jUIlkqxP0Sqg8Afpk/tB5PGyan8GbsTVX7EE/l6724ZLyvH4/ -Zuvhhqa4HA6hYwiNuXxoUBmabiMULIBZYdsn9znjRKeh6oeoqRa2C2El46o05sy+ -woXtbjtbPIeSV1o7KUax0tkg2VqeKBW/qXBkyzLbRSC+vsYVpnO5pPqjaBPoqgIw -vWtDEroKvHDVC+T76U+BlKTooOU0sdWGS8x25HbFVUaxOOFEybkZiFZ2cOlADgcj -R5fTvoVeebaUFoTe -=d4EI ------END PGP PUBLIC KEY BLOCK----- diff --git a/LICENSE b/LICENSE index 1394d656fa0..3f01e10f654 100644 --- a/LICENSE +++ b/LICENSE @@ -184,7 +184,7 @@ This distribution contains third party resources. Within the . directory licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows) - Copyright 2005-2010 Thomas Nagy + Copyright (c) 2005-2010 Thomas Nagy Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -217,7 +217,7 @@ Within the . directory Within the awsapi directory licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows) - Copyright 2005-2010 Thomas Nagy + Copyright (c) 2005-2010 Thomas Nagy Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -250,7 +250,7 @@ Within the awsapi directory Within the console-proxy/js directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright 2009, John Resig + Copyright (c) 2009, John Resig Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -312,7 +312,7 @@ Within the deps directory Within the deps/awsapi-lib directory licensed under the ANTLR 2 License http://www.antlr2.org/license.html (as follows) - + ANTLR 2 License We reserve no legal rights to the ANTLR--it is fully in the public domain. An @@ -328,17 +328,17 @@ Within the deps/awsapi-lib directory remain intact in our source code. As long as these guidelines are kept, we expect to continue enhancing this system and expect to make other tools available as they are completed. - + from ANTLR Translator Generator Project http://www.antlr2.org/ antlr-2.7.6.jar http://repo1.maven.org/maven2/antlr/antlr/2.7.6/antlr-2.7.6-sources.jar licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2004-2008 The Apache Software Foundation + Copyright (c) 2004-2008 The Apache Software Foundation from The Apache Software Foundation http://www.apache.org/ XmlSchema-1.4.3.jar licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2004-2012 The Apache Software Foundation + Copyright (c) 2004-2012 The Apache Software Foundation from The Apache Software Foundation http://www.apache.org/ apache-log4j-extras-1.0.jar http://logging.apache.org/log4j/companions/extras/ axiom-api-1.2.8.jar http://ws.apache.org/axiom/source-repository.html @@ -346,6 +346,7 @@ Within the deps/awsapi-lib directory axis2-1.5.1.jar http://axis.apache.org/axis/ axis2-adb-1.5.1.jar http://axis.apache.org/axis/ axis2-ant-plugin-1.5.1.jar http://axis.apache.org/axis/ + axis2-codegen-1.4.1.jar http://axis.apache.org/axis/ axis2-jaxbri-1.5.1.jar http://axis.apache.org/axis/ axis2-jaxws-1.5.1.jar http://axis.apache.org/axis/ axis2-jibx-1.5.1.jar http://axis.apache.org/axis/ @@ -366,11 +367,12 @@ Within the deps/awsapi-lib directory rampart-lib http://axis.apache.org/axis2/java/rampart/download/1.5/download.cgi woden-api-1.0M8.jar http://svn.apache.org/viewvc/webservices/woden/tags/1.0M8_20080423/ woden-impl-dom-1.0M8.jar http://svn.apache.org/viewvc/webservices/woden/tags/1.0M8_20080423/ + wss4j-1.5.8.jar http://ws.apache.org/wss4j/source-repository.html xercesImpl.jar http://xerces.apache.org/xerces2-j/source-repository.html xml-apis.jar http://repo1.maven.org/maven2/xml-apis/xml-apis/1.3.04/xml-apis-1.3.04-sources.jar licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2009 Google Inc. + Copyright (c) 2009 Google Inc. from Google Inc. http://google.com cloud-gson.jar http://code.google.com/p/google-gson/ @@ -381,7 +383,7 @@ Within the deps/awsapi-lib directory licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows) - Copyright 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. + Copyright (c) 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -412,7 +414,7 @@ Within the deps/awsapi-lib directory licensed under the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 http://www.opensource.org/licenses/CDDL-1.0 (as follows) - Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 @@ -802,7 +804,7 @@ Within the deps/awsapi-lib directory licensed under the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 http://www.opensource.org/licenses/CDDL-1.0 (as follows) - Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 @@ -1190,7 +1192,7 @@ Within the deps/awsapi-lib directory licensed under the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 http://www.opensource.org/licenses/CDDL-1.0 (as follows) - Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 @@ -1839,13 +1841,13 @@ Within the deps/awsapi-lib directory STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + from DOM4J Project http://dom4j.sourceforge.net/ dom4j-1.6.1.jar http://dom4j.sourceforge.net/source-repository.html licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright 2004-2011 QOS.ch + Copyright (c) 2004-2011 QOS.ch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -2343,21 +2345,79 @@ Within the deps/awsapi-lib directory use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] - + from Shigeru Chiba http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/ javassist-3.9.0.GA.jar http://sourceforge.net/projects/jboss/files/Javassist/ +Within the patches/systemvm/debian/config/etc directory + placed in the public domain + by Adiscon GmbH http://www.adiscon.com/ + rsyslog.conf + by Simon Kelley + dnsmasq.conf + vpcdnsmasq.conf + + +Within the patches/systemvm/debian/config/etc/apache2 directory + licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) + Copyright (c) 2012 The Apache Software Foundation + from The Apache Software Foundation http://www.apache.org/ + httpd.conf + ports.conf + sites-available/default + sites-available/default-ssl + vhostexample.conf + + +Within the patches/systemvm/debian/config/etc/ssh/ directory + licensed under the BSD (2-clause) http://www.opensource.org/licenses/BSD-2-Clause (as follows) + + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. Redistributions in binary form must + reproduce the above copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the author nor the names of contributors may be used to + endorse or promote products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + from OpenSSH Project http://www.openssh.org/ + sshd_config + + +Within the patches/systemvm/debian/config/root/redundant_router directory + placed in the public domain + by The netfilter.org project http://www.netfilter.org/ + conntrackd.conf.templ + + Within the scripts/storage/secondary directory licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2010-2011 OpenStack, LLC. + Copyright (c) 2010-2011 OpenStack, LLC. from OpenStack, LLC http://www.openstack.org swift Within the scripts/vm/hypervisor/xenserver directory licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2010-2011 OpenStack, LLC. + Copyright (c) 2010-2011 OpenStack, LLC. from OpenStack, LLC http://www.openstack.org swift @@ -2369,7 +2429,7 @@ Within the target/jar directory licensed under the Apache License, Version 1.1 http://www.apache.org/licenses/LICENSE-1.1 (as follows) - Copyright 2012 The Apache Software Foundation + Copyright (c) 2012 The Apache Software Foundation /* ==================================================================== * The Apache Software License, Version 1.1 @@ -2429,7 +2489,7 @@ Within the target/jar directory cloud-commons-discovery.jar http://commons.apache.org/discovery/ licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2012 The Apache Software Foundation + Copyright (c) 2012 The Apache Software Foundation from The Apache Software Foundation http://www.apache.org/ cloud-axis.jar http://axis.apache.org/axis/ cloud-cglib.jar http://cglib.sourceforge.net/ @@ -2453,12 +2513,12 @@ Within the target/jar directory cloud-jasypt-1.9.jar http://www.jasypt.org licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2003-2007 Luck Consulting Pty Ltd + Copyright (c) 2003-2007 Luck Consulting Pty Ltd from Luck Consulting Pty Ltd http://gregluck.com/blog/about/ cloud-ehcache.jar http://ehcache.org/ licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2009 Google Inc. + Copyright (c) 2009 Google Inc. from Google Inc. http://google.com cloud-google-gson-1.7.1.jar http://code.google.com/p/google-gson/ @@ -2470,7 +2530,7 @@ Within the target/jar directory licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows) - Copyright 2009, Caringo, Inc. + Copyright (c) 2009, Caringo, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -2501,7 +2561,7 @@ Within the target/jar directory licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows) - Copyright 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. + Copyright (c) 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -2532,7 +2592,7 @@ Within the target/jar directory licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows) - Copyright 2007-2008 Trilead AG (http://www.trilead.com) + Copyright (c) 2007-2008 Trilead AG (http://www.trilead.com) All rights reserved. Redistribution and use in source and binary forms, with or without @@ -2593,7 +2653,7 @@ Within the target/jar directory licensed under the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 http://www.opensource.org/licenses/CDDL-1.0 (as follows) - Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 @@ -2982,7 +3042,7 @@ Within the target/jar directory licensed under the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 http://www.opensource.org/licenses/CDDL-1.0 (as follows) - Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 @@ -3370,7 +3430,7 @@ Within the target/jar directory licensed under the Common Public License - v 1.0 http://opensource.org/licenses/cpl1.0 (as follows) - Copyright IBM Corp 2006 + Copyright (c) IBM Corp 2006 Common Public License Version 1.0 (CPL) @@ -3812,7 +3872,7 @@ Within the target/jar directory licensed under the Eclipse Distribution License Version 1.0 http://www.eclipse.org/org/documents/edl-v10.php (as follows) - Copyright 2012 The Eclipse Foundation. + Copyright (c) 2012 The Eclipse Foundation. Eclipse Distribution License Version 1.0 @@ -3845,6 +3905,34 @@ Within the target/jar directory from The Eclipse Foundation http://www.eclipse.org cloud-javax.persistence-2.0.0.jar http://wiki.eclipse.org/EclipseLink/Release/2.0.0 + licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) + + Copyright (C) 2008 Tth Istvn + 2008-2012 Daniel Veillard + 2009-2011 Bryan Kearney + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + from The libvirt project http://libvirt.org/ + libvirt-java-0.4.9 + licensed under the XStream BSD Style License https://fisheye.codehaus.org/browse/xstream/trunk/LICENSE.txt?hb=true (as follows) @@ -3881,21 +3969,19 @@ Within the target/jar directory cloud-xstream-1.3.1.jar http://xstream.codehaus.org/repository.html -Within the tools/gcc directory - licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2009 Google Inc. - from Google Inc. http://google.com - compiler.jar - - Within the ui/lib directory placed in the public domain by Eric Meyer http://meyerweb.com/eric/ reset.css + licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) + Copyright (c) 2006 Google Inc. + from Google Inc. http://google.com + excanvas.js http://code.google.com/p/explorercanvas/ + licensed under the BSD (2-clause) http://www.opensource.org/licenses/BSD-2-Clause (as follows) - Copyright 2008 George McGinley Smith + Copyright (c) 2008 George McGinley Smith All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -3927,7 +4013,7 @@ Within the ui/lib directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright 2011, John Resig + Copyright (c) 2011, John Resig Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -3953,7 +4039,7 @@ Within the ui/lib directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright 2006 - 2011 Jrn Zaefferer + Copyright (c) 2006 - 2011 Jrn Zaefferer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -3979,7 +4065,7 @@ Within the ui/lib directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright 2010, Sebastian Tschan + Copyright (c) 2010, Sebastian Tschan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -4005,7 +4091,7 @@ Within the ui/lib directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright 2006 Klaus Hartl (stilbuero.de) + Copyright (c) 2006 Klaus Hartl (stilbuero.de) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -4151,7 +4237,7 @@ Within the ui/lib/jquery-ui directory Within the ui/lib/qunit directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright 2012 John Resig, Jrn Zaefferer + Copyright (c) 2012 John Resig, Jrn Zaefferer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -4179,7 +4265,7 @@ Within the ui/lib/qunit directory Within the utils/src/com/cloud/utils/db directory licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above) - Copyright 2004 Clinton Begin + Copyright (c) 2004 Clinton Begin from Clinton Begin http://code.google.com/p/mybatis/ ScriptRunner.java http://code.google.com/p/mybatis/ diff --git a/NOTICE b/NOTICE index cecb580925e..18679580c47 100644 --- a/NOTICE +++ b/NOTICE @@ -449,6 +449,7 @@ axis2-1.5.1.jar axis2-adb-1.5.1.jar axis2-ant-plugin-1.5.1.jar + axis2-codegen-1.4.1.jar axis2-jaxbri-1.5.1.jar axis2-jaxws-1.5.1.jar axis2-jibx-1.5.1.jar @@ -672,3 +673,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ + + + For + wss4j-1.5.8.jar + + + Apache WebServices - WSS4J + Copyright 2004-2011 The Apache Software Foundation + + This product includes software developed at + The Apache Software Foundation (http://www.apache.org/). + + This product includes software Copyright University of Southampton IT + Innovation Centre, 2006 (http://www.it-innovation.soton.ac.uk). diff --git a/README.md b/README.md index a672397c31a..7b4d973666e 100644 --- a/README.md +++ b/README.md @@ -45,67 +45,7 @@ under the License. # Building CloudStack -By default, CloudStack will only build with supporting packages -that are appropved by the ASF as being compatible with the Apache -Software License Version 2. - -## Default build - -To build the default build target, use maven3 and execute: - -maven install - -## Including optional third party libraries in your build - -If you want to build this software against one of the optional -third party libraries, follow the instructions below: - -These third parties jars are non available in Maven central, and -need to be located and downloaded by the developer themselves. -The libraries to download are listed below, by the feature that -they support. - -For F5 load balancing support: -cloud-iControl.jar - -For Netscaler support: -cloud-netscaler.jar -cloud-netscaler-sdx.jar - -For NetApp Storage Support: -cloud-manageontap.jar - -For VMware Support: -vmware-vim.jar -vmware-vim25.jar -vmware-apputils.jar - -Once downloaded (and named the same as listed above), they can be -installed into your local maven repository with the following command: - -cd deps&&sh ./install-non-oss.sh - -To perform the build, run the following command: - -mvn -Dnonoss install - -## Running a developer environment - -To run the webapp client: - -mvn org.apache.tomcat.maven:tomcat7-maven-plugin:2.0-beta-1:run -pl :cloud-client-ui -am -Pclient - -Then hit: http://localhost:8080/cloud-client-ui/ - -or add in your ~/.m2/settings.xml - - org.apache.tomcat.maven - -and save your fingers with mvn tomcat7:run -pl :cloud-client-ui -am -Pclient - -Optionally add -Dnonoss to either of the commands above. - -If you want to use ide debug: replace mvn with mvnDebug and attach your ide debugger to port 8000 +See the INSTALL file. # Notice of Cryptographic Software @@ -126,5 +66,15 @@ Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Sec The following provides more details on the included cryptographic software: -TODO + CloudStack makes use of JaSypt cryptographic libraries + CloudStack has a system requirement of MySQL, and uses native database encryption + functionality. + + CloudStack makes use of the Bouncy Castle general-purpose encryption library. + + CloudStack can optionally interacts with and controls OpenSwan-based VPNs. + + CloudStack has a dependency on Apache WSS4J as part of the AWSAPI implementation. + + CloudStack has a dependency on and makes use of JSch - a java SSH2 implementation. diff --git a/README.tools.md b/README.tools.md new file mode 100644 index 00000000000..f743c8927c6 --- /dev/null +++ b/README.tools.md @@ -0,0 +1,260 @@ +> Licensed to the Apache Software Foundation (ASF) under one +> or more contributor license agreements. See the NOTICE file +> distributed with this work for additional information +> regarding copyright ownership. The ASF licenses this file +> to you 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. + + +--------------------------------------------------------------------------- +This README describes the various tools available with Apache Cloudstack - +for compiling, deploying, building and testing the project +--------------------------------------------------------------------------- + +DevCloud +========================================================= +Under tools/devcloud + +NOTE - DevCloud (tools/devcloud) is a work in progress. The project has not +determined how to best establish a nightly DevCloud build process, or how to +distribute the image. + +#### Contents: #### + +Under tools/devcloud are various scripts used to build the devcloud image. +devcloudsetup.sh - the origional devcloud build script (assumes an Ubuntu 12.04 +VM image) + + $ cd tools/devcloud + +* build_vagrant_basebox.sh - a script that uses VirtualBox, VeeWee, Vagrant +(patched) and puppet to create a devcloud basebox +* veewee - configuration files used to build a basic Ubuntu 12.04 vagrant box +via VeeWee +* basebuild - The Vagrantfile and puppet module that gets applied to the basic +Ubuntu 12.04 box +* devcloudbox - The Vagrantfile and puppet module that is used with the +[hopefully] distributed devcloud base box + +#### Instructions: #### + +To build a "devcloud base box", run you need a system with VirtualBox and rvm +installed (use ruby 1.9.2). Run build_vagrant_basebox.sh to build the base +box. + +To use the "devcloud base box" that is created in the previous step, you need +to have installed a forked version of Vagrant (until we make the changes +plugins instead of direct source patches) that can be found here: + +Once installed per the Vagrant installation process, run: + + $ vagrant box add devcloud [path to devcloud.box] + +Then, either go into the devcloudbox folder of your checked out version of the +CloudStack code (incubator-cloudstack/tools/devcloud/devcloudbox), or copy the +contents of that folder to another location. + +Assuming the patched Vagrant installation is working, you then +simply run "vagrant up" from within that directory. + +#### Installation #### + +Install DevCloud Base system: + +1. get code from https://github.com/jedi4ever/veewee, and install +2. veewee vbox define devcloud ubuntu-12.04-server-i386 +3. put these two files(definition.rb and preseed.cfg) under ./definition/devcloud/ +3. veewee vbox build devcloud + + +Marvin +========================================================= +Under tools/marvin + +Marvin is the functional testing framework for CloudStack written in python. +Writing of unittests and functional tests with Marvin makes testing with +cloudstack easier + +Visit the +[wiki](https://cwiki.apache.org/confluence/display/CLOUDSTACK/Testing+with+Python) +for the most updated information + +#### Dependencies #### +Marvin will require the following dependencies, these will be automatically +downloaded from the python cheeseshop when you install Marvin. + +- mysql-connector-python, +- paramiko, +- nose, +- unittest-xml-reporting, + +#### Installation #### + + $ untar Marvin-0.1.0.tar.gz + $ cd Marvin-0.1.0 + $ python setup.py install + +#### Features #### + +1. very handy cloudstack API python wrapper +2. support async job executing in parallel +3. remote ssh login/execute command +4. mysql query + +#### Examples #### + +Examples on how to develop your own configuration can be found in the marvin sandbox. +Under tools/marvin/marvin/sandbox + +To generate the config for a deployment. Alter the .properties file in the sandbox. For example the +simualtordemo.properties after modification can generate the config file as +shown below + + $ python simulator_setup.py -i simulatordemo.properties -o simulatordemo.cfg + +To deploy the environment and run the tests + + $ python -m marvin.deployAndRun -c simulatordemo.cfg -t /tmp/t.log -r /tmp/r.log -d testcase + +#### Tests #### + +Functional Tests written using marvin can be found under test/integration +folder. These are tests that are written to be run against a live deployed +system. + +To run the tests - you should have marvin installed and correctly importable. +The tests are long running and are best monitored by external hudson jobs. + +Also you will have to point marvin to the right configuration file that has +details about your cloudstack deployment. For more help on how to write the +config file and run tests check the tutorial at : + +[] (https://cwiki.apache.org/confluence/display/CLOUDSTACK/Testing+with+Python) + +#### Build Verification Testing (BVT) #### + +These test cases are the core functionality tests that ensure the application +is stable and can be tested thoroughly. These BVT cases definitions are +located at : +[] (https://docs.google.com/a/cloud.com/spreadsheet/ccc?key=0Ak8acbfxQG8ndEppOGZSLV9mUF9idjVkTkZkajhTZkE&invite=CPij0K0L) + +##### Guidelines on tests ##### + +BVT test cases are being developed using Python unittests2. Following are +certain guidelines being followed + +1. Tests exercised for the same resource should ideally be present under a +single suite or file. + +2. Time-consuming operations that create new cloud resources like server +creation, volume creation etc should not necessarily be exercised per unit +test. The resources can be shared by creating them at the class-level using +setUpClass and shared across all instances during a single run. + +3. Certain tests pertaining to NAT, Firewall and Load Balancing warrant fresh +resources per test. Hence a call should be taken by the stakeholders regarding +sharing resources. + +4. Ensure that the tearDown/tearDownClass functions clean up all the resources +created during the test run. + +For more information about unittests: [] (http://docs.python.org/library/unittest.html) + +##### BVT Tests ##### +Under test/integration/smoke + +The following files contain these BVT cases: + +1. test_vm_life_cycle.py - VM Life Cycle tests +2. test_volumes.py - Volumes related tests +3. test_snapshots.py - Snapshots related tests +4. test_disk_offerings.py - Disk Offerings related tests +5. test_service_offerings.py - Service Offerings related tests +6. test_hosts.py - Hosts and Clusters related tests +7. test_iso.py - ISO related tests +8. test_network.py - Network related tests +9. test_primary_storage.py - Primary storage related tests +10. test_secondary_storage.py - Secondary storage related tests +11. test_ssvm.py - SSVM & CPVM related tests +12. test_templates.py - Templates related tests +13. test_routers.py - Router related tests + + +##### P1 Tests ##### +Under test/integration/component + +These test cases are the core functionality tests that ensure the application +is stable and can be tested thoroughly. These P1 cases definitions are located +at : +[] (https://docs.google.com/a/clogeny.com/spreadsheet/ccc?key=0Aq5M2ldK6eyedDJBa0EzM0RPNmdVNVZOWnFnOVJJcHc&hl=en_US) + +The following files contain these P1 cases: + +1. test_snapshots.py - Snapshots related tests +2. test_routers.py - Router related tests +3. test_usage.py - Usage realted tests +4. test_account.py - Account related tests +5. test_resource_limits.py - Resource limits tests +6. test_security_groups.py - Security groups related tests +7. test_templates.py - templates related tests +8. test_volumes.py - Volumes related tests +9. test_blocker_bugs.py - Blocker bugs tests +10. test_project_configs.py - Project global configuration related tests +11. test_project_limits.py - Project resource limits related tests +12. test_project_resources.py - Project resource creation related tests +13. test_project_usage.py - Project usage related tests +14. test_projects - Projects functionality tests + +Marvin Sandbox +========================================================= +In: tools/marvin/marvin/sandbox + +In here you should find a few common deployment models of CloudStack that you +can configure with properties files to suit your own deployment. One deployment +model for each of - advanced zone, basic zone and a simulator demo are given. + +$ ls - +basic/ +advanced/ +simulator/ + +Each property file is divided into logical sections and should be familiar to +those who have deployed CloudStack before. Once you have your properties file +you will have to create a JSON configuration of your deployment using the +python script provided in the respective folder. + +The demo files are from the tutorial for testing with python that can be found at + https://cwiki.apache.org/confluence/display/CLOUDSTACK/Testing+with+Python + +A common deployment model of a simulator.cfg that can be used for debugging is +included. This will configure an advanced zone with simulators that can be used +for debugging purposes when you do not have hardware to debug with. + +To do this: +$ cd cloudstack-oss/ +$ ant run-simulator #This will start up the mgmt server with the simulator seeded + +## In another shell +$ ant run-simulator + +test/conf - EC2 script +========================================================= + +To run submitCertEC2 and deleteCertEC2 scripts, update parameters in conf/tool.properties file: + +* host - ip address of the host where cloud-bridge software is installed +* port - port cloud-bridge software is listening to +* accesspoint - access point for cloud-bridge REST request +* version - Amazon EC2 api version supported by cloud-bridge +* signaturemethod - HmacSHA1 or HmacSHA256 +* expires - the date when certificate expires diff --git a/agent-simulator/db/create-schema-simulator.sql b/agent-simulator/db/create-schema-simulator.sql deleted file mode 100644 index 09da344dc42..00000000000 --- a/agent-simulator/db/create-schema-simulator.sql +++ /dev/null @@ -1,89 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you 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. -DROP TABLE IF EXISTS `cloud`.`mockhost`; -DROP TABLE IF EXISTS `cloud`.`mocksecstorage`; -DROP TABLE IF EXISTS `cloud`.`mockstoragepool`; -DROP TABLE IF EXISTS `cloud`.`mockvm`; -DROP TABLE IF EXISTS `cloud`.`mockvolume`; - -CREATE TABLE `cloud`.`mockhost` ( - `id` bigint unsigned NOT NULL auto_increment, - `name` varchar(255) NOT NULL, - `private_ip_address` char(40), - `private_mac_address` varchar(17), - `private_netmask` varchar(15), - `storage_ip_address` char(40), - `storage_netmask` varchar(15), - `storage_mac_address` varchar(17), - `public_ip_address` char(40), - `public_netmask` varchar(15), - `public_mac_address` varchar(17), - `guid` varchar(255) UNIQUE, - `version` varchar(40) NOT NULL, - `data_center_id` bigint unsigned NOT NULL, - `pod_id` bigint unsigned, - `cluster_id` bigint unsigned COMMENT 'foreign key to cluster', - `cpus` int(10) unsigned, - `speed` int(10) unsigned, - `ram` bigint unsigned, - `capabilities` varchar(255) COMMENT 'host capabilities in comma separated list', - `vm_id` bigint unsigned, - `resource` varchar(255) DEFAULT NULL COMMENT 'If it is a local resource, this is the class name', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`mocksecstorage` ( - `id` bigint unsigned NOT NULL auto_increment, - `url` varchar(255), - `capacity` bigint unsigned, - `mount_point` varchar(255), - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE `cloud`.`mockstoragepool` ( - `id` bigint unsigned NOT NULL auto_increment, - `guid` varchar(255), - `mount_point` varchar(255), - `capacity` bigint, - `pool_type` varchar(40), - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`mockvm` ( - `id` bigint unsigned NOT NULL auto_increment, - `name` varchar(255), - `host_id` bigint unsigned, - `type` varchar(40), - `state` varchar(40), - `vnc_port` bigint unsigned, - `memory` bigint unsigned, - `cpu` bigint unsigned, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE `cloud`.`mockvolume` ( - `id` bigint unsigned NOT NULL auto_increment, - `name` varchar(255), - `size` bigint unsigned, - `path` varchar(255), - `pool_id` bigint unsigned, - `type` varchar(40), - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - diff --git a/agent-simulator/src/com/cloud/agent/manager/MockAgentManager.java b/agent-simulator/src/com/cloud/agent/manager/MockAgentManager.java index 993217362d0..7db5b20f55c 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockAgentManager.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockAgentManager.java @@ -33,28 +33,34 @@ import com.cloud.simulator.MockHost; import com.cloud.utils.component.Manager; public interface MockAgentManager extends Manager { - public static final long DEFAULT_HOST_MEM_SIZE = 8 * 1024 * 1024 * 1024L; // 8G, unit of - // Mbytes - public static final int DEFAULT_HOST_CPU_CORES = 4; // 2 dual core CPUs (2 x - // 2) - public static final int DEFAULT_HOST_SPEED_MHZ = 8000; // 1 GHz CPUs - boolean configure(String name, Map params) throws ConfigurationException; + public static final long DEFAULT_HOST_MEM_SIZE = 8 * 1024 * 1024 * 1024L; // 8G, + // unit + // of + // Mbytes + public static final int DEFAULT_HOST_CPU_CORES = 4; // 2 dual core CPUs (2 x + // 2) + public static final int DEFAULT_HOST_SPEED_MHZ = 8000; // 1 GHz CPUs - Map> createServerResources(Map params); + boolean configure(String name, Map params) throws ConfigurationException; - boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name, String vmType, String url); + Map> createServerResources(Map params); - boolean handleSystemVMStop(long vmId); + boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, + long dcId, long podId, String name, String vmType, String url); - GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd); - Answer checkHealth(CheckHealthCommand cmd); - Answer pingTest(PingTestCommand cmd); - - Answer prepareForMigrate(PrepareForMigrationCommand cmd); - - MockHost getHost(String guid); + boolean handleSystemVMStop(long vmId); - Answer maintain(MaintainCommand cmd); + GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd); + + Answer checkHealth(CheckHealthCommand cmd); + + Answer pingTest(PingTestCommand cmd); + + Answer prepareForMigrate(PrepareForMigrationCommand cmd); + + MockHost getHost(String guid); + + Answer maintain(MaintainCommand cmd); Answer checkNetworkCommand(CheckNetworkCommand cmd); } diff --git a/agent-simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java index 0dd8f05737f..cb992979e07 100755 --- a/agent-simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java @@ -61,321 +61,408 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.Inject; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @Local(value = { MockAgentManager.class }) public class MockAgentManagerImpl implements MockAgentManager { - private static final Logger s_logger = Logger.getLogger(MockAgentManagerImpl.class); - @Inject HostPodDao _podDao = null; - @Inject MockHostDao _mockHostDao = null; - @Inject MockVMDao _mockVmDao = null; - @Inject SimulatorManager _simulatorMgr = null; - @Inject AgentManager _agentMgr = null; - @Inject MockStorageManager _storageMgr = null; - @Inject ResourceManager _resourceMgr; - private SecureRandom random; - private Map _resources = new ConcurrentHashMap(); - private ThreadPoolExecutor _executor; + private static final Logger s_logger = Logger.getLogger(MockAgentManagerImpl.class); + @Inject + HostPodDao _podDao = null; + @Inject + MockHostDao _mockHostDao = null; + @Inject + MockVMDao _mockVmDao = null; + @Inject + SimulatorManager _simulatorMgr = null; + @Inject + AgentManager _agentMgr = null; + @Inject + MockStorageManager _storageMgr = null; + @Inject + ResourceManager _resourceMgr; + private SecureRandom random; + private Map _resources = new ConcurrentHashMap(); + private ThreadPoolExecutor _executor; - private Pair getPodCidr(long podId, long dcId) { - try { - - HashMap> podMap = _podDao - .getCurrentPodCidrSubnets(dcId, 0); - List cidrPair = podMap.get(podId); - String cidrAddress = (String) cidrPair.get(0); - Long cidrSize = (Long)cidrPair.get(1); - return new Pair(cidrAddress, cidrSize); - } catch (PatternSyntaxException e) { - s_logger.error("Exception while splitting pod cidr"); - return null; - } catch(IndexOutOfBoundsException e) { - s_logger.error("Invalid pod cidr. Please check"); - return null; - } - } - + private Pair getPodCidr(long podId, long dcId) { + try { - private String getIpAddress(long instanceId, long dcId, long podId) { - Pair cidr = this.getPodCidr(podId, dcId); - return NetUtils.long2Ip(NetUtils.ip2Long(cidr.first()) + instanceId); - } - - private String getMacAddress(long dcId, long podId, long clusterId, int instanceId) { - return NetUtils.long2Mac((dcId << 40 + podId << 32 + clusterId << 24 + instanceId)); - } - public synchronized int getNextAgentId(long cidrSize) { - return random.nextInt((int)cidrSize); - } - - @Override - @DB - public Map> createServerResources( - Map params) { - - Map args = new HashMap(); - Map> newResources = new HashMap>(); - AgentResourceBase agentResource; - long cpuCore = Long.parseLong((String)params.get("cpucore")); - long cpuSpeed = Long.parseLong((String)params.get("cpuspeed")); - long memory = Long.parseLong((String)params.get("memory")); - long localStorageSize = Long.parseLong((String)params.get("localstorage")); - synchronized (this) { - long dataCenterId = Long.parseLong((String)params.get("zone")); - long podId = Long.parseLong((String)params.get("pod")); - long clusterId = Long.parseLong((String)params.get("cluster")); - long cidrSize = getPodCidr(podId, dataCenterId).second(); + HashMap> podMap = _podDao.getCurrentPodCidrSubnets(dcId, 0); + List cidrPair = podMap.get(podId); + String cidrAddress = (String) cidrPair.get(0); + Long cidrSize = (Long) cidrPair.get(1); + return new Pair(cidrAddress, cidrSize); + } catch (PatternSyntaxException e) { + s_logger.error("Exception while splitting pod cidr"); + return null; + } catch (IndexOutOfBoundsException e) { + s_logger.error("Invalid pod cidr. Please check"); + return null; + } + } - int agentId = getNextAgentId(cidrSize); - String ipAddress = getIpAddress(agentId, dataCenterId, podId); - String macAddress = getMacAddress(dataCenterId, podId, clusterId, agentId); - MockHostVO mockHost = new MockHostVO(); - mockHost.setDataCenterId(dataCenterId); - mockHost.setPodId(podId); - mockHost.setClusterId(clusterId); - mockHost.setCapabilities("hvm"); - mockHost.setCpuCount(cpuCore); - mockHost.setCpuSpeed(cpuSpeed); - mockHost.setMemorySize(memory); - String guid = UUID.randomUUID().toString(); - mockHost.setGuid(guid); - mockHost.setName("SimulatedAgent." + guid); - mockHost.setPrivateIpAddress(ipAddress); - mockHost.setPublicIpAddress(ipAddress); - mockHost.setStorageIpAddress(ipAddress); - mockHost.setPrivateMacAddress(macAddress); - mockHost.setPublicMacAddress(macAddress); - mockHost.setStorageMacAddress(macAddress); - mockHost.setVersion(this.getClass().getPackage().getImplementationVersion()); - mockHost.setResource("com.cloud.agent.AgentRoutingResource"); - mockHost = _mockHostDao.persist(mockHost); - - _storageMgr.getLocalStorage(guid, localStorageSize); + private String getIpAddress(long instanceId, long dcId, long podId) { + Pair cidr = this.getPodCidr(podId, dcId); + return NetUtils.long2Ip(NetUtils.ip2Long(cidr.first()) + instanceId); + } - agentResource = new AgentRoutingResource(); - if (agentResource != null) { - try { - params.put("guid", mockHost.getGuid()); - agentResource.start(); - agentResource.configure(mockHost.getName(), - params); + private String getMacAddress(long dcId, long podId, long clusterId, int instanceId) { + return NetUtils.long2Mac((dcId << 40 + podId << 32 + clusterId << 24 + instanceId)); + } - newResources.put(agentResource, args); - } catch (ConfigurationException e) { - s_logger - .error("error while configuring server resource" - + e.getMessage()); - } - } - } - return newResources; - } - - - @Override - public boolean configure(String name, Map params) - throws ConfigurationException { - try { - random = SecureRandom.getInstance("SHA1PRNG"); - _executor = new ThreadPoolExecutor(1, 5, 1, TimeUnit.DAYS, new LinkedBlockingQueue(), new NamedThreadFactory("Simulator-Agent-Mgr")); - //ComponentLocator locator = ComponentLocator.getCurrentLocator(); - //_simulatorMgr = (SimulatorManager) locator.getComponent(SimulatorManager.Name); - } catch (NoSuchAlgorithmException e) { - s_logger.debug("Failed to initialize random:" + e.toString()); - return false; - } - return true; - } - - @Override - public boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name, String vmType, String url) { - _executor.execute(new SystemVMHandler(vmId, privateIpAddress, privateMacAddress, privateNetMask, dcId, podId, name, vmType, _simulatorMgr, url)); - return true; - } - - @Override - public boolean handleSystemVMStop(long vmId) { - _executor.execute(new SystemVMHandler(vmId)); - return true; - } - - private class SystemVMHandler implements Runnable { - private long vmId; - private String privateIpAddress; - private String privateMacAddress; - private String privateNetMask; - private long dcId; - private long podId; - private String guid; - private String name; - private String vmType; - private SimulatorManager mgr; - private String mode; - private String url; - public SystemVMHandler(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, long dcId, long podId, String name, String vmType, - SimulatorManager mgr, String url) { - this.vmId = vmId; - this.privateIpAddress = privateIpAddress; - this.privateMacAddress = privateMacAddress; - this.privateNetMask = privateNetMask; - this.dcId = dcId; - this.guid = "SystemVM-" + UUID.randomUUID().toString(); - this.name = name; - this.vmType = vmType; - this.mgr = mgr; - this.mode = "Start"; - this.url = url; - this.podId = podId; - } - - public SystemVMHandler(long vmId) { - this.vmId = vmId; - this.mode = "Stop"; - } - - @Override - @DB - public void run() { - if (this.mode.equalsIgnoreCase("Stop")) { - MockHost host = _mockHostDao.findByVmId(this.vmId); - if (host != null) { - String guid = host.getGuid(); - if (guid != null) { - AgentResourceBase res = _resources.get(guid); - if (res != null) { - res.stop(); - _resources.remove(guid); - } - } - } - return; - } - - String resource = null; - if (vmType.equalsIgnoreCase("secstorage")) { - resource = "com.cloud.agent.AgentStorageResource"; - } - MockHostVO mockHost = new MockHostVO(); - mockHost.setDataCenterId(this.dcId); - mockHost.setPodId(this.podId); - mockHost.setCpuCount(DEFAULT_HOST_CPU_CORES); - mockHost.setCpuSpeed(DEFAULT_HOST_SPEED_MHZ); - mockHost.setMemorySize(DEFAULT_HOST_MEM_SIZE); - mockHost.setGuid(this.guid); - mockHost.setName(name); - mockHost.setPrivateIpAddress(this.privateIpAddress); - mockHost.setPublicIpAddress(this.privateIpAddress); - mockHost.setStorageIpAddress(this.privateIpAddress); - mockHost.setPrivateMacAddress(this.privateMacAddress); - mockHost.setPublicMacAddress(this.privateMacAddress); - mockHost.setStorageMacAddress(this.privateMacAddress); - mockHost.setVersion(this.getClass().getPackage().getImplementationVersion()); - mockHost.setResource(resource); - mockHost.setVmId(vmId); - mockHost = _mockHostDao.persist(mockHost); - - if (vmType.equalsIgnoreCase("secstorage")) { - AgentStorageResource storageResource = new AgentStorageResource(); - try { - Map params = new HashMap(); - Map details = new HashMap(); - params.put("guid", this.guid); - details.put("guid", this.guid); - storageResource.configure("secondaryStorage", params); - storageResource.start(); - //on the simulator the ssvm is as good as a direct agent - _resourceMgr.addHost(mockHost.getDataCenterId(), storageResource, Host.Type.SecondaryStorageVM, details); - _resources.put(this.guid, storageResource); - } catch (ConfigurationException e) { - s_logger.debug("Failed to load secondary storage resource: " + e.toString()); - return; - } - } - } - } + public synchronized int getNextAgentId(long cidrSize) { + return random.nextInt((int) cidrSize); + } - @Override - public MockHost getHost(String guid) { - return _mockHostDao.findByGuid(guid); - } + @Override + @DB + public Map> createServerResources(Map params) { - @Override - public GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd) { - String hostGuid = cmd.getHostGuid(); - MockHost host = _mockHostDao.findByGuid(hostGuid); - if (host == null) { - return null; - } - List vms = _mockVmDao.findByHostId(host.getId()); - double usedMem = 0.0; - double usedCpu = 0.0; - for (MockVMVO vm : vms) { - usedMem += vm.getMemory(); - usedCpu += vm.getCpu(); - } - - HostStatsEntry hostStats = new HostStatsEntry(); - hostStats.setTotalMemoryKBs(host.getMemorySize()); - hostStats.setFreeMemoryKBs(host.getMemorySize() - usedMem); - hostStats.setNetworkReadKBs(32768); - hostStats.setNetworkWriteKBs(16384); - hostStats.setCpuUtilization(usedCpu/(host.getCpuCount() * host.getCpuSpeed())); - hostStats.setEntityType("simulator-host"); - hostStats.setHostId(cmd.getHostId()); - return new GetHostStatsAnswer(cmd, hostStats); - } + Map args = new HashMap(); + Map> newResources = new HashMap>(); + AgentResourceBase agentResource; + long cpuCore = Long.parseLong((String) params.get("cpucore")); + long cpuSpeed = Long.parseLong((String) params.get("cpuspeed")); + long memory = Long.parseLong((String) params.get("memory")); + long localStorageSize = Long.parseLong((String) params.get("localstorage")); + synchronized (this) { + long dataCenterId = Long.parseLong((String) params.get("zone")); + long podId = Long.parseLong((String) params.get("pod")); + long clusterId = Long.parseLong((String) params.get("cluster")); + long cidrSize = getPodCidr(podId, dataCenterId).second(); + int agentId = getNextAgentId(cidrSize); + String ipAddress = getIpAddress(agentId, dataCenterId, podId); + String macAddress = getMacAddress(dataCenterId, podId, clusterId, agentId); + MockHostVO mockHost = new MockHostVO(); + mockHost.setDataCenterId(dataCenterId); + mockHost.setPodId(podId); + mockHost.setClusterId(clusterId); + mockHost.setCapabilities("hvm"); + mockHost.setCpuCount(cpuCore); + mockHost.setCpuSpeed(cpuSpeed); + mockHost.setMemorySize(memory); + String guid = UUID.randomUUID().toString(); + mockHost.setGuid(guid); + mockHost.setName("SimulatedAgent." + guid); + mockHost.setPrivateIpAddress(ipAddress); + mockHost.setPublicIpAddress(ipAddress); + mockHost.setStorageIpAddress(ipAddress); + mockHost.setPrivateMacAddress(macAddress); + mockHost.setPublicMacAddress(macAddress); + mockHost.setStorageMacAddress(macAddress); + mockHost.setVersion(this.getClass().getPackage().getImplementationVersion()); + mockHost.setResource("com.cloud.agent.AgentRoutingResource"); - @Override - public Answer checkHealth(CheckHealthCommand cmd) { - return new Answer(cmd); - } + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + mockHost = _mockHostDao.persist(mockHost); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + s_logger.error("Error while configuring mock agent " + ex.getMessage()); + throw new CloudRuntimeException("Error configuring agent", ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + _storageMgr.getLocalStorage(guid, localStorageSize); - @Override - public Answer pingTest(PingTestCommand cmd) { - return new Answer(cmd); - } + agentResource = new AgentRoutingResource(); + if (agentResource != null) { + try { + params.put("guid", mockHost.getGuid()); + agentResource.start(); + agentResource.configure(mockHost.getName(), params); + newResources.put(agentResource, args); + } catch (ConfigurationException e) { + s_logger.error("error while configuring server resource" + e.getMessage()); + } + } + } + return newResources; + } - @Override - public PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd) { - VirtualMachineTO vm = cmd.getVirtualMachine(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Preparing host for migrating " + vm); - } - return new PrepareForMigrationAnswer(cmd); - } + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + try { + random = SecureRandom.getInstance("SHA1PRNG"); + _executor = new ThreadPoolExecutor(1, 5, 1, TimeUnit.DAYS, new LinkedBlockingQueue(), + new NamedThreadFactory("Simulator-Agent-Mgr")); + // ComponentLocator locator = ComponentLocator.getCurrentLocator(); + // _simulatorMgr = (SimulatorManager) + // locator.getComponent(SimulatorManager.Name); + } catch (NoSuchAlgorithmException e) { + s_logger.debug("Failed to initialize random:" + e.toString()); + return false; + } + return true; + } + @Override + public boolean handleSystemVMStart(long vmId, String privateIpAddress, String privateMacAddress, + String privateNetMask, long dcId, long podId, String name, String vmType, String url) { + _executor.execute(new SystemVMHandler(vmId, privateIpAddress, privateMacAddress, privateNetMask, dcId, podId, + name, vmType, _simulatorMgr, url)); + return true; + } - @Override - public boolean start() { - return true; - } + @Override + public boolean handleSystemVMStop(long vmId) { + _executor.execute(new SystemVMHandler(vmId)); + return true; + } + private class SystemVMHandler implements Runnable { + private long vmId; + private String privateIpAddress; + private String privateMacAddress; + private String privateNetMask; + private long dcId; + private long podId; + private String guid; + private String name; + private String vmType; + private SimulatorManager mgr; + private String mode; + private String url; - @Override - public boolean stop() { - return true; - } + public SystemVMHandler(long vmId, String privateIpAddress, String privateMacAddress, String privateNetMask, + long dcId, long podId, String name, String vmType, SimulatorManager mgr, String url) { + this.vmId = vmId; + this.privateIpAddress = privateIpAddress; + this.privateMacAddress = privateMacAddress; + this.privateNetMask = privateNetMask; + this.dcId = dcId; + this.guid = "SystemVM-" + UUID.randomUUID().toString(); + this.name = name; + this.vmType = vmType; + this.mgr = mgr; + this.mode = "Start"; + this.url = url; + this.podId = podId; + } + public SystemVMHandler(long vmId) { + this.vmId = vmId; + this.mode = "Stop"; + } - @Override - public String getName() { - return this.getClass().getSimpleName(); - } + @Override + @DB + public void run() { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + if (this.mode.equalsIgnoreCase("Stop")) { + txn.start(); + MockHost host = _mockHostDao.findByVmId(this.vmId); + if (host != null) { + String guid = host.getGuid(); + if (guid != null) { + AgentResourceBase res = _resources.get(guid); + if (res != null) { + res.stop(); + _resources.remove(guid); + } + } + } + txn.commit(); + return; + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } - @Override - public MaintainAnswer maintain(com.cloud.agent.api.MaintainCommand cmd) { - return new MaintainAnswer(cmd); - } + String resource = null; + if (vmType.equalsIgnoreCase("secstorage")) { + resource = "com.cloud.agent.AgentStorageResource"; + } + MockHostVO mockHost = new MockHostVO(); + mockHost.setDataCenterId(this.dcId); + mockHost.setPodId(this.podId); + mockHost.setCpuCount(DEFAULT_HOST_CPU_CORES); + mockHost.setCpuSpeed(DEFAULT_HOST_SPEED_MHZ); + mockHost.setMemorySize(DEFAULT_HOST_MEM_SIZE); + mockHost.setGuid(this.guid); + mockHost.setName(name); + mockHost.setPrivateIpAddress(this.privateIpAddress); + mockHost.setPublicIpAddress(this.privateIpAddress); + mockHost.setStorageIpAddress(this.privateIpAddress); + mockHost.setPrivateMacAddress(this.privateMacAddress); + mockHost.setPublicMacAddress(this.privateMacAddress); + mockHost.setStorageMacAddress(this.privateMacAddress); + mockHost.setVersion(this.getClass().getPackage().getImplementationVersion()); + mockHost.setResource(resource); + mockHost.setVmId(vmId); + Transaction simtxn = Transaction.open(Transaction.SIMULATOR_DB); + try { + simtxn.start(); + mockHost = _mockHostDao.persist(mockHost); + simtxn.commit(); + } catch (Exception ex) { + simtxn.rollback(); + throw new CloudRuntimeException("Unable to persist host " + mockHost.getGuid() + " due to " + + ex.getMessage(), ex); + } finally { + simtxn.close(); + simtxn = Transaction.open(Transaction.CLOUD_DB); + simtxn.close(); + } + + if (vmType.equalsIgnoreCase("secstorage")) { + AgentStorageResource storageResource = new AgentStorageResource(); + try { + Map params = new HashMap(); + Map details = new HashMap(); + params.put("guid", this.guid); + details.put("guid", this.guid); + storageResource.configure("secondaryStorage", params); + storageResource.start(); + // on the simulator the ssvm is as good as a direct + // agent + _resourceMgr.addHost(mockHost.getDataCenterId(), storageResource, Host.Type.SecondaryStorageVM, + details); + _resources.put(this.guid, storageResource); + } catch (ConfigurationException e) { + s_logger.debug("Failed to load secondary storage resource: " + e.toString()); + return; + } + } + } + } + + @Override + public MockHost getHost(String guid) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockHost _host = _mockHostDao.findByGuid(guid); + txn.commit(); + if (_host != null) { + return _host; + } else { + s_logger.error("Host with guid " + guid + " was not found"); + return null; + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to get host " + guid + " due to " + ex.getMessage(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + + @Override + public GetHostStatsAnswer getHostStatistic(GetHostStatsCommand cmd) { + String hostGuid = cmd.getHostGuid(); + MockHost host = null; + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + host = _mockHostDao.findByGuid(hostGuid); + txn.commit(); + if (host == null) { + return null; + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to get host " + hostGuid + " due to " + ex.getMessage(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + Transaction vmtxn = Transaction.open(Transaction.SIMULATOR_DB); + try { + vmtxn.start(); + List vms = _mockVmDao.findByHostId(host.getId()); + vmtxn.commit(); + double usedMem = 0.0; + double usedCpu = 0.0; + for (MockVMVO vm : vms) { + usedMem += vm.getMemory(); + usedCpu += vm.getCpu(); + } + + HostStatsEntry hostStats = new HostStatsEntry(); + hostStats.setTotalMemoryKBs(host.getMemorySize()); + hostStats.setFreeMemoryKBs(host.getMemorySize() - usedMem); + hostStats.setNetworkReadKBs(32768); + hostStats.setNetworkWriteKBs(16384); + hostStats.setCpuUtilization(usedCpu / (host.getCpuCount() * host.getCpuSpeed())); + hostStats.setEntityType("simulator-host"); + hostStats.setHostId(cmd.getHostId()); + return new GetHostStatsAnswer(cmd, hostStats); + } catch (Exception ex) { + vmtxn.rollback(); + throw new CloudRuntimeException("Unable to get Vms on host " + host.getGuid() + " due to " + + ex.getMessage(), ex); + } finally { + vmtxn.close(); + vmtxn = Transaction.open(Transaction.CLOUD_DB); + vmtxn.close(); + } + } + + @Override + public Answer checkHealth(CheckHealthCommand cmd) { + return new Answer(cmd); + } + + @Override + public Answer pingTest(PingTestCommand cmd) { + return new Answer(cmd); + } + + @Override + public PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd) { + VirtualMachineTO vm = cmd.getVirtualMachine(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Preparing host for migrating " + vm); + } + return new PrepareForMigrationAnswer(cmd); + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return this.getClass().getSimpleName(); + } + + @Override + public MaintainAnswer maintain(com.cloud.agent.api.MaintainCommand cmd) { + return new MaintainAnswer(cmd); + } @Override public Answer checkNetworkCommand(CheckNetworkCommand cmd) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking if network name setup is done on the resource"); - } - return new CheckNetworkAnswer(cmd, true , "Network Setup check by names is done"); + s_logger.debug("Checking if network name setup is done on the resource"); + } + return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done"); } } diff --git a/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index 7b096fbd845..cc15b206738 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -84,650 +84,1215 @@ import com.cloud.simulator.dao.MockSecStorageDao; import com.cloud.simulator.dao.MockStoragePoolDao; import com.cloud.simulator.dao.MockVMDao; import com.cloud.simulator.dao.MockVolumeDao; +import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.template.TemplateInfo; import com.cloud.utils.component.Inject; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine.State; - @Local(value = { MockStorageManager.class }) public class MockStorageManagerImpl implements MockStorageManager { - private static final Logger s_logger = Logger.getLogger(MockStorageManagerImpl.class); - @Inject MockStoragePoolDao _mockStoragePoolDao = null; - @Inject MockSecStorageDao _mockSecStorageDao = null; - @Inject MockVolumeDao _mockVolumeDao = null; - @Inject MockVMDao _mockVMDao = null; - @Inject MockHostDao _mockHostDao = null; + private static final Logger s_logger = Logger.getLogger(MockStorageManagerImpl.class); + @Inject + MockStoragePoolDao _mockStoragePoolDao = null; + @Inject + MockSecStorageDao _mockSecStorageDao = null; + @Inject + MockVolumeDao _mockVolumeDao = null; + @Inject + MockVMDao _mockVMDao = null; + @Inject + MockHostDao _mockHostDao = null; - private MockVolumeVO findVolumeFromSecondary(String path, String ssUrl, MockVolumeType type) { - - String volumePath = path.replaceAll(ssUrl, ""); - - MockSecStorageVO secStorage = _mockSecStorageDao.findByUrl(ssUrl); - if (secStorage == null) { - return null; - } - - volumePath = secStorage.getMountPoint() + volumePath; - volumePath = volumePath.replaceAll("//", "/"); - - MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(volumePath); - if (volume == null) { - return null; - } - - return volume; - } - @Override - public PrimaryStorageDownloadAnswer primaryStorageDownload(PrimaryStorageDownloadCommand cmd) { - MockVolumeVO template = findVolumeFromSecondary(cmd.getUrl(),cmd.getSecondaryStorageUrl(), MockVolumeType.TEMPLATE); - if (template == null) { - return new PrimaryStorageDownloadAnswer("Can't find primary storage"); - } - - MockStoragePoolVO primaryStorage = _mockStoragePoolDao.findByUuid(cmd.getPoolUuid()); - if (primaryStorage == null) { - return new PrimaryStorageDownloadAnswer("Can't find primary storage"); - } - - String volumeName = UUID.randomUUID().toString(); - MockVolumeVO newVolume = new MockVolumeVO(); - newVolume.setName(volumeName); - newVolume.setPath(primaryStorage.getMountPoint() + volumeName); - newVolume.setPoolId(primaryStorage.getId()); - newVolume.setSize(template.getSize()); - newVolume.setType(MockVolumeType.VOLUME); - _mockVolumeDao.persist(newVolume); - - - return new PrimaryStorageDownloadAnswer(newVolume.getPath(), newVolume.getSize()); - } + private MockVolumeVO findVolumeFromSecondary(String path, String ssUrl, MockVolumeType type) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + String volumePath = path.replaceAll(ssUrl, ""); + MockSecStorageVO secStorage = _mockSecStorageDao.findByUrl(ssUrl); + if (secStorage == null) { + return null; + } + volumePath = secStorage.getMountPoint() + volumePath; + volumePath = volumePath.replaceAll("//", "/"); + MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(volumePath); + txn.commit(); + if (volume == null) { + return null; + } + return volume; + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to find volume " + path + " on secondary " + ssUrl, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } - @Override - public CreateAnswer createVolume(CreateCommand cmd) { - StorageFilerTO sf = cmd.getPool(); - DiskProfile dskch = cmd.getDiskCharacteristics(); - MockStoragePoolVO storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid()); - if (storagePool == null) { - return new CreateAnswer(cmd, "Failed to find storage pool: " + sf.getUuid()); - } - - String volumeName = UUID.randomUUID().toString(); - MockVolumeVO volume = new MockVolumeVO(); - volume.setPoolId(storagePool.getId()); - volume.setName(volumeName); - volume.setPath(storagePool.getMountPoint() + volumeName); - volume.setSize(dskch.getSize()); - volume.setType(MockVolumeType.VOLUME); - volume = _mockVolumeDao.persist(volume); - - VolumeTO volumeTo = new VolumeTO(cmd.getVolumeId(), dskch.getType(), sf.getType(), sf.getUuid(), - volume.getName(), storagePool.getMountPoint(), volume.getPath(), volume.getSize(), null); - - return new CreateAnswer(cmd, volumeTo); - } + @Override + public PrimaryStorageDownloadAnswer primaryStorageDownload(PrimaryStorageDownloadCommand cmd) { + MockVolumeVO template = findVolumeFromSecondary(cmd.getUrl(), cmd.getSecondaryStorageUrl(), + MockVolumeType.TEMPLATE); + if (template == null) { + return new PrimaryStorageDownloadAnswer("Can't find primary storage"); + } - @Override - public AttachVolumeAnswer AttachVolume(AttachVolumeCommand cmd) { - String poolid = cmd.getPoolUuid(); - String volumeName = cmd.getVolumeName(); - MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); - if (volume == null) { - return new AttachVolumeAnswer(cmd, "Can't find volume:" + volumeName + "on pool:" + poolid); - } - - String vmName = cmd.getVmName(); - MockVMVO vm = _mockVMDao.findByVmName(vmName); - if (vm == null) { - return new AttachVolumeAnswer(cmd, "can't vm :" + vmName); - } - - return new AttachVolumeAnswer(cmd, cmd.getDeviceId()); - } + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockStoragePoolVO primaryStorage = null; + try { + txn.start(); + primaryStorage = _mockStoragePoolDao.findByUuid(cmd.getPoolUuid()); + txn.commit(); + if (primaryStorage == null) { + return new PrimaryStorageDownloadAnswer("Can't find primary storage"); + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when finding primary storagee " + cmd.getPoolUuid(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } - @Override - public Answer AttachIso(AttachIsoCommand cmd) { - MockVolumeVO iso = findVolumeFromSecondary(cmd.getIsoPath(), cmd.getStoreUrl(), MockVolumeType.ISO); - if (iso == null) { - return new Answer(cmd, false, "Failed to find the iso: " + cmd.getIsoPath() + "on secondary storage " + cmd.getStoreUrl()); - } - - String vmName = cmd.getVmName(); - MockVMVO vm = _mockVMDao.findByVmName(vmName); - if (vm == null) { - return new Answer(cmd, false, "can't vm :" + vmName); - } - - return new Answer(cmd); - } + String volumeName = UUID.randomUUID().toString(); + MockVolumeVO newVolume = new MockVolumeVO(); + newVolume.setName(volumeName); + newVolume.setPath(primaryStorage.getMountPoint() + volumeName); + newVolume.setPoolId(primaryStorage.getId()); + newVolume.setSize(template.getSize()); + newVolume.setType(MockVolumeType.VOLUME); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + _mockVolumeDao.persist(newVolume); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving volume " + newVolume, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new PrimaryStorageDownloadAnswer(newVolume.getPath(), newVolume.getSize()); + } - @Override - public Answer DeleteStoragePool(DeleteStoragePoolCommand cmd) { - MockStoragePoolVO storage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid()); - if (storage == null) { - return new Answer(cmd, false, "can't find storage pool:" + cmd.getPool().getUuid()); - } - _mockStoragePoolDao.remove(storage.getId()); - return new Answer(cmd); - } + @Override + public CreateAnswer createVolume(CreateCommand cmd) { + StorageFilerTO sf = cmd.getPool(); + DiskProfile dskch = cmd.getDiskCharacteristics(); + MockStoragePoolVO storagePool = null; + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid()); + txn.commit(); + if (storagePool == null) { + return new CreateAnswer(cmd, "Failed to find storage pool: " + sf.getUuid()); + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when finding storage " + sf.getUuid(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } - @Override - public ModifyStoragePoolAnswer ModifyStoragePool(ModifyStoragePoolCommand cmd) { - StorageFilerTO sf = cmd.getPool(); - MockStoragePoolVO storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid()); - if (storagePool == null) { - storagePool = new MockStoragePoolVO(); - storagePool.setUuid(sf.getUuid()); - storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator); - - Long size = DEFAULT_HOST_STORAGE_SIZE; - String path = sf.getPath(); - int index = path.lastIndexOf("/"); - if (index != -1) { - path = path.substring(index+1); - if (path != null) { - String values[] = path.split("="); - if (values.length > 1 && values[0].equalsIgnoreCase("size")) { - size = Long.parseLong(values[1]); - } - } - } - - storagePool.setCapacity(size); - - storagePool.setStorageType(sf.getType()); - storagePool = _mockStoragePoolDao.persist(storagePool); - } + String volumeName = UUID.randomUUID().toString(); + MockVolumeVO volume = new MockVolumeVO(); + volume.setPoolId(storagePool.getId()); + volume.setName(volumeName); + volume.setPath(storagePool.getMountPoint() + volumeName); + volume.setSize(dskch.getSize()); + volume.setType(MockVolumeType.VOLUME); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + volume = _mockVolumeDao.persist(volume); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving volume " + volume, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } - return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); - } + VolumeTO volumeTo = new VolumeTO(cmd.getVolumeId(), dskch.getType(), sf.getType(), sf.getUuid(), + volume.getName(), storagePool.getMountPoint(), volume.getPath(), volume.getSize(), null); - @Override - public Answer CreateStoragePool(CreateStoragePoolCommand cmd) { - StorageFilerTO sf = cmd.getPool(); - MockStoragePoolVO storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid()); - if (storagePool == null) { - storagePool = new MockStoragePoolVO(); - storagePool.setUuid(sf.getUuid()); - storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator); + return new CreateAnswer(cmd, volumeTo); + } - Long size = DEFAULT_HOST_STORAGE_SIZE; - String path = sf.getPath(); - int index = path.lastIndexOf("/"); - if (index != -1) { - path = path.substring(index+1); - if (path != null) { - String values[] = path.split("="); - if (values.length > 1 && values[0].equalsIgnoreCase("size")) { - size = Long.parseLong(values[1]); - } - } - } - storagePool.setCapacity(size); - - storagePool.setStorageType(sf.getType()); - storagePool = _mockStoragePoolDao.persist(storagePool); - } + @Override + public AttachVolumeAnswer AttachVolume(AttachVolumeCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + String poolid = cmd.getPoolUuid(); + String volumeName = cmd.getVolumeName(); + MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); + if (volume == null) { + return new AttachVolumeAnswer(cmd, "Can't find volume:" + volumeName + "on pool:" + poolid); + } - return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); - } + String vmName = cmd.getVmName(); + MockVMVO vm = _mockVMDao.findByVmName(vmName); + if (vm == null) { + return new AttachVolumeAnswer(cmd, "can't vm :" + vmName); + } + txn.commit(); - @Override - public Answer SecStorageSetup(SecStorageSetupCommand cmd) { - MockSecStorageVO storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); - if (storage == null) { - return new Answer(cmd, false, "can't find the storage"); - } - return new SecStorageSetupAnswer(storage.getMountPoint()); - } + return new AttachVolumeAnswer(cmd, cmd.getDeviceId()); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when attaching volume " + cmd.getVolumeName() + " to VM " + + cmd.getVmName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } - @Override - public Answer ListTemplates(ListTemplateCommand cmd) { - MockSecStorageVO storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); - if (storage == null) { - return new Answer(cmd, false, "Failed to get secondary storage"); - } - - List templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(), MockVolumeType.TEMPLATE); - Map templateInfos = new HashMap(); - for (MockVolumeVO template : templates) { - templateInfos.put(template.getName(), new TemplateInfo(template.getName(), template.getPath().replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false)); - } - - return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); - - } + @Override + public Answer AttachIso(AttachIsoCommand cmd) { + MockVolumeVO iso = findVolumeFromSecondary(cmd.getIsoPath(), cmd.getStoreUrl(), MockVolumeType.ISO); + if (iso == null) { + return new Answer(cmd, false, "Failed to find the iso: " + cmd.getIsoPath() + "on secondary storage " + + cmd.getStoreUrl()); + } - @Override - public Answer Destroy(DestroyCommand cmd) { + String vmName = cmd.getVmName(); + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockVMVO vm = null; + try { + txn.start(); + vm = _mockVMDao.findByVmName(vmName); + txn.commit(); + if (vm == null) { + return new Answer(cmd, false, "can't vm :" + vmName); + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when attaching iso to vm " + vm.getName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new Answer(cmd); + } - MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolume().getPath()); - if (volume != null) { - _mockVolumeDao.remove(volume.getId()); - } - - if (cmd.getVmName() != null) { - MockVm vm = _mockVMDao.findByVmName(cmd.getVmName()); - vm.setState(State.Expunging); - if (vm != null ) { - MockVMVO vmVo = _mockVMDao.createForUpdate(vm.getId()); - _mockVMDao.update(vm.getId(), vmVo); - } - } - return new Answer(cmd); - } + @Override + public Answer DeleteStoragePool(DeleteStoragePoolCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockStoragePoolVO storage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid()); + if (storage == null) { + return new Answer(cmd, false, "can't find storage pool:" + cmd.getPool().getUuid()); + } + _mockStoragePoolDao.remove(storage.getId()); + txn.commit(); + return new Answer(cmd); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when deleting storage pool " + cmd.getPool().getPath(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } - @Override - public DownloadAnswer Download(DownloadCommand cmd) { - MockSecStorageVO ssvo = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); - if (ssvo == null) { - return new DownloadAnswer("can't find secondary storage", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); - } - - MockVolumeVO volume = new MockVolumeVO(); - volume.setPoolId(ssvo.getId()); - volume.setName(cmd.getName()); - volume.setPath(ssvo.getMountPoint() + cmd.getName()); - volume.setSize(0); - volume.setType(MockVolumeType.TEMPLATE); - volume.setStatus(Status.DOWNLOAD_IN_PROGRESS); - volume = _mockVolumeDao.persist(volume); - - return new DownloadAnswer(String.valueOf(volume.getId()), 0, "Downloading", Status.DOWNLOAD_IN_PROGRESS, cmd.getName(), cmd.getName(), volume.getSize(), volume.getSize(), null); - } + @Override + public ModifyStoragePoolAnswer ModifyStoragePool(ModifyStoragePoolCommand cmd) { + StorageFilerTO sf = cmd.getPool(); + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockStoragePoolVO storagePool = null; + try { + txn.start(); + storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid()); + if (storagePool == null) { + storagePool = new MockStoragePoolVO(); + storagePool.setUuid(sf.getUuid()); + storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator); - @Override - public DownloadAnswer DownloadProcess(DownloadProgressCommand cmd) { - String volumeId = cmd.getJobId(); - MockVolumeVO volume = _mockVolumeDao.findById(Long.parseLong(volumeId)); - if (volume == null) { - return new DownloadAnswer("Can't find the downloading volume", Status.ABANDONED); - } - - long size = Math.min(volume.getSize() + DEFAULT_TEMPLATE_SIZE/5, DEFAULT_TEMPLATE_SIZE); - volume.setSize(size); - - double volumeSize = volume.getSize(); - double pct = volumeSize/DEFAULT_TEMPLATE_SIZE; - if (pct >= 1.0) { - volume.setStatus(Status.DOWNLOADED); - _mockVolumeDao.update(volume.getId(), volume); - return new DownloadAnswer(cmd.getJobId(), 100, cmd, com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED, volume.getPath(), volume.getName()); - } else { - _mockVolumeDao.update(volume.getId(), volume); - return new DownloadAnswer(cmd.getJobId(), (int)(pct*100.0) , cmd, com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS, volume.getPath(), volume.getName()); - } - } + Long size = DEFAULT_HOST_STORAGE_SIZE; + String path = sf.getPath(); + int index = path.lastIndexOf("/"); + if (index != -1) { + path = path.substring(index + 1); + if (path != null) { + String values[] = path.split("="); + if (values.length > 1 && values[0].equalsIgnoreCase("size")) { + size = Long.parseLong(values[1]); + } + } + } + storagePool.setCapacity(size); + storagePool.setStorageType(sf.getType()); + storagePool = _mockStoragePoolDao.persist(storagePool); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when modifying storage pool " + cmd.getPool().getPath(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); + } - @Override - public GetStorageStatsAnswer GetStorageStats(GetStorageStatsCommand cmd) { - String uuid = cmd.getStorageId(); - if (uuid == null) { - String secUrl = cmd.getSecUrl(); - MockSecStorageVO secondary = _mockSecStorageDao.findByUrl(secUrl); - if (secondary == null) { - return new GetStorageStatsAnswer(cmd, "Can't find the secondary storage:" + secUrl); - } - Long totalUsed = _mockVolumeDao.findTotalStorageId(secondary.getId()); - return new GetStorageStatsAnswer(cmd, secondary.getCapacity(), totalUsed); - } else { - MockStoragePoolVO pool = _mockStoragePoolDao.findByUuid(uuid); - if (pool == null) { - return new GetStorageStatsAnswer(cmd, "Can't find the pool"); - } - Long totalUsed = _mockVolumeDao.findTotalStorageId(pool.getId()); - if (totalUsed == null) { - totalUsed = 0L; - } - return new GetStorageStatsAnswer(cmd, pool.getCapacity(), totalUsed); - } - } + @Override + public Answer CreateStoragePool(CreateStoragePoolCommand cmd) { + StorageFilerTO sf = cmd.getPool(); + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockStoragePoolVO storagePool = null; + try { + txn.start(); + storagePool = _mockStoragePoolDao.findByUuid(sf.getUuid()); + if (storagePool == null) { + storagePool = new MockStoragePoolVO(); + storagePool.setUuid(sf.getUuid()); + storagePool.setMountPoint("/mnt/" + sf.getUuid() + File.separator); - @Override - public ManageSnapshotAnswer ManageSnapshot(ManageSnapshotCommand cmd) { - String volPath = cmd.getVolumePath(); - - MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(volPath); - if (volume == null) { - return new ManageSnapshotAnswer(cmd, false, "Can't find the volume"); - } - MockStoragePoolVO storagePool = _mockStoragePoolDao.findById(volume.getPoolId()); - if (storagePool == null) { - return new ManageSnapshotAnswer(cmd, false, "Can't find the storage pooll"); - } - - String mountPoint = storagePool.getMountPoint(); - MockVolumeVO snapshot = new MockVolumeVO(); - - snapshot.setName(cmd.getSnapshotName()); - snapshot.setPath(mountPoint + cmd.getSnapshotName()); - snapshot.setSize(volume.getSize()); - snapshot.setPoolId(storagePool.getId()); - snapshot.setType(MockVolumeType.SNAPSHOT); - snapshot.setStatus(Status.DOWNLOADED); - - snapshot = _mockVolumeDao.persist(snapshot); - - return new ManageSnapshotAnswer(cmd, snapshot.getId(), snapshot.getPath(), true, ""); - } + Long size = DEFAULT_HOST_STORAGE_SIZE; + String path = sf.getPath(); + int index = path.lastIndexOf("/"); + if (index != -1) { + path = path.substring(index + 1); + if (path != null) { + String values[] = path.split("="); + if (values.length > 1 && values[0].equalsIgnoreCase("size")) { + size = Long.parseLong(values[1]); + } + } + } + storagePool.setCapacity(size); + storagePool.setStorageType(sf.getType()); + storagePool = _mockStoragePoolDao.persist(storagePool); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when creating storage pool " + cmd.getPool().getPath(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); + } - @Override - public BackupSnapshotAnswer BackupSnapshot(BackupSnapshotCommand cmd, SimulatorInfo info) { - //emulate xenserver backupsnapshot, if the base volume is deleted, then backupsnapshot failed - MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); - if (volume == null) { - return new BackupSnapshotAnswer(cmd, false, "Can't find base volume: " + cmd.getVolumePath(), null, true); - } - String snapshotPath = cmd.getSnapshotUuid(); - MockVolumeVO snapshot = _mockVolumeDao.findByStoragePathAndType(snapshotPath); - if (snapshot == null) { - return new BackupSnapshotAnswer(cmd, false, "can't find snapshot" + snapshotPath, null, true); - } - - String secStorageUrl = cmd.getSecondaryStorageUrl(); - MockSecStorageVO secStorage = _mockSecStorageDao.findByUrl(secStorageUrl); - if (secStorage == null) { - return new BackupSnapshotAnswer(cmd, false, "can't find sec storage" + snapshotPath, null, true); - } - MockVolumeVO newsnapshot = new MockVolumeVO(); - String name = UUID.randomUUID().toString(); - newsnapshot.setName(name); - newsnapshot.setPath(secStorage.getMountPoint() + name); - newsnapshot.setPoolId(secStorage.getId()); - newsnapshot.setSize(snapshot.getSize()); - newsnapshot.setStatus(Status.DOWNLOADED); - newsnapshot.setType(MockVolumeType.SNAPSHOT); - newsnapshot = _mockVolumeDao.persist(newsnapshot); - - return new BackupSnapshotAnswer(cmd, true, null, newsnapshot.getName(), true); - } + @Override + public Answer SecStorageSetup(SecStorageSetupCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockSecStorageVO storage = null; + try { + txn.start(); + storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); + if (storage == null) { + return new Answer(cmd, false, "can't find the storage"); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when setting up sec storage" + cmd.getSecUrl(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new SecStorageSetupAnswer(storage.getMountPoint()); + } - @Override - public Answer DeleteSnapshotBackup(DeleteSnapshotBackupCommand cmd) { - - MockVolumeVO backSnapshot = _mockVolumeDao.findByName(cmd.getSnapshotUuid()); - if (backSnapshot == null) { - return new Answer(cmd, false, "can't find the backupsnapshot: " + cmd.getSnapshotUuid()); - } - - _mockVolumeDao.remove(backSnapshot.getId()); - - return new Answer(cmd); - } + @Override + public Answer ListTemplates(ListTemplateCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockSecStorageVO storage = null; + try { + txn.start(); + storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); + if (storage == null) { + return new Answer(cmd, false, "Failed to get secondary storage"); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when finding sec storage " + cmd.getSecUrl(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } - @Override - public CreateVolumeFromSnapshotAnswer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd) { - MockVolumeVO backSnapshot = _mockVolumeDao.findByName(cmd.getSnapshotUuid()); - if (backSnapshot == null) { - return new CreateVolumeFromSnapshotAnswer(cmd, false, "can't find the backupsnapshot: " + cmd.getSnapshotUuid(), null); - } - - MockStoragePoolVO primary = _mockStoragePoolDao.findByUuid(cmd.getPrimaryStoragePoolNameLabel()); - if (primary == null) { - return new CreateVolumeFromSnapshotAnswer(cmd, false, "can't find the primary storage: " + cmd.getPrimaryStoragePoolNameLabel(), null); - } - - String uuid = UUID.randomUUID().toString(); - MockVolumeVO volume = new MockVolumeVO(); - - volume.setName(uuid); - volume.setPath(primary.getMountPoint() + uuid); - volume.setPoolId(primary.getId()); - volume.setSize(backSnapshot.getSize()); - volume.setStatus(Status.DOWNLOADED); - volume.setType(MockVolumeType.VOLUME); - _mockVolumeDao.persist(volume); - - return new CreateVolumeFromSnapshotAnswer(cmd, true, null, volume.getPath()); - } + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + List templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(), + MockVolumeType.TEMPLATE); - @Override - public Answer DeleteTemplate(DeleteTemplateCommand cmd) { - MockVolumeVO template = _mockVolumeDao.findByStoragePathAndType(cmd.getTemplatePath()); - if (template == null) { - return new Answer(cmd, false, "can't find template:" + cmd.getTemplatePath()); - } - - _mockVolumeDao.remove(template.getId()); - - return new Answer(cmd); - } + Map templateInfos = new HashMap(); + for (MockVolumeVO template : templates) { + templateInfos.put(template.getName(), new TemplateInfo(template.getName(), template.getPath() + .replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false)); + } + txn.commit(); + return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when finding template on sec storage " + storage.getId(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } - @Override - public Answer SecStorageVMSetup(SecStorageVMSetupCommand cmd) { - return new Answer(cmd); - } + @Override + public Answer Destroy(DestroyCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolume().getPath()); + if (volume != null) { + _mockVolumeDao.remove(volume.getId()); + } - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - // TODO Auto-generated method stub - return true; - } + if (cmd.getVmName() != null) { + MockVm vm = _mockVMDao.findByVmName(cmd.getVmName()); + vm.setState(State.Expunging); + if (vm != null) { + MockVMVO vmVo = _mockVMDao.createForUpdate(vm.getId()); + _mockVMDao.update(vm.getId(), vmVo); + } + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when destroying volume " + cmd.getVolume().getPath(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new Answer(cmd); + } - @Override - public boolean start() { - // TODO Auto-generated method stub - return true; - } + @Override + public DownloadAnswer Download(DownloadCommand cmd) { + MockSecStorageVO ssvo = null; + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + ssvo = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); + if (ssvo == null) { + return new DownloadAnswer("can't find secondary storage", + VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error accessing secondary storage " + cmd.getSecUrl(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } - @Override - public boolean stop() { - // TODO Auto-generated method stub - return true; - } + MockVolumeVO volume = new MockVolumeVO(); + volume.setPoolId(ssvo.getId()); + volume.setName(cmd.getName()); + volume.setPath(ssvo.getMountPoint() + cmd.getName()); + volume.setSize(0); + volume.setType(MockVolumeType.TEMPLATE); + volume.setStatus(Status.DOWNLOAD_IN_PROGRESS); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + volume = _mockVolumeDao.persist(volume); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving volume " + volume, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new DownloadAnswer(String.valueOf(volume.getId()), 0, "Downloading", Status.DOWNLOAD_IN_PROGRESS, + cmd.getName(), cmd.getName(), volume.getSize(), volume.getSize(), null); + } - @Override - public String getName() { - return this.getClass().getSimpleName(); - } + @Override + public DownloadAnswer DownloadProcess(DownloadProgressCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + String volumeId = cmd.getJobId(); + MockVolumeVO volume = _mockVolumeDao.findById(Long.parseLong(volumeId)); + if (volume == null) { + return new DownloadAnswer("Can't find the downloading volume", Status.ABANDONED); + } - @Override - public void preinstallTemplates(String url, long zoneId) { - MockSecStorageVO storage = _mockSecStorageDao.findByUrl(url); - if (storage == null) { - storage = new MockSecStorageVO(); - URI uri; - try { - uri = new URI(url); - } catch (URISyntaxException e) { - return; - } - - String nfsHost = uri.getHost(); - String nfsPath = uri.getPath(); - String path = nfsHost + ":" + nfsPath; - String dir = "/mnt/" + UUID.nameUUIDFromBytes(path.getBytes()).toString() + File.separator; - - storage.setUrl(url); - storage.setCapacity(DEFAULT_HOST_STORAGE_SIZE); - - storage.setMountPoint(dir); - - storage = _mockSecStorageDao.persist(storage); - - //preinstall default templates into secondary storage - long defaultTemplateSize = 2 * 1024 * 1024 * 1024L; - MockVolumeVO template = new MockVolumeVO(); - template.setName("simulator-domR"); - template.setPath(storage.getMountPoint() + "template/tmpl/1/9/" + UUID.randomUUID().toString()); - template.setPoolId(storage.getId()); - template.setSize(defaultTemplateSize); - template.setType(MockVolumeType.TEMPLATE); - template.setStatus(Status.DOWNLOADED); - _mockVolumeDao.persist(template); - - template = new MockVolumeVO(); - template.setName("simulator-Centos"); - template.setPath(storage.getMountPoint() + "template/tmpl/1/10/" + UUID.randomUUID().toString()); - template.setPoolId(storage.getId()); - template.setSize(defaultTemplateSize); - template.setType(MockVolumeType.TEMPLATE); - template.setStatus(Status.DOWNLOADED); - _mockVolumeDao.persist(template); - } - - } - - @Override - public StoragePoolInfo getLocalStorage(String hostGuid) { - MockHost host = _mockHostDao.findByGuid(hostGuid); - - MockStoragePoolVO storagePool = _mockStoragePoolDao.findByHost(hostGuid); - if (storagePool == null) { - String uuid = UUID.randomUUID().toString(); - storagePool = new MockStoragePoolVO(); - storagePool.setUuid(uuid); - storagePool.setMountPoint("/mnt/" + uuid + File.separator); - storagePool.setCapacity(DEFAULT_HOST_STORAGE_SIZE); - storagePool.setHostGuid(hostGuid); - storagePool.setStorageType(StoragePoolType.Filesystem); - storagePool = _mockStoragePoolDao.persist(storagePool); - } - - - return new StoragePoolInfo(storagePool.getUuid(), host.getPrivateIpAddress(), storagePool.getMountPoint(), storagePool.getMountPoint(), storagePool.getPoolType(), storagePool.getCapacity(), 0 ); - } - - @Override - public StoragePoolInfo getLocalStorage(String hostGuid, Long storageSize) { - MockHost host = _mockHostDao.findByGuid(hostGuid); - if (storageSize == null) { - storageSize = DEFAULT_HOST_STORAGE_SIZE; - } - MockStoragePoolVO storagePool = _mockStoragePoolDao.findByHost(hostGuid); - if (storagePool == null) { - String uuid = UUID.randomUUID().toString(); - storagePool = new MockStoragePoolVO(); - storagePool.setUuid(uuid); - storagePool.setMountPoint("/mnt/" + uuid + File.separator); - storagePool.setCapacity(storageSize); - storagePool.setHostGuid(hostGuid); - storagePool.setStorageType(StoragePoolType.Filesystem); - storagePool = _mockStoragePoolDao.persist(storagePool); - } - - - return new StoragePoolInfo(storagePool.getUuid(), host.getPrivateIpAddress(), storagePool.getMountPoint(), storagePool.getMountPoint(), storagePool.getPoolType(), storagePool.getCapacity(), 0 ); - } - - @Override - public CreatePrivateTemplateAnswer CreatePrivateTemplateFromSnapshot(CreatePrivateTemplateFromSnapshotCommand cmd) { - String snapshotUUId = cmd.getSnapshotUuid(); - MockVolumeVO snapshot = _mockVolumeDao.findByName(snapshotUUId); - if (snapshot == null) { - snapshotUUId = cmd.getSnapshotName(); - snapshot = _mockVolumeDao.findByName(snapshotUUId); - if (snapshot == null) { - return new CreatePrivateTemplateAnswer(cmd, false, "can't find snapshot:" + snapshotUUId); - } - } - - MockSecStorageVO sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl()); - if (sec == null) { - return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage"); - } - - MockVolumeVO template = new MockVolumeVO(); - String uuid = UUID.randomUUID().toString(); - template.setName(uuid); - template.setPath(sec.getMountPoint() + uuid); - template.setPoolId(sec.getId()); - template.setSize(snapshot.getSize()); - template.setStatus(Status.DOWNLOADED); - template.setType(MockVolumeType.TEMPLATE); - template = _mockVolumeDao.persist(template); - - return new CreatePrivateTemplateAnswer(cmd, true, "", template.getName(), template.getSize(), template.getSize(), template.getName(), ImageFormat.QCOW2); - } - - @Override - public Answer ComputeChecksum(ComputeChecksumCommand cmd) { - MockVolumeVO volume = _mockVolumeDao.findByName(cmd.getTemplatePath()); - if (volume == null) { - return new Answer(cmd, false, "cant' find volume:" + cmd.getTemplatePath()); - } - String md5 = null; - try { - MessageDigest md = MessageDigest.getInstance("md5"); - md5 = String.format("%032x", new BigInteger(1, md.digest(cmd.getTemplatePath().getBytes()))); - } catch (NoSuchAlgorithmException e) { - s_logger.debug("failed to gernerate md5:" + e.toString()); - } - - return new Answer(cmd, true, md5); - } - @Override - public CreatePrivateTemplateAnswer CreatePrivateTemplateFromVolume(CreatePrivateTemplateFromVolumeCommand cmd) { - MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); - if (volume == null) { - return new CreatePrivateTemplateAnswer(cmd, false, "cant' find volume" + cmd.getVolumePath()); - } - - MockSecStorageVO sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl()); - if (sec == null) { - return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage"); - } - - MockVolumeVO template = new MockVolumeVO(); - String uuid = UUID.randomUUID().toString(); - template.setName(uuid); - template.setPath(sec.getMountPoint() + uuid); - template.setPoolId(sec.getId()); - template.setSize(volume.getSize()); - template.setStatus(Status.DOWNLOADED); - template.setType(MockVolumeType.TEMPLATE); - template = _mockVolumeDao.persist(template); - - return new CreatePrivateTemplateAnswer(cmd, true, "", template.getName(), template.getSize(), template.getSize(), template.getName(), ImageFormat.QCOW2); - } - - @Override - public CopyVolumeAnswer CopyVolume(CopyVolumeCommand cmd) { - boolean toSecondaryStorage = cmd.toSecondaryStorage(); - MockSecStorageVO sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageURL()); - if (sec == null) { - return new CopyVolumeAnswer(cmd, false, "can't find secondary storage", null, null); - } - MockStoragePoolVO primaryStorage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid()); - if (primaryStorage == null) { - return new CopyVolumeAnswer(cmd, false, "Can't find primary storage", null, null); - } - - MockVolumeVO volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); - if (volume == null) { - return new CopyVolumeAnswer(cmd, false, "cant' find volume" + cmd.getVolumePath(), null, null); - } - - String name = UUID.randomUUID().toString(); - if (toSecondaryStorage) { - - MockVolumeVO vol = new MockVolumeVO(); - - vol.setName(name); - vol.setPath(sec.getMountPoint() + name); - vol.setPoolId(sec.getId()); - vol.setSize(volume.getSize()); - vol.setStatus(Status.DOWNLOADED); - vol.setType(MockVolumeType.VOLUME); - vol = _mockVolumeDao.persist(vol); - return new CopyVolumeAnswer(cmd, true, null, sec.getMountPoint(), vol.getPath()); - } - else { - MockVolumeVO vol = new MockVolumeVO(); - vol.setName(name); - vol.setPath(primaryStorage.getMountPoint() + name); - vol.setPoolId(primaryStorage.getId()); - vol.setSize(volume.getSize()); - vol.setStatus(Status.DOWNLOADED); - vol.setType(MockVolumeType.VOLUME); - vol = _mockVolumeDao.persist(vol); - return new CopyVolumeAnswer(cmd, true, null, primaryStorage.getMountPoint(), vol.getPath()); - } - } - + long size = Math.min(volume.getSize() + DEFAULT_TEMPLATE_SIZE / 5, DEFAULT_TEMPLATE_SIZE); + volume.setSize(size); + + double volumeSize = volume.getSize(); + double pct = volumeSize / DEFAULT_TEMPLATE_SIZE; + if (pct >= 1.0) { + volume.setStatus(Status.DOWNLOADED); + _mockVolumeDao.update(volume.getId(), volume); + txn.commit(); + return new DownloadAnswer(cmd.getJobId(), 100, cmd, + com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED, volume.getPath(), + volume.getName()); + } else { + _mockVolumeDao.update(volume.getId(), volume); + txn.commit(); + return new DownloadAnswer(cmd.getJobId(), (int) (pct * 100.0), cmd, + com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS, volume.getPath(), + volume.getName()); + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error during download job " + cmd.getJobId(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + + @Override + public GetStorageStatsAnswer GetStorageStats(GetStorageStatsCommand cmd) { + String uuid = cmd.getStorageId(); + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + if (uuid == null) { + String secUrl = cmd.getSecUrl(); + MockSecStorageVO secondary = _mockSecStorageDao.findByUrl(secUrl); + if (secondary == null) { + return new GetStorageStatsAnswer(cmd, "Can't find the secondary storage:" + secUrl); + } + Long totalUsed = _mockVolumeDao.findTotalStorageId(secondary.getId()); + txn.commit(); + return new GetStorageStatsAnswer(cmd, secondary.getCapacity(), totalUsed); + } else { + MockStoragePoolVO pool = _mockStoragePoolDao.findByUuid(uuid); + if (pool == null) { + return new GetStorageStatsAnswer(cmd, "Can't find the pool"); + } + Long totalUsed = _mockVolumeDao.findTotalStorageId(pool.getId()); + if (totalUsed == null) { + totalUsed = 0L; + } + txn.commit(); + return new GetStorageStatsAnswer(cmd, pool.getCapacity(), totalUsed); + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("DBException during storage stats collection for pool " + uuid, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + + @Override + public ManageSnapshotAnswer ManageSnapshot(ManageSnapshotCommand cmd) { + String volPath = cmd.getVolumePath(); + MockVolumeVO volume = null; + MockStoragePoolVO storagePool = null; + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + volume = _mockVolumeDao.findByStoragePathAndType(volPath); + if (volume == null) { + return new ManageSnapshotAnswer(cmd, false, "Can't find the volume"); + } + storagePool = _mockStoragePoolDao.findById(volume.getPoolId()); + if (storagePool == null) { + return new ManageSnapshotAnswer(cmd, false, "Can't find the storage pooll"); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to perform snapshot", ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + String mountPoint = storagePool.getMountPoint(); + MockVolumeVO snapshot = new MockVolumeVO(); + + snapshot.setName(cmd.getSnapshotName()); + snapshot.setPath(mountPoint + cmd.getSnapshotName()); + snapshot.setSize(volume.getSize()); + snapshot.setPoolId(storagePool.getId()); + snapshot.setType(MockVolumeType.SNAPSHOT); + snapshot.setStatus(Status.DOWNLOADED); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + snapshot = _mockVolumeDao.persist(snapshot); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving snapshot " + snapshot, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + return new ManageSnapshotAnswer(cmd, snapshot.getId(), snapshot.getPath(), true, ""); + } + + @Override + public BackupSnapshotAnswer BackupSnapshot(BackupSnapshotCommand cmd, SimulatorInfo info) { + // emulate xenserver backupsnapshot, if the base volume is deleted, then + // backupsnapshot failed + MockVolumeVO volume = null; + MockVolumeVO snapshot = null; + MockSecStorageVO secStorage = null; + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); + if (volume == null) { + return new BackupSnapshotAnswer(cmd, false, "Can't find base volume: " + cmd.getVolumePath(), null, + true); + } + String snapshotPath = cmd.getSnapshotUuid(); + snapshot = _mockVolumeDao.findByStoragePathAndType(snapshotPath); + if (snapshot == null) { + return new BackupSnapshotAnswer(cmd, false, "can't find snapshot" + snapshotPath, null, true); + } + + String secStorageUrl = cmd.getSecondaryStorageUrl(); + secStorage = _mockSecStorageDao.findByUrl(secStorageUrl); + if (secStorage == null) { + return new BackupSnapshotAnswer(cmd, false, "can't find sec storage" + snapshotPath, null, true); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when backing up snapshot"); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + MockVolumeVO newsnapshot = new MockVolumeVO(); + String name = UUID.randomUUID().toString(); + newsnapshot.setName(name); + newsnapshot.setPath(secStorage.getMountPoint() + name); + newsnapshot.setPoolId(secStorage.getId()); + newsnapshot.setSize(snapshot.getSize()); + newsnapshot.setStatus(Status.DOWNLOADED); + newsnapshot.setType(MockVolumeType.SNAPSHOT); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + snapshot = _mockVolumeDao.persist(snapshot); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when backing up snapshot " + newsnapshot, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + return new BackupSnapshotAnswer(cmd, true, null, newsnapshot.getName(), true); + } + + @Override + public Answer DeleteSnapshotBackup(DeleteSnapshotBackupCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockVolumeVO backSnapshot = _mockVolumeDao.findByName(cmd.getSnapshotUuid()); + if (backSnapshot == null) { + return new Answer(cmd, false, "can't find the backupsnapshot: " + cmd.getSnapshotUuid()); + } + _mockVolumeDao.remove(backSnapshot.getId()); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when deleting snapshot"); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new Answer(cmd); + } + + @Override + public CreateVolumeFromSnapshotAnswer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockVolumeVO backSnapshot = null; + MockStoragePoolVO primary = null; + try { + txn.start(); + backSnapshot = _mockVolumeDao.findByName(cmd.getSnapshotUuid()); + if (backSnapshot == null) { + return new CreateVolumeFromSnapshotAnswer(cmd, false, "can't find the backupsnapshot: " + + cmd.getSnapshotUuid(), null); + } + + primary = _mockStoragePoolDao.findByUuid(cmd.getPrimaryStoragePoolNameLabel()); + if (primary == null) { + return new CreateVolumeFromSnapshotAnswer(cmd, false, "can't find the primary storage: " + + cmd.getPrimaryStoragePoolNameLabel(), null); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when creating volume from snapshot", ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + String uuid = UUID.randomUUID().toString(); + MockVolumeVO volume = new MockVolumeVO(); + + volume.setName(uuid); + volume.setPath(primary.getMountPoint() + uuid); + volume.setPoolId(primary.getId()); + volume.setSize(backSnapshot.getSize()); + volume.setStatus(Status.DOWNLOADED); + volume.setType(MockVolumeType.VOLUME); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + _mockVolumeDao.persist(volume); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when creating volume from snapshot " + volume, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + return new CreateVolumeFromSnapshotAnswer(cmd, true, null, volume.getPath()); + } + + @Override + public Answer DeleteTemplate(DeleteTemplateCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockVolumeVO template = _mockVolumeDao.findByStoragePathAndType(cmd.getTemplatePath()); + if (template == null) { + return new Answer(cmd, false, "can't find template:" + cmd.getTemplatePath()); + } + _mockVolumeDao.remove(template.getId()); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when deleting template"); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new Answer(cmd); + } + + @Override + public Answer SecStorageVMSetup(SecStorageVMSetupCommand cmd) { + return new Answer(cmd); + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + // TODO Auto-generated method stub + return true; + } + + @Override + public boolean start() { + // TODO Auto-generated method stub + return true; + } + + @Override + public boolean stop() { + // TODO Auto-generated method stub + return true; + } + + @Override + public String getName() { + return this.getClass().getSimpleName(); + } + + @Override + public void preinstallTemplates(String url, long zoneId) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockSecStorageVO storage = null; + try { + txn.start(); + storage = _mockSecStorageDao.findByUrl(url); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to find sec storage at " + url, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + if (storage == null) { + storage = new MockSecStorageVO(); + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + return; + } + + String nfsHost = uri.getHost(); + String nfsPath = uri.getPath(); + String path = nfsHost + ":" + nfsPath; + String dir = "/mnt/" + UUID.nameUUIDFromBytes(path.getBytes()).toString() + File.separator; + + storage.setUrl(url); + storage.setCapacity(DEFAULT_HOST_STORAGE_SIZE); + + storage.setMountPoint(dir); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + storage = _mockSecStorageDao.persist(storage); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving storage " + storage, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + // preinstall default templates into secondary storage + long defaultTemplateSize = 2 * 1024 * 1024 * 1024L; + MockVolumeVO template = new MockVolumeVO(); + template.setName("simulator-domR"); + template.setPath(storage.getMountPoint() + "template/tmpl/1/9/" + UUID.randomUUID().toString()); + template.setPoolId(storage.getId()); + template.setSize(defaultTemplateSize); + template.setType(MockVolumeType.TEMPLATE); + template.setStatus(Status.DOWNLOADED); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + template = _mockVolumeDao.persist(template); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving template " + template, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + template = new MockVolumeVO(); + template.setName("simulator-Centos"); + template.setPath(storage.getMountPoint() + "template/tmpl/1/10/" + UUID.randomUUID().toString()); + template.setPoolId(storage.getId()); + template.setSize(defaultTemplateSize); + template.setType(MockVolumeType.TEMPLATE); + template.setStatus(Status.DOWNLOADED); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + template = _mockVolumeDao.persist(template); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving template " + template, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + + } + + @Override + public StoragePoolInfo getLocalStorage(String hostGuid) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockHost host = null; + MockStoragePoolVO storagePool = null; + try { + txn.start(); + host = _mockHostDao.findByGuid(hostGuid); + storagePool = _mockStoragePoolDao.findByHost(hostGuid); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to find host " + hostGuid, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + if (storagePool == null) { + String uuid = UUID.randomUUID().toString(); + storagePool = new MockStoragePoolVO(); + storagePool.setUuid(uuid); + storagePool.setMountPoint("/mnt/" + uuid + File.separator); + storagePool.setCapacity(DEFAULT_HOST_STORAGE_SIZE); + storagePool.setHostGuid(hostGuid); + storagePool.setStorageType(StoragePoolType.Filesystem); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + storagePool = _mockStoragePoolDao.persist(storagePool); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving storagePool " + storagePool, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + return new StoragePoolInfo(storagePool.getUuid(), host.getPrivateIpAddress(), storagePool.getMountPoint(), + storagePool.getMountPoint(), storagePool.getPoolType(), storagePool.getCapacity(), 0); + } + + @Override + public StoragePoolInfo getLocalStorage(String hostGuid, Long storageSize) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockHost host = null; + try { + txn.start(); + host = _mockHostDao.findByGuid(hostGuid); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to find host " + hostGuid, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + if (storageSize == null) { + storageSize = DEFAULT_HOST_STORAGE_SIZE; + } + txn = Transaction.open(Transaction.SIMULATOR_DB); + MockStoragePoolVO storagePool = null; + try { + txn.start(); + storagePool = _mockStoragePoolDao.findByHost(hostGuid); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when finding storagePool " + storagePool, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + if (storagePool == null) { + String uuid = UUID.randomUUID().toString(); + storagePool = new MockStoragePoolVO(); + storagePool.setUuid(uuid); + storagePool.setMountPoint("/mnt/" + uuid + File.separator); + storagePool.setCapacity(storageSize); + storagePool.setHostGuid(hostGuid); + storagePool.setStorageType(StoragePoolType.Filesystem); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + storagePool = _mockStoragePoolDao.persist(storagePool); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving storagePool " + storagePool, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + return new StoragePoolInfo(storagePool.getUuid(), host.getPrivateIpAddress(), storagePool.getMountPoint(), + storagePool.getMountPoint(), storagePool.getPoolType(), storagePool.getCapacity(), 0); + } + + @Override + public CreatePrivateTemplateAnswer CreatePrivateTemplateFromSnapshot(CreatePrivateTemplateFromSnapshotCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockVolumeVO snapshot = null; + MockSecStorageVO sec = null; + try { + txn.start(); + String snapshotUUId = cmd.getSnapshotUuid(); + snapshot = _mockVolumeDao.findByName(snapshotUUId); + if (snapshot == null) { + snapshotUUId = cmd.getSnapshotName(); + snapshot = _mockVolumeDao.findByName(snapshotUUId); + if (snapshot == null) { + return new CreatePrivateTemplateAnswer(cmd, false, "can't find snapshot:" + snapshotUUId); + } + } + + sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl()); + if (sec == null) { + return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage"); + } + txn.commit(); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + MockVolumeVO template = new MockVolumeVO(); + String uuid = UUID.randomUUID().toString(); + template.setName(uuid); + template.setPath(sec.getMountPoint() + uuid); + template.setPoolId(sec.getId()); + template.setSize(snapshot.getSize()); + template.setStatus(Status.DOWNLOADED); + template.setType(MockVolumeType.TEMPLATE); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + template = _mockVolumeDao.persist(template); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when saving template " + template, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + return new CreatePrivateTemplateAnswer(cmd, true, "", template.getName(), template.getSize(), + template.getSize(), template.getName(), ImageFormat.QCOW2); + } + + @Override + public Answer ComputeChecksum(ComputeChecksumCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockVolumeVO volume = _mockVolumeDao.findByName(cmd.getTemplatePath()); + if (volume == null) { + return new Answer(cmd, false, "cant' find volume:" + cmd.getTemplatePath()); + } + String md5 = null; + try { + MessageDigest md = MessageDigest.getInstance("md5"); + md5 = String.format("%032x", new BigInteger(1, md.digest(cmd.getTemplatePath().getBytes()))); + } catch (NoSuchAlgorithmException e) { + s_logger.debug("failed to gernerate md5:" + e.toString()); + } + txn.commit(); + return new Answer(cmd, true, md5); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + + @Override + public CreatePrivateTemplateAnswer CreatePrivateTemplateFromVolume(CreatePrivateTemplateFromVolumeCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockVolumeVO volume = null; + MockSecStorageVO sec = null; + try { + txn.start(); + volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); + if (volume == null) { + return new CreatePrivateTemplateAnswer(cmd, false, "cant' find volume" + cmd.getVolumePath()); + } + + sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageUrl()); + if (sec == null) { + return new CreatePrivateTemplateAnswer(cmd, false, "can't find secondary storage"); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when creating private template from volume"); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + MockVolumeVO template = new MockVolumeVO(); + String uuid = UUID.randomUUID().toString(); + template.setName(uuid); + template.setPath(sec.getMountPoint() + uuid); + template.setPoolId(sec.getId()); + template.setSize(volume.getSize()); + template.setStatus(Status.DOWNLOADED); + template.setType(MockVolumeType.TEMPLATE); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + template = _mockVolumeDao.persist(template); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when persisting template " + + template.getName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + return new CreatePrivateTemplateAnswer(cmd, true, "", template.getName(), template.getSize(), + template.getSize(), template.getName(), ImageFormat.QCOW2); + } + + @Override + public CopyVolumeAnswer CopyVolume(CopyVolumeCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + boolean toSecondaryStorage = cmd.toSecondaryStorage(); + MockSecStorageVO sec = null; + MockStoragePoolVO primaryStorage = null; + try { + txn.start(); + sec = _mockSecStorageDao.findByUrl(cmd.getSecondaryStorageURL()); + if (sec == null) { + return new CopyVolumeAnswer(cmd, false, "can't find secondary storage", null, null); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when accessing secondary at " + + cmd.getSecondaryStorageURL(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + primaryStorage = _mockStoragePoolDao.findByUuid(cmd.getPool().getUuid()); + if (primaryStorage == null) { + return new CopyVolumeAnswer(cmd, false, "Can't find primary storage", null, null); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when accessing primary at " + + cmd.getPool(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + MockVolumeVO volume = null; + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + volume = _mockVolumeDao.findByStoragePathAndType(cmd.getVolumePath()); + if (volume == null) { + return new CopyVolumeAnswer(cmd, false, "cant' find volume" + cmd.getVolumePath(), null, null); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when accessing volume at " + + cmd.getVolumePath(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + String name = UUID.randomUUID().toString(); + if (toSecondaryStorage) { + MockVolumeVO vol = new MockVolumeVO(); + vol.setName(name); + vol.setPath(sec.getMountPoint() + name); + vol.setPoolId(sec.getId()); + vol.setSize(volume.getSize()); + vol.setStatus(Status.DOWNLOADED); + vol.setType(MockVolumeType.VOLUME); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + vol = _mockVolumeDao.persist(vol); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when persisting volume " + + vol.getName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new CopyVolumeAnswer(cmd, true, null, sec.getMountPoint(), vol.getPath()); + } else { + MockVolumeVO vol = new MockVolumeVO(); + vol.setName(name); + vol.setPath(primaryStorage.getMountPoint() + name); + vol.setPoolId(primaryStorage.getId()); + vol.setSize(volume.getSize()); + vol.setStatus(Status.DOWNLOADED); + vol.setType(MockVolumeType.VOLUME); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + vol = _mockVolumeDao.persist(vol); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Encountered " + ex.getMessage() + " when persisting volume " + + vol.getName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return new CopyVolumeAnswer(cmd, true, null, primaryStorage.getMountPoint(), vol.getPath()); + } + } } - diff --git a/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java b/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java index cd8f5faf7da..07cf584883e 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java @@ -19,21 +19,7 @@ package com.cloud.agent.manager; import java.util.HashMap; import java.util.Map; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.CheckVirtualMachineCommand; -import com.cloud.agent.api.CleanupNetworkRulesCmd; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.GetVmStatsCommand; -import com.cloud.agent.api.GetVncPortCommand; -import com.cloud.agent.api.MigrateAnswer; -import com.cloud.agent.api.MigrateCommand; -import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.SecurityGroupRuleAnswer; -import com.cloud.agent.api.SecurityGroupRulesCmd; -import com.cloud.agent.api.StartCommand; -import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.*; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; @@ -90,5 +76,8 @@ public interface MockVmManager extends Manager { MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info); GetDomRVersionAnswer getDomRVersion(GetDomRVersionCmd cmd); Map getVms(String hostGuid); - + + CheckRouterAnswer checkRouter(CheckRouterCommand cmd); + + Answer bumpPriority(BumpUpPriorityCommand cmd); } diff --git a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index 9f420beffed..78881f2fc3a 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -25,43 +25,15 @@ import java.util.concurrent.ConcurrentHashMap; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.agent.api.*; +import com.cloud.agent.api.routing.*; +import com.cloud.network.router.VirtualRouter; import org.apache.log4j.Logger; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.CheckVirtualMachineAnswer; -import com.cloud.agent.api.CheckVirtualMachineCommand; -import com.cloud.agent.api.CleanupNetworkRulesCmd; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.GetVmStatsAnswer; -import com.cloud.agent.api.GetVmStatsCommand; -import com.cloud.agent.api.GetVncPortAnswer; -import com.cloud.agent.api.GetVncPortCommand; -import com.cloud.agent.api.MigrateAnswer; -import com.cloud.agent.api.MigrateCommand; -import com.cloud.agent.api.NetworkUsageAnswer; -import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.RebootAnswer; -import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.SecurityGroupRuleAnswer; -import com.cloud.agent.api.SecurityGroupRulesCmd; -import com.cloud.agent.api.StartAnswer; -import com.cloud.agent.api.StartCommand; -import com.cloud.agent.api.StopAnswer; -import com.cloud.agent.api.StopCommand; -import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.IpAssocCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.network.Networks.TrafficType; @@ -75,6 +47,8 @@ import com.cloud.simulator.dao.MockVMDao; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine.State; @Local(value = { MockVmManager.class }) @@ -85,7 +59,7 @@ public class MockVmManagerImpl implements MockVmManager { @Inject MockAgentManager _mockAgentMgr = null; @Inject MockHostDao _mockHostDao = null; @Inject MockSecurityRulesDao _mockSecurityDao = null; - private Map>> _securityRules = new ConcurrentHashMap>>(); + private Map>> _securityRules = new ConcurrentHashMap>>(); public MockVmManagerImpl() { } @@ -101,12 +75,27 @@ public class MockVmManagerImpl implements MockVmManager { int cpuHz, long ramSize, String bootArgs, String hostGuid) { - MockHost host = _mockHostDao.findByGuid(hostGuid); - if (host == null) { - return "can't find host"; - } - - MockVm vm = _mockVmDao.findByVmName(vmName); + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockHost host = null; + MockVm vm = null; + try { + txn.start(); + host = _mockHostDao.findByGuid(hostGuid); + if (host == null) { + return "can't find host"; + } + + vm = _mockVmDao.findByVmName(vmName); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to start VM " + vmName, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + if(vm == null) { int vncPort = 0; if(vncPort < 0) @@ -127,11 +116,35 @@ public class MockVmManagerImpl implements MockVmManager { } else if (vmName.startsWith("i-")) { vm.setType("User"); } - vm = _mockVmDao.persist((MockVMVO)vm); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + vm = _mockVmDao.persist((MockVMVO) vm); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to save vm to db " + vm.getName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } } else { if(vm.getState() == State.Stopped) { vm.setState(State.Running); - _mockVmDao.update(vm.getId(), (MockVMVO)vm); + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + _mockVmDao.update(vm.getId(), (MockVMVO)vm); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to update vm " + vm.getName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } } } @@ -179,37 +192,102 @@ public class MockVmManagerImpl implements MockVmManager { } public boolean rebootVM(String vmName) { - MockVm vm = _mockVmDao.findByVmName(vmName); - if(vm != null) { - vm.setState(State.Running); - _mockVmDao.update(vm.getId(), (MockVMVO)vm); - } - return true; + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockVm vm = _mockVmDao.findByVmName(vmName); + if (vm != null) { + vm.setState(State.Running); + _mockVmDao.update(vm.getId(), (MockVMVO) vm); + + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to reboot vm " + vmName, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + return true; } @Override - public Map getVms(String hostGuid) { - List vms = _mockVmDao.findByHostGuid(hostGuid); - Map vmMap = new HashMap(); - for (MockVMVO vm : vms) { - vmMap.put(vm.getName(), vm); + public Map getVms(String hostGuid) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + List vms = _mockVmDao.findByHostGuid(hostGuid); + Map vmMap = new HashMap(); + for (MockVMVO vm : vms) { + vmMap.put(vm.getName(), vm); + } + txn.commit(); + return vmMap; + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to fetch vms from host " + hostGuid, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); } - return vmMap; } - - @Override - public Map getVmStates(String hostGuid) { - Map states = new HashMap(); - List vms = _mockVmDao.findByHostGuid(hostGuid); - if (vms.isEmpty()) { - return states; - } - for(MockVm vm : vms) { - states.put(vm.getName(), vm.getState()); - } + @Override + public CheckRouterAnswer checkRouter(CheckRouterCommand cmd) { + String router_name = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + int router_id = Integer.parseInt(router_name.split("-")[1]); + if (router_id % 2 == 0) { + s_logger.debug("Found even routerId, making it MASTER in RvR"); + CheckRouterAnswer ans = new CheckRouterAnswer(cmd, "Status: MASTER & Bumped: NO", true); + ans.setState(VirtualRouter.RedundantState.MASTER); + return ans; + } else { + s_logger.debug("Found odd routerId, making it BACKUP in RvR"); + CheckRouterAnswer ans = new CheckRouterAnswer(cmd, "Status: MASTER & Bumped: NO", true); + ans.setState(VirtualRouter.RedundantState.BACKUP); + return ans; + } + } - return states; + @Override + public Answer bumpPriority(BumpUpPriorityCommand cmd) { + String router_name = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + int router_id = Integer.parseInt(router_name.split("-")[1]); + if (router_id % 2 == 0) { + return new Answer(cmd, true, "Status: MASTER & Bumped: YES"); + } else { + return new Answer(cmd, true, "Status: BACKUP & Bumped: YES"); + } + + } + + @Override + public Map getVmStates(String hostGuid) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + Map states = new HashMap(); + List vms = _mockVmDao.findByHostGuid(hostGuid); + if (vms.isEmpty()) { + txn.commit(); + return states; + } + for (MockVm vm : vms) { + states.put(vm.getName(), vm.getState()); + } + txn.commit(); + return states; + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to fetch vms from host " + hostGuid, ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } } @Override @@ -243,14 +321,26 @@ public class MockVmManagerImpl implements MockVmManager { } @Override - public CheckVirtualMachineAnswer checkVmState(CheckVirtualMachineCommand cmd) { - MockVMVO vm = _mockVmDao.findByVmName(cmd.getVmName()); - if (vm == null) { - return new CheckVirtualMachineAnswer(cmd, "can't find vm:" + cmd.getVmName()); - } - - return new CheckVirtualMachineAnswer(cmd, vm.getState(), vm.getVncPort()); - } + public CheckVirtualMachineAnswer checkVmState(CheckVirtualMachineCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockVMVO vm = _mockVmDao.findByVmName(cmd.getVmName()); + if (vm == null) { + return new CheckVirtualMachineAnswer(cmd, "can't find vm:" + cmd.getVmName()); + } + + txn.commit(); + return new CheckVirtualMachineAnswer(cmd, vm.getState(), vm.getVncPort()); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to fetch vm state " + cmd.getVmName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } @Override public Answer startVM(StartCommand cmd, SimulatorInfo info) { @@ -290,22 +380,34 @@ public class MockVmManagerImpl implements MockVmManager { } @Override - public MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info) { - String vmName = cmd.getVmName(); - String destGuid = cmd.getHostGuid(); - MockVMVO vm = _mockVmDao.findByVmNameAndHost(vmName, info.getHostUuid()); - if (vm == null) { - return new MigrateAnswer(cmd, false, "can;t find vm:" + vmName + " on host:" + info.getHostUuid(), null); - } - - MockHost destHost = _mockHostDao.findByGuid(destGuid); - if (destHost == null) { - return new MigrateAnswer(cmd, false, "can;t find host:" + info.getHostUuid(), null); - } - vm.setHostId(destHost.getId()); - _mockVmDao.update(vm.getId(), vm); - return new MigrateAnswer(cmd, true,null, 0); - } + public MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + String vmName = cmd.getVmName(); + String destGuid = cmd.getHostGuid(); + MockVMVO vm = _mockVmDao.findByVmNameAndHost(vmName, info.getHostUuid()); + if (vm == null) { + return new MigrateAnswer(cmd, false, "can;t find vm:" + vmName + " on host:" + info.getHostUuid(), null); + } + + MockHost destHost = _mockHostDao.findByGuid(destGuid); + if (destHost == null) { + return new MigrateAnswer(cmd, false, "can;t find host:" + info.getHostUuid(), null); + } + vm.setHostId(destHost.getId()); + _mockVmDao.update(vm.getId(), vm); + txn.commit(); + return new MigrateAnswer(cmd, true, null, 0); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to migrate vm " + cmd.getVmName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } @Override public Answer IpAssoc(IpAssocCommand cmd) { @@ -328,37 +430,77 @@ public class MockVmManagerImpl implements MockVmManager { } @Override - public Answer CleanupNetworkRules(CleanupNetworkRulesCmd cmd, SimulatorInfo info) { - List rules = _mockSecurityDao.findByHost(info.getHostUuid()); - for (MockSecurityRulesVO rule : rules) { - MockVMVO vm = _mockVmDao.findByVmNameAndHost(rule.getVmName(), info.getHostUuid()); - if (vm == null) { - _mockSecurityDao.remove(rule.getId()); - } - } - return new Answer(cmd); - } + public Answer CleanupNetworkRules(CleanupNetworkRulesCmd cmd, SimulatorInfo info) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + List rules = _mockSecurityDao.findByHost(info.getHostUuid()); + for (MockSecurityRulesVO rule : rules) { + MockVMVO vm = _mockVmDao.findByVmNameAndHost(rule.getVmName(), info.getHostUuid()); + if (vm == null) { + _mockSecurityDao.remove(rule.getId()); + } + } + txn.commit(); + return new Answer(cmd); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to clean up rules", ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } @Override - public Answer stopVM(StopCommand cmd) { - String vmName = cmd.getVmName(); - MockVm vm = _mockVmDao.findByVmName(vmName); - if(vm != null) { - vm.setState(State.Stopped); - _mockVmDao.update(vm.getId(), (MockVMVO)vm); - } + public Answer stopVM(StopCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + String vmName = cmd.getVmName(); + MockVm vm = _mockVmDao.findByVmName(vmName); + if (vm != null) { + vm.setState(State.Stopped); + _mockVmDao.update(vm.getId(), (MockVMVO) vm); + } - if (vmName.startsWith("s-")) { - _mockAgentMgr.handleSystemVMStop(vm.getId()); - } - - return new StopAnswer(cmd, null, new Integer(0), true); - } + if (vmName.startsWith("s-")) { + _mockAgentMgr.handleSystemVMStop(vm.getId()); + } + txn.commit(); + return new StopAnswer(cmd, null, new Integer(0), true); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to stop vm " + cmd.getVmName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } @Override - public Answer rebootVM(RebootCommand cmd) { - return new RebootAnswer(cmd, "Rebooted "+cmd.getVmName(), false); - } + public Answer rebootVM(RebootCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockVm vm = _mockVmDao.findByVmName(cmd.getVmName()); + if (vm != null) { + vm.setState(State.Running); + _mockVmDao.update(vm.getId(), (MockVMVO) vm); + } + txn.commit(); + return new RebootAnswer(cmd, "Rebooted " + cmd.getVmName(), true); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to stop vm " + cmd.getVmName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } @Override public Answer getVncPort(GetVncPortCommand cmd) { diff --git a/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index b980939e387..9a81ea6edaa 100644 --- a/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -24,44 +24,9 @@ import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.agent.api.*; import org.apache.log4j.Logger; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.AttachIsoCommand; -import com.cloud.agent.api.AttachVolumeCommand; -import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.CheckHealthCommand; -import com.cloud.agent.api.CheckNetworkCommand; -import com.cloud.agent.api.CheckVirtualMachineCommand; -import com.cloud.agent.api.CleanupNetworkRulesCmd; -import com.cloud.agent.api.ClusterSyncCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.ComputeChecksumCommand; -import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; -import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; -import com.cloud.agent.api.CreateStoragePoolCommand; -import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.DeleteStoragePoolCommand; -import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.GetHostStatsCommand; -import com.cloud.agent.api.GetStorageStatsCommand; -import com.cloud.agent.api.GetVmStatsCommand; -import com.cloud.agent.api.GetVncPortCommand; -import com.cloud.agent.api.MaintainCommand; -import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.MigrateCommand; -import com.cloud.agent.api.ModifyStoragePoolCommand; -import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.PingTestCommand; -import com.cloud.agent.api.PrepareForMigrationCommand; -import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.SecStorageSetupCommand; -import com.cloud.agent.api.SecStorageVMSetupCommand; -import com.cloud.agent.api.SecurityGroupRulesCmd; -import com.cloud.agent.api.StartCommand; -import com.cloud.agent.api.StopCommand; -import com.cloud.agent.api.StoragePoolInfo; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; @@ -111,11 +76,11 @@ public class SimulatorManagerImpl implements SimulatorManager { public boolean configure(String name, Map params) throws ConfigurationException { /* try { - Connection conn = Transaction.getStandaloneConnectionWithException(); + Connection conn = Transaction.getStandaloneSimulatorConnection(); conn.setAutoCommit(true); _concierge = new ConnectionConcierge("SimulatorConnection", conn, true); } catch (SQLException e) { - throw new CloudRuntimeException("Unable to get a db connection", e); + throw new CloudRuntimeException("Unable to get a db connection to simulator", e); } */ return true; @@ -291,21 +256,28 @@ public class SimulatorManagerImpl implements SimulatorManager { return _mockAgentMgr.maintain((MaintainCommand)cmd); } else if (cmd instanceof GetVmStatsCommand) { return _mockVmMgr.getVmStats((GetVmStatsCommand)cmd); + } else if (cmd instanceof CheckRouterCommand) { + return _mockVmMgr.checkRouter((CheckRouterCommand) cmd); + } else if (cmd instanceof BumpUpPriorityCommand) { + return _mockVmMgr.bumpPriority((BumpUpPriorityCommand) cmd); } else if (cmd instanceof GetDomRVersionCmd) { - return _mockVmMgr.getDomRVersion((GetDomRVersionCmd)cmd); + return _mockVmMgr.getDomRVersion((GetDomRVersionCmd) cmd); } else if (cmd instanceof ClusterSyncCommand) { return new Answer(cmd); + //return new ClusterSyncAnswer(((ClusterSyncCommand) cmd).getClusterId(), this.getVmStates(hostGuid)); } else if (cmd instanceof CopyVolumeCommand) { - return _mockStorageMgr.CopyVolume((CopyVolumeCommand)cmd); + return _mockStorageMgr.CopyVolume((CopyVolumeCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } catch(Exception e) { - s_logger.debug("Failed execute cmd: " + e.toString()); + s_logger.error("Failed execute cmd: " + e.toString()); txn.rollback(); return new Answer(cmd, false, e.toString()); } finally { - txn.transitToAutoManagedConnection(Transaction.CLOUD_DB); + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); } } @@ -315,53 +287,50 @@ public class SimulatorManagerImpl implements SimulatorManager { } @Override - public boolean configureSimulator(Long zoneId, Long podId, Long clusterId, Long hostId, String command, String values) { - MockConfigurationVO config = _mockConfigDao.findByCommand(zoneId, podId, clusterId, hostId, command); - if (config == null) { - config = new MockConfigurationVO(); - config.setClusterId(clusterId); - config.setDataCenterId(zoneId); - config.setPodId(podId); - config.setHostId(hostId); - config.setName(command); - config.setValues(values); - _mockConfigDao.persist(config); - } else { - config.setValues(values); - _mockConfigDao.update(config.getId(), config); - } - return true; - } - - @Override - @DB public Map getVmStates(String hostGuid) { - Transaction txn = Transaction.currentTxn(); - txn.transitToUserManagedConnection(_concierge.conn()); - try { - return _mockVmMgr.getVmStates(hostGuid); - } finally { - txn.transitToAutoManagedConnection(Transaction.CLOUD_DB); - } + return _mockVmMgr.getVmStates(hostGuid); } @Override - @DB public Map getVms(String hostGuid) { - Transaction txn = Transaction.currentTxn(); - txn.transitToUserManagedConnection(_concierge.conn()); - try { - return _mockVmMgr.getVms(hostGuid); - } finally { - txn.transitToAutoManagedConnection(Transaction.CLOUD_DB); - } + return _mockVmMgr.getVms(hostGuid); } - + @Override public HashMap> syncNetworkGroups(String hostGuid) { SimulatorInfo info = new SimulatorInfo(); info.setHostUuid(hostGuid); - return _mockVmMgr.syncNetworkGroups(info); + return _mockVmMgr.syncNetworkGroups(info); } + @Override + public boolean configureSimulator(Long zoneId, Long podId, Long clusterId, Long hostId, String command, + String values) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + MockConfigurationVO config = _mockConfigDao.findByCommand(zoneId, podId, clusterId, hostId, command); + if (config == null) { + config = new MockConfigurationVO(); + config.setClusterId(clusterId); + config.setDataCenterId(zoneId); + config.setPodId(podId); + config.setHostId(hostId); + config.setName(command); + config.setValues(values); + _mockConfigDao.persist(config); + txn.commit(); + } else { + config.setValues(values); + _mockConfigDao.update(config.getId(), config); + txn.commit(); + } + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Unable to configure simulator because of " + ex.getMessage(), ex); + } finally { + txn.close(); + } + return true; + } } diff --git a/agent-simulator/src/com/cloud/simulator/SimulatorRuntimeException.java b/agent-simulator/src/com/cloud/simulator/SimulatorRuntimeException.java new file mode 100644 index 00000000000..ce962a2d296 --- /dev/null +++ b/agent-simulator/src/com/cloud/simulator/SimulatorRuntimeException.java @@ -0,0 +1,41 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.simulator; + +import com.cloud.utils.SerialVersionUID; +import com.cloud.utils.exception.RuntimeCloudException; + +/** + * wrap exceptions that you know there's no point in dealing with. + */ +public class SimulatorRuntimeException extends RuntimeCloudException { + + private static final long serialVersionUID = SerialVersionUID.CloudRuntimeException; + + public SimulatorRuntimeException(String message) { + super(message); + } + + public SimulatorRuntimeException(String message, Throwable th) { + super(message, th); + } + + protected SimulatorRuntimeException() { + super(); + } +} diff --git a/agent/pom.xml b/agent/pom.xml index a5595805042..458d97ce4df 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-agent Apache CloudStack Agents org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT diff --git a/api/pom.xml b/api/pom.xml index db147758ff3..f25a6bcbf74 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-api Apache CloudStack API org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT diff --git a/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java b/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java index 693db291e5f..10dab557bf5 100644 --- a/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java +++ b/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java @@ -45,6 +45,10 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand{ return networkDomain; } + public boolean isAdd() { + return add; + } + @Override public boolean executeInSequence() { return true; diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 067ddf73567..32b852fb4a3 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -382,6 +382,7 @@ public class ApiConstants { public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid"; public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid"; public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename"; + public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid"; public enum HostDetails { diff --git a/api/src/com/cloud/api/BaseAsyncCmd.java b/api/src/com/cloud/api/BaseAsyncCmd.java index 2960e4878e9..cf6d0bdbb93 100644 --- a/api/src/com/cloud/api/BaseAsyncCmd.java +++ b/api/src/com/cloud/api/BaseAsyncCmd.java @@ -25,10 +25,11 @@ import com.cloud.user.UserContext; * queryAsyncJobResult API command. */ public abstract class BaseAsyncCmd extends BaseCmd { + public static final String ipAddressSyncObject = "ipaddress"; public static final String networkSyncObject = "network"; public static final String vpcSyncObject = "vpc"; - + public static final String snapshotHostSyncObject = "snapshothost"; private AsyncJob job; diff --git a/api/src/com/cloud/api/commands/AddVpnUserCmd.java b/api/src/com/cloud/api/commands/AddVpnUserCmd.java index 4a4be0178ec..10dc11a6e43 100644 --- a/api/src/com/cloud/api/commands/AddVpnUserCmd.java +++ b/api/src/com/cloud/api/commands/AddVpnUserCmd.java @@ -120,7 +120,7 @@ public class AddVpnUserCmd extends BaseAsyncCreateCmd { public void execute(){ VpnUser vpnUser = _entityMgr.findById(VpnUser.class, getEntityId()); Account account = _entityMgr.findById(Account.class, vpnUser.getAccountId()); - if (!_ravService.applyVpnUsers(vpnUser.getAccountId())) { + if (!_ravService.applyVpnUsers(vpnUser.getAccountId(), userName)) { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to add vpn user"); } diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 666611476aa..3f3915a705d 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -63,9 +63,15 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P description = "the protocol for the port fowarding rule. Valid values are TCP or UDP.") private String protocol; + @Parameter(name = ApiConstants.PRIVATE_END_PORT, type = CommandType.INTEGER, required = false, description = "the ending port of port forwarding rule's private port range") + private Integer privateEndPort; + @Parameter(name = ApiConstants.PUBLIC_START_PORT, type = CommandType.INTEGER, required = true, description = "the starting port of port forwarding rule's public port range") private Integer publicStartPort; + + @Parameter(name = ApiConstants.PUBLIC_END_PORT, type = CommandType.INTEGER, required = false, description = "the ending port of port forwarding rule's private port range") + private Integer publicEndPort; @IdentityMapper(entityTableName = "vm_instance") @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.LONG, required = true, @@ -93,7 +99,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P // /////////////////////////////////////////////////// public String getEntityTable() { - return "firewall_rules"; + return "firewall_rules"; } public Long getIpAddressId() { @@ -117,7 +123,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P } return null; } - + public Boolean getOpenFirewall() { boolean isVpc = getVpcId() == null ? false : true; if (openFirewall != null) { @@ -154,6 +160,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P return s_name; } + @Override public void execute() throws ResourceUnavailableException { UserContext callerContext = UserContext.current(); @@ -161,16 +168,16 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P PortForwardingRule rule = null; try { UserContext.current().setEventDetails("Rule Id: " + getEntityId()); - + if (getOpenFirewall()) { success = success && _firewallService.applyFirewallRules(ipAddressId, callerContext.getCaller()); } - + success = success && _rulesService.applyPortForwardingRules(ipAddressId, callerContext.getCaller()); // State is different after the rule is applied, so get new object here rule = _entityMgr.findById(PortForwardingRule.class, getEntityId()); - FirewallRuleResponse fwResponse = new FirewallRuleResponse(); + FirewallRuleResponse fwResponse = new FirewallRuleResponse(); if (rule != null) { fwResponse = _responseGenerator.createPortForwardingRuleResponse(rule); setResponseObject(fwResponse); @@ -178,13 +185,13 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P fwResponse.setResponseName(getCommandName()); } finally { if (!success || rule == null) { - + if (getOpenFirewall()) { _firewallService.revokeRelatedFirewallRule(getEntityId(), true); } - + _rulesService.revokePortForwardingRule(getEntityId(), true); - + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to apply port forwarding rule"); } } @@ -213,7 +220,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P @Override public Integer getSourcePortEnd() { - return publicStartPort.intValue(); + return (publicEndPort == null)? publicStartPort.intValue() : publicEndPort.intValue(); } @Override @@ -265,10 +272,10 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P public Ip getDestinationIpAddress() { return null; } - + @Override public void setDestinationIpAddress(Ip destinationIpAddress) { - return; + return; } @Override @@ -278,7 +285,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P @Override public int getDestinationPortEnd() { - return privateStartPort.intValue(); + return (privateEndPort == null)? privateStartPort.intValue() : privateEndPort.intValue(); } @Override @@ -287,12 +294,12 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P if (cidrlist != null) { throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command"); } - + try { PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, getOpenFirewall()); setEntityId(result.getId()); } catch (NetworkRuleConflictException ex) { - s_logger.info("Network rule conflict: ", ex); + s_logger.info("Network rule conflict: " , ex); s_logger.trace("Network Rule Conflict: ", ex); throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage()); } @@ -332,27 +339,27 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P } return ip; } - + @Override public Integer getIcmpCode() { return null; } - + @Override public Integer getIcmpType() { return null; } - + @Override public Long getRelated() { return null; } - @Override - public FirewallRuleType getType() { - return FirewallRuleType.User; - } - + @Override + public FirewallRuleType getType() { + return FirewallRuleType.User; + } + @Override public AsyncJob.Type getInstanceType() { return AsyncJob.Type.FirewallRule; diff --git a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java index d1b6d7ad41a..e78dbdabe67 100755 --- a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java +++ b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java @@ -19,6 +19,7 @@ package com.cloud.api.commands; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; import com.cloud.api.BaseAsyncCreateCmd; import com.cloud.api.BaseCmd; import com.cloud.api.IdentityMapper; @@ -60,6 +61,8 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { @IdentityMapper(entityTableName="snapshot_policy") @Parameter(name = ApiConstants.POLICY_ID, type = CommandType.LONG, description = "policy id of the snapshot, if this is null, then use MANUAL_POLICY.") private Long policyId; + + private String syncObjectType = BaseAsyncCmd.snapshotHostSyncObject; // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// @@ -88,7 +91,16 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { return Snapshot.MANUAL_POLICY_ID; } } + + private Long getHostId() { + Volume volume = _entityMgr.findById(Volume.class, getVolumeId()); + if (volume == null) { + throw new InvalidParameterValueException("Unable to find volume by id"); + } + return _snapshotService.getHostIdForSnapshotOperation(volume); + } + // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// @@ -161,4 +173,21 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + volumeId); } } + + + @Override + public String getSyncObjType() { + if (getSyncObjId() != null) { + return syncObjectType; + } + return null; + } + + @Override + public Long getSyncObjId() { + if (getHostId() != null) { + return getHostId(); + } + return null; + } } diff --git a/api/src/com/cloud/api/commands/DeleteRemoteAccessVpnCmd.java b/api/src/com/cloud/api/commands/DeleteRemoteAccessVpnCmd.java index c924fd9fe13..899142b357f 100644 --- a/api/src/com/cloud/api/commands/DeleteRemoteAccessVpnCmd.java +++ b/api/src/com/cloud/api/commands/DeleteRemoteAccessVpnCmd.java @@ -28,7 +28,8 @@ import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.RemoteAccessVpn; - +import com.cloud.user.UserContext; + @Implementation(description="Destroys a l2tp/ipsec remote access vpn", responseObject=SuccessResponse.class) public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeleteRemoteAccessVpnCmd.class.getName()); @@ -83,7 +84,7 @@ public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd { @Override public void execute() throws ResourceUnavailableException { - _ravService.destroyRemoteAccessVpn(publicIpId); + _ravService.destroyRemoteAccessVpn(publicIpId, UserContext.current().getCaller()); } @Override diff --git a/api/src/com/cloud/api/commands/DeleteVolumeCmd.java b/api/src/com/cloud/api/commands/DeleteVolumeCmd.java index a998311321a..6364e0bdf55 100644 --- a/api/src/com/cloud/api/commands/DeleteVolumeCmd.java +++ b/api/src/com/cloud/api/commands/DeleteVolumeCmd.java @@ -79,7 +79,7 @@ public class DeleteVolumeCmd extends BaseCmd { @Override public void execute() throws ConcurrentOperationException { UserContext.current().setEventDetails("Volume Id: "+getId()); - boolean result = _storageService.deleteVolume(id); + boolean result = _storageService.deleteVolume(id, UserContext.current().getCaller()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/DestroyRouterCmd.java b/api/src/com/cloud/api/commands/DestroyRouterCmd.java index 2026e8727c3..f5286d6a6ad 100644 --- a/api/src/com/cloud/api/commands/DestroyRouterCmd.java +++ b/api/src/com/cloud/api/commands/DestroyRouterCmd.java @@ -96,8 +96,10 @@ public class DestroyRouterCmd extends BaseAsyncCmd { @Override public void execute() throws ConcurrentOperationException, ResourceUnavailableException { - UserContext.current().setEventDetails("Router Id: "+getId()); - VirtualRouter result = _routerService.destroyRouter(getId()); + UserContext ctx = UserContext.current(); + ctx.setEventDetails("Router Id: "+getId()); + + VirtualRouter result = _routerService.destroyRouter(getId(), ctx.getCaller(), ctx.getCallerUserId()); if (result != null) { DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/ListAccountsCmd.java b/api/src/com/cloud/api/commands/ListAccountsCmd.java index eac7d1b9e09..6e0a524cc93 100755 --- a/api/src/com/cloud/api/commands/ListAccountsCmd.java +++ b/api/src/com/cloud/api/commands/ListAccountsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.AccountResponse; import com.cloud.api.response.ListResponse; import com.cloud.user.Account; +import com.cloud.utils.Pair; @Implementation(description="Lists accounts and provides detailed account information for listed accounts", responseObject=AccountResponse.class) public class ListAccountsCmd extends BaseListDomainResourcesCmd { @@ -91,15 +92,15 @@ public class ListAccountsCmd extends BaseListDomainResourcesCmd { @Override public void execute(){ - List accounts = _accountService.searchForAccounts(this); + Pair, Integer> accounts = _accountService.searchForAccounts(this); ListResponse response = new ListResponse(); List accountResponses = new ArrayList(); - for (Account account : accounts) { + for (Account account : accounts.first()) { AccountResponse acctResponse = _responseGenerator.createAccountResponse(account); acctResponse.setObjectName("account"); accountResponses.add(acctResponse); } - response.setResponses(accountResponses); + response.setResponses(accountResponses, accounts.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListAlertsCmd.java b/api/src/com/cloud/api/commands/ListAlertsCmd.java index 15040936195..1f6c7b3e413 100644 --- a/api/src/com/cloud/api/commands/ListAlertsCmd.java +++ b/api/src/com/cloud/api/commands/ListAlertsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.response.AlertResponse; import com.cloud.api.response.ListResponse; +import com.cloud.utils.Pair; @Implementation(description = "Lists all alerts.", responseObject = AlertResponse.class) public class ListAlertsCmd extends BaseListCmd { @@ -71,10 +72,10 @@ public class ListAlertsCmd extends BaseListCmd { @Override public void execute() { - List result = _mgr.searchForAlerts(this); + Pair, Integer> result = _mgr.searchForAlerts(this); ListResponse response = new ListResponse(); List alertResponseList = new ArrayList(); - for (Alert alert : result) { + for (Alert alert : result.first()) { AlertResponse alertResponse = new AlertResponse(); alertResponse.setId(alert.getId()); alertResponse.setAlertType(alert.getType()); @@ -85,7 +86,7 @@ public class ListAlertsCmd extends BaseListCmd { alertResponseList.add(alertResponse); } - response.setResponses(alertResponseList); + response.setResponses(alertResponseList, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListAsyncJobsCmd.java b/api/src/com/cloud/api/commands/ListAsyncJobsCmd.java index bd6e80bd094..e0520cd63a9 100644 --- a/api/src/com/cloud/api/commands/ListAsyncJobsCmd.java +++ b/api/src/com/cloud/api/commands/ListAsyncJobsCmd.java @@ -27,6 +27,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.AsyncJobResponse; import com.cloud.api.response.ListResponse; import com.cloud.async.AsyncJob; +import com.cloud.utils.Pair; @Implementation(description="Lists all pending asynchronous jobs for the account.", responseObject=AsyncJobResponse.class) public class ListAsyncJobsCmd extends BaseListAccountResourcesCmd { @@ -58,14 +59,14 @@ public class ListAsyncJobsCmd extends BaseListAccountResourcesCmd { @Override public void execute(){ - List result = _mgr.searchForAsyncJobs(this); + Pair, Integer> result = _mgr.searchForAsyncJobs(this); ListResponse response = new ListResponse(); List jobResponses = new ArrayList(); - for (AsyncJob job : result) { + for (AsyncJob job : result.first()) { jobResponses.add(_responseGenerator.createAsyncJobResponse(job)); } - response.setResponses(jobResponses); + response.setResponses(jobResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListCfgsByCmd.java b/api/src/com/cloud/api/commands/ListCfgsByCmd.java index 8dc740f00bd..6e07ca9f519 100644 --- a/api/src/com/cloud/api/commands/ListCfgsByCmd.java +++ b/api/src/com/cloud/api/commands/ListCfgsByCmd.java @@ -28,6 +28,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ConfigurationResponse; import com.cloud.api.response.ListResponse; import com.cloud.configuration.Configuration; +import com.cloud.utils.Pair; @Implementation(description = "Lists all configurations.", responseObject = ConfigurationResponse.class) public class ListCfgsByCmd extends BaseListCmd { @@ -78,16 +79,16 @@ public class ListCfgsByCmd extends BaseListCmd { @Override public void execute() { - List result = _mgr.searchForConfigurations(this); + Pair, Integer> result = _mgr.searchForConfigurations(this); ListResponse response = new ListResponse(); List configResponses = new ArrayList(); - for (Configuration cfg : result) { + for (Configuration cfg : result.first()) { ConfigurationResponse cfgResponse = _responseGenerator.createConfigurationResponse(cfg); cfgResponse.setObjectName("configuration"); configResponses.add(cfgResponse); } - response.setResponses(configResponses); + response.setResponses(configResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListClustersCmd.java b/api/src/com/cloud/api/commands/ListClustersCmd.java index e3e2e5096ba..e571bf52e8e 100755 --- a/api/src/com/cloud/api/commands/ListClustersCmd.java +++ b/api/src/com/cloud/api/commands/ListClustersCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ClusterResponse; import com.cloud.api.response.ListResponse; import com.cloud.org.Cluster; +import com.cloud.utils.Pair; @Implementation(description="Lists clusters.", responseObject=ClusterResponse.class) public class ListClustersCmd extends BaseListCmd { @@ -127,16 +128,16 @@ public class ListClustersCmd extends BaseListCmd { @Override public void execute(){ - List result = _mgr.searchForClusters(this); + Pair, Integer> result = _mgr.searchForClusters(this); ListResponse response = new ListResponse(); List clusterResponses = new ArrayList(); - for (Cluster cluster : result) { + for (Cluster cluster : result.first()) { ClusterResponse clusterResponse = _responseGenerator.createClusterResponse(cluster,showCapacities); clusterResponse.setObjectName("cluster"); clusterResponses.add(clusterResponse); } - response.setResponses(clusterResponses); + response.setResponses(clusterResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListDomainChildrenCmd.java b/api/src/com/cloud/api/commands/ListDomainChildrenCmd.java index d5b3f6cbc44..bb0dd7f7e83 100644 --- a/api/src/com/cloud/api/commands/ListDomainChildrenCmd.java +++ b/api/src/com/cloud/api/commands/ListDomainChildrenCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.DomainResponse; import com.cloud.api.response.ListResponse; import com.cloud.domain.Domain; +import com.cloud.utils.Pair; @Implementation(description="Lists all children domains belonging to a specified domain", responseObject=DomainResponse.class) public class ListDomainChildrenCmd extends BaseListCmd { @@ -84,16 +85,16 @@ public class ListDomainChildrenCmd extends BaseListCmd { @Override public void execute(){ - List result = _domainService.searchForDomainChildren(this); + Pair, Integer> result = _domainService.searchForDomainChildren(this); ListResponse response = new ListResponse(); List domainResponses = new ArrayList(); - for (Domain domain : result) { + for (Domain domain : result.first()) { DomainResponse domainResponse = _responseGenerator.createDomainResponse(domain); domainResponse.setObjectName("domain"); domainResponses.add(domainResponse); } - response.setResponses(domainResponses); + response.setResponses(domainResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListDomainsCmd.java b/api/src/com/cloud/api/commands/ListDomainsCmd.java index 9cefe9b48dd..93d1570d6df 100644 --- a/api/src/com/cloud/api/commands/ListDomainsCmd.java +++ b/api/src/com/cloud/api/commands/ListDomainsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.DomainResponse; import com.cloud.api.response.ListResponse; import com.cloud.domain.Domain; +import com.cloud.utils.Pair; @Implementation(description="Lists domains and provides detailed information for listed domains", responseObject=DomainResponse.class) public class ListDomainsCmd extends BaseListCmd { @@ -84,16 +85,16 @@ public class ListDomainsCmd extends BaseListCmd { @Override public void execute(){ - List result = _domainService.searchForDomains(this); + Pair, Integer> result = _domainService.searchForDomains(this); ListResponse response = new ListResponse(); List domainResponses = new ArrayList(); - for (Domain domain : result) { + for (Domain domain : result.first()) { DomainResponse domainResponse = _responseGenerator.createDomainResponse(domain); domainResponse.setObjectName("domain"); domainResponses.add(domainResponse); } - response.setResponses(domainResponses); + response.setResponses(domainResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java index 66dcc4d8e35..c136266b85f 100644 --- a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.FirewallResponse; import com.cloud.api.response.ListResponse; import com.cloud.network.rules.FirewallRule; +import com.cloud.utils.Pair; @Implementation(description="Lists all firewall rules for an IP address.", responseObject=FirewallResponse.class) public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd { @@ -69,16 +70,16 @@ public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List result = _firewallService.listFirewallRules(this); + Pair, Integer> result = _firewallService.listFirewallRules(this); ListResponse response = new ListResponse(); List fwResponses = new ArrayList(); - for (FirewallRule fwRule : result) { + for (FirewallRule fwRule : result.first()) { FirewallResponse ruleData = _responseGenerator.createFirewallResponse(fwRule); ruleData.setObjectName("firewallrule"); fwResponses.add(ruleData); } - response.setResponses(fwResponses); + response.setResponses(fwResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java b/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java index 9974aca8429..79ce7097d8a 100644 --- a/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java +++ b/api/src/com/cloud/api/commands/ListGuestOsCategoriesCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.GuestOSCategoryResponse; import com.cloud.api.response.ListResponse; import com.cloud.storage.GuestOsCategory; +import com.cloud.utils.Pair; @Implementation(description="Lists all supported OS categories for this cloud.", responseObject=GuestOSCategoryResponse.class) public class ListGuestOsCategoriesCmd extends BaseListCmd { @@ -72,10 +73,10 @@ public class ListGuestOsCategoriesCmd extends BaseListCmd { @Override public void execute(){ - List result = _mgr.listGuestOSCategoriesByCriteria(this); + Pair, Integer> result = _mgr.listGuestOSCategoriesByCriteria(this); ListResponse response = new ListResponse(); List osCatResponses = new ArrayList(); - for (GuestOsCategory osCategory : result) { + for (GuestOsCategory osCategory : result.first()) { GuestOSCategoryResponse categoryResponse = new GuestOSCategoryResponse(); categoryResponse.setId(osCategory.getId()); categoryResponse.setName(osCategory.getName()); @@ -84,7 +85,7 @@ public class ListGuestOsCategoriesCmd extends BaseListCmd { osCatResponses.add(categoryResponse); } - response.setResponses(osCatResponses); + response.setResponses(osCatResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListGuestOsCmd.java b/api/src/com/cloud/api/commands/ListGuestOsCmd.java index 396c441f0af..61ec453b83c 100644 --- a/api/src/com/cloud/api/commands/ListGuestOsCmd.java +++ b/api/src/com/cloud/api/commands/ListGuestOsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.GuestOSResponse; import com.cloud.api.response.ListResponse; import com.cloud.storage.GuestOS; +import com.cloud.utils.Pair; @Implementation(description="Lists all supported OS types for this cloud.", responseObject=GuestOSResponse.class) public class ListGuestOsCmd extends BaseListCmd { @@ -79,10 +80,10 @@ public class ListGuestOsCmd extends BaseListCmd { @Override public void execute(){ - List result = _mgr.listGuestOSByCriteria(this); + Pair, Integer> result = _mgr.listGuestOSByCriteria(this); ListResponse response = new ListResponse(); List osResponses = new ArrayList(); - for (GuestOS guestOS : result) { + for (GuestOS guestOS : result.first()) { GuestOSResponse guestOSResponse = new GuestOSResponse(); guestOSResponse.setDescription(guestOS.getDisplayName()); guestOSResponse.setId(guestOS.getId()); @@ -92,7 +93,7 @@ public class ListGuestOsCmd extends BaseListCmd { osResponses.add(guestOSResponse); } - response.setResponses(osResponses); + response.setResponses(osResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListHypervisorCapabilitiesCmd.java b/api/src/com/cloud/api/commands/ListHypervisorCapabilitiesCmd.java index 0cda15a8368..9afd3eb2903 100644 --- a/api/src/com/cloud/api/commands/ListHypervisorCapabilitiesCmd.java +++ b/api/src/com/cloud/api/commands/ListHypervisorCapabilitiesCmd.java @@ -30,6 +30,7 @@ import com.cloud.api.response.HypervisorCapabilitiesResponse; import com.cloud.api.response.ListResponse; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorCapabilities; +import com.cloud.utils.Pair; @Implementation(description="Lists all hypervisor capabilities.", responseObject=HypervisorCapabilitiesResponse.class, since="3.0.0") public class ListHypervisorCapabilitiesCmd extends BaseListCmd { @@ -76,16 +77,17 @@ public class ListHypervisorCapabilitiesCmd extends BaseListCmd { @Override public void execute(){ - List hpvCapabilities = _mgr.listHypervisorCapabilities(getId(), getHypervisor(), getKeyword(), this.getStartIndex(), this.getPageSizeVal()); + Pair, Integer> hpvCapabilities = _mgr.listHypervisorCapabilities(getId(), + getHypervisor(), getKeyword(), this.getStartIndex(), this.getPageSizeVal()); ListResponse response = new ListResponse(); List hpvCapabilitiesResponses = new ArrayList(); - for (HypervisorCapabilities capability : hpvCapabilities) { + for (HypervisorCapabilities capability : hpvCapabilities.first()) { HypervisorCapabilitiesResponse hpvCapabilityResponse = _responseGenerator.createHypervisorCapabilitiesResponse(capability); hpvCapabilityResponse.setObjectName("hypervisorCapabilities"); hpvCapabilitiesResponses.add(hpvCapabilityResponse); } - response.setResponses(hpvCapabilitiesResponses); + response.setResponses(hpvCapabilitiesResponses, hpvCapabilities.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java b/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java index f385fe04c79..fedbac0d177 100644 --- a/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListIpForwardingRulesCmd.java @@ -22,7 +22,6 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListProjectAndAccountResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; @@ -32,6 +31,7 @@ import com.cloud.api.response.IpForwardingRuleResponse; import com.cloud.api.response.ListResponse; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNatRule; +import com.cloud.utils.Pair; @Implementation(description="List the ip forwarding rules", responseObject=FirewallRuleResponse.class) public class ListIpForwardingRulesCmd extends BaseListProjectAndAccountResourcesCmd { @@ -82,17 +82,18 @@ public class ListIpForwardingRulesCmd extends BaseListProjectAndAccountResources @Override public void execute(){ - List result = _rulesService.searchStaticNatRules(publicIpAddressId, id, vmId, this.getStartIndex(), this.getPageSizeVal(), this.getAccountName(), this.getDomainId(), this.getProjectId(), this.isRecursive(), this.listAll()); + Pair, Integer> result = _rulesService.searchStaticNatRules(publicIpAddressId, id, vmId, + this.getStartIndex(), this.getPageSizeVal(), this.getAccountName(), this.getDomainId(), this.getProjectId(), this.isRecursive(), this.listAll()); ListResponse response = new ListResponse(); List ipForwardingResponses = new ArrayList(); - for (FirewallRule rule : result) { + for (FirewallRule rule : result.first()) { StaticNatRule staticNatRule = _rulesService.buildStaticNatRule(rule, false); IpForwardingRuleResponse resp = _responseGenerator.createIpForwardingRuleResponse(staticNatRule); if (resp != null) { ipForwardingResponses.add(resp); } } - response.setResponses(ipForwardingResponses); + response.setResponses(ipForwardingResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListIsosCmd.java b/api/src/com/cloud/api/commands/ListIsosCmd.java index 35a996e9df3..752c834f81b 100755 --- a/api/src/com/cloud/api/commands/ListIsosCmd.java +++ b/api/src/com/cloud/api/commands/ListIsosCmd.java @@ -23,7 +23,6 @@ import java.util.Set; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListTaggedResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; diff --git a/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java b/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java index 43b05402269..8413f607a6b 100644 --- a/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.LoadBalancerResponse; import com.cloud.network.rules.LoadBalancer; +import com.cloud.utils.Pair; @Implementation(description = "Lists load balancer rules.", responseObject = LoadBalancerResponse.class) public class ListLoadBalancerRulesCmd extends BaseListTaggedResourcesCmd { @@ -94,17 +95,17 @@ public class ListLoadBalancerRulesCmd extends BaseListTaggedResourcesCmd { @Override public void execute() { - List loadBalancers = _lbService.searchForLoadBalancers(this); + Pair, Integer> loadBalancers = _lbService.searchForLoadBalancers(this); ListResponse response = new ListResponse(); List lbResponses = new ArrayList(); if (loadBalancers != null) { - for (LoadBalancer loadBalancer : loadBalancers) { + for (LoadBalancer loadBalancer : loadBalancers.first()) { LoadBalancerResponse lbResponse = _responseGenerator.createLoadBalancerResponse(loadBalancer); lbResponse.setObjectName("loadbalancerrule"); lbResponses.add(lbResponse); } } - response.setResponses(lbResponses); + response.setResponses(lbResponses, loadBalancers.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java index 3529558de71..bdb3c3b733b 100644 --- a/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java @@ -31,6 +31,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.NetworkACLResponse; import com.cloud.network.rules.FirewallRule; +import com.cloud.utils.Pair; @Implementation(description="Lists all network ACLs", responseObject=NetworkACLResponse.class) public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { @@ -79,15 +80,15 @@ public class ListNetworkACLsCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List result = _networkACLService.listNetworkACLs(this); + Pair,Integer> result = _networkACLService.listNetworkACLs(this); ListResponse response = new ListResponse(); List aclResponses = new ArrayList(); - for (FirewallRule acl : result) { + for (FirewallRule acl : result.first()) { NetworkACLResponse ruleData = _responseGenerator.createNetworkACLResponse(acl); aclResponses.add(ruleData); } - response.setResponses(aclResponses); + response.setResponses(aclResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListNetworkServiceProvidersCmd.java b/api/src/com/cloud/api/commands/ListNetworkServiceProvidersCmd.java index c973b35b711..97bfd77f463 100644 --- a/api/src/com/cloud/api/commands/ListNetworkServiceProvidersCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworkServiceProvidersCmd.java @@ -30,6 +30,7 @@ import com.cloud.api.response.ListResponse; import com.cloud.api.response.ProviderResponse; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.user.Account; +import com.cloud.utils.Pair; @Implementation(description="Lists network serviceproviders for a given physical network.", responseObject=ProviderResponse.class, since="3.0.0") @@ -86,15 +87,16 @@ public class ListNetworkServiceProvidersCmd extends BaseListCmd { @Override public void execute(){ - List serviceProviders = _networkService.listNetworkServiceProviders(getPhysicalNetworkId(), getName(), getState(), this.getStartIndex(), this.getPageSizeVal()); + Pair, Integer> serviceProviders = _networkService.listNetworkServiceProviders(getPhysicalNetworkId(), + getName(), getState(), this.getStartIndex(), this.getPageSizeVal()); ListResponse response = new ListResponse(); List serviceProvidersResponses = new ArrayList(); - for (PhysicalNetworkServiceProvider serviceProvider : serviceProviders) { + for (PhysicalNetworkServiceProvider serviceProvider : serviceProviders.first()) { ProviderResponse serviceProviderResponse = _responseGenerator.createNetworkServiceProviderResponse(serviceProvider); serviceProvidersResponses.add(serviceProviderResponse); } - response.setResponses(serviceProvidersResponses); + response.setResponses(serviceProvidersResponses, serviceProviders.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListPhysicalNetworksCmd.java b/api/src/com/cloud/api/commands/ListPhysicalNetworksCmd.java index e1ec427d718..ed2968fffe9 100644 --- a/api/src/com/cloud/api/commands/ListPhysicalNetworksCmd.java +++ b/api/src/com/cloud/api/commands/ListPhysicalNetworksCmd.java @@ -32,6 +32,7 @@ import com.cloud.api.response.ListResponse; import com.cloud.api.response.PhysicalNetworkResponse; import com.cloud.network.PhysicalNetwork; import com.cloud.user.Account; +import com.cloud.utils.Pair; @Implementation(description="Lists physical networks", responseObject=PhysicalNetworkResponse.class, since="3.0.0") public class ListPhysicalNetworksCmd extends BaseListCmd { @@ -86,15 +87,16 @@ public class ListPhysicalNetworksCmd extends BaseListCmd { @Override public void execute(){ - List result = _networkService.searchPhysicalNetworks(getId(),getZoneId(), this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), getNetworkName()); + Pair, Integer> result = _networkService.searchPhysicalNetworks(getId(),getZoneId(), + this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), getNetworkName()); if (result != null) { ListResponse response = new ListResponse(); List networkResponses = new ArrayList(); - for (PhysicalNetwork network : result) { + for (PhysicalNetwork network : result.first()) { PhysicalNetworkResponse networkResponse = _responseGenerator.createPhysicalNetworkResponse(network); networkResponses.add(networkResponse); } - response.setResponses(networkResponses); + response.setResponses(networkResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); }else { diff --git a/api/src/com/cloud/api/commands/ListPodsByCmd.java b/api/src/com/cloud/api/commands/ListPodsByCmd.java index b1270bbf192..37b8e29d6f6 100755 --- a/api/src/com/cloud/api/commands/ListPodsByCmd.java +++ b/api/src/com/cloud/api/commands/ListPodsByCmd.java @@ -26,10 +26,10 @@ import com.cloud.api.BaseListCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.ListResponse; import com.cloud.api.response.PodResponse; import com.cloud.dc.Pod; +import com.cloud.utils.Pair; @Implementation(description="Lists all Pods.", responseObject=PodResponse.class) public class ListPodsByCmd extends BaseListCmd { @@ -93,16 +93,16 @@ public class ListPodsByCmd extends BaseListCmd { @Override public void execute(){ - List result = _mgr.searchForPods(this); + Pair, Integer> result = _mgr.searchForPods(this); ListResponse response = new ListResponse(); List podResponses = new ArrayList(); - for (Pod pod : result) { + for (Pod pod : result.first()) { PodResponse podResponse = _responseGenerator.createPodResponse(pod, showCapacities); podResponse.setObjectName("pod"); podResponses.add(podResponse); } - response.setResponses(podResponses); + response.setResponses(podResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java b/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java index 499a574bffb..0315a12d1a5 100644 --- a/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.FirewallRuleResponse; import com.cloud.api.response.ListResponse; import com.cloud.network.rules.PortForwardingRule; +import com.cloud.utils.Pair; @Implementation(description="Lists all port forwarding rules for an IP address.", responseObject=FirewallRuleResponse.class) public class ListPortForwardingRulesCmd extends BaseListTaggedResourcesCmd { @@ -71,16 +72,16 @@ public class ListPortForwardingRulesCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List result = _rulesService.listPortForwardingRules(this); + Pair, Integer> result = _rulesService.listPortForwardingRules(this); ListResponse response = new ListResponse(); List fwResponses = new ArrayList(); - for (PortForwardingRule fwRule : result) { + for (PortForwardingRule fwRule : result.first()) { FirewallRuleResponse ruleData = _responseGenerator.createPortForwardingRuleResponse(fwRule); ruleData.setObjectName("portforwardingrule"); fwResponses.add(ruleData); } - response.setResponses(fwResponses); + response.setResponses(fwResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java index 203d51745d6..389df5e3880 100644 --- a/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java +++ b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.PrivateGatewayResponse; import com.cloud.network.vpc.PrivateGateway; +import com.cloud.utils.Pair; @Implementation(description="List private gateways", responseObject=PrivateGatewayResponse.class) public class ListPrivateGatewaysCmd extends BaseListProjectAndAccountResourcesCmd{ @@ -91,14 +92,14 @@ public class ListPrivateGatewaysCmd extends BaseListProjectAndAccountResourcesCm @Override public void execute() { - List gateways = _vpcService.listPrivateGateway(this); + Pair, Integer> gateways = _vpcService.listPrivateGateway(this); ListResponse response = new ListResponse(); List projectResponses = new ArrayList(); - for (PrivateGateway gateway : gateways) { + for (PrivateGateway gateway : gateways.first()) { PrivateGatewayResponse gatewayResponse = _responseGenerator.createPrivateGatewayResponse(gateway); projectResponses.add(gatewayResponse); } - response.setResponses(projectResponses); + response.setResponses(projectResponses, gateways.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListProjectAccountsCmd.java b/api/src/com/cloud/api/commands/ListProjectAccountsCmd.java index 893e7534ce9..088363377c7 100644 --- a/api/src/com/cloud/api/commands/ListProjectAccountsCmd.java +++ b/api/src/com/cloud/api/commands/ListProjectAccountsCmd.java @@ -31,6 +31,7 @@ import com.cloud.api.response.ProjectAccountResponse; import com.cloud.api.response.ProjectResponse; import com.cloud.projects.ProjectAccount; import com.cloud.user.Account; +import com.cloud.utils.Pair; @Implementation(description="Lists project's accounts", responseObject=ProjectResponse.class, since="3.0.0") public class ListProjectAccountsCmd extends BaseListCmd { @@ -78,14 +79,15 @@ public class ListProjectAccountsCmd extends BaseListCmd { @Override public void execute(){ - List projectAccounts = _projectService.listProjectAccounts(projectId, accountName, role, this.getStartIndex(), this.getPageSizeVal()); + Pair, Integer> projectAccounts = _projectService.listProjectAccounts(projectId, + accountName, role, this.getStartIndex(), this.getPageSizeVal()); ListResponse response = new ListResponse(); List projectResponses = new ArrayList(); - for (ProjectAccount projectAccount : projectAccounts) { + for (ProjectAccount projectAccount : projectAccounts.first()) { ProjectAccountResponse projectAccountResponse = _responseGenerator.createProjectAccountResponse(projectAccount); projectResponses.add(projectAccountResponse); } - response.setResponses(projectResponses); + response.setResponses(projectResponses, projectAccounts.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListProjectInvitationsCmd.java b/api/src/com/cloud/api/commands/ListProjectInvitationsCmd.java index cb707805cde..fe697808b4b 100644 --- a/api/src/com/cloud/api/commands/ListProjectInvitationsCmd.java +++ b/api/src/com/cloud/api/commands/ListProjectInvitationsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.ProjectInvitationResponse; import com.cloud.projects.ProjectInvitation; +import com.cloud.utils.Pair; @Implementation(description = "Lists projects and provides detailed information for listed projects", responseObject = ProjectInvitationResponse.class, since = "3.0.0") public class ListProjectInvitationsCmd extends BaseListAccountResourcesCmd { @@ -82,15 +83,16 @@ public class ListProjectInvitationsCmd extends BaseListAccountResourcesCmd { @Override public void execute() { - List invites = _projectService.listProjectInvitations(id, projectId, this.getAccountName(), this.getDomainId(), state, activeOnly, this.getStartIndex(), this.getPageSizeVal(), + Pair, Integer> invites = _projectService.listProjectInvitations(id, projectId, + this.getAccountName(), this.getDomainId(), state, activeOnly, this.getStartIndex(), this.getPageSizeVal(), this.isRecursive(), this.listAll()); ListResponse response = new ListResponse(); List projectInvitationResponses = new ArrayList(); - for (ProjectInvitation invite : invites) { + for (ProjectInvitation invite : invites.first()) { ProjectInvitationResponse projectResponse = _responseGenerator.createProjectInvitationResponse(invite); projectInvitationResponses.add(projectResponse); } - response.setResponses(projectInvitationResponses); + response.setResponses(projectInvitationResponses, invites.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListProjectsCmd.java b/api/src/com/cloud/api/commands/ListProjectsCmd.java index 187e52cfce1..b7a04eb4e33 100644 --- a/api/src/com/cloud/api/commands/ListProjectsCmd.java +++ b/api/src/com/cloud/api/commands/ListProjectsCmd.java @@ -34,6 +34,7 @@ import com.cloud.api.response.ListResponse; import com.cloud.api.response.ProjectResponse; import com.cloud.exception.InvalidParameterValueException; import com.cloud.projects.Project; +import com.cloud.utils.Pair; @Implementation(description="Lists projects and provides detailed information for listed projects", responseObject=ProjectResponse.class, since="3.0.0") public class ListProjectsCmd extends BaseListAccountResourcesCmd { @@ -106,16 +107,16 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd { @Override public void execute(){ - List projects = _projectService.listProjects(id, name, displayText, state, + Pair, Integer> projects = _projectService.listProjects(id, name, displayText, state, this.getAccountName(), this.getDomainId(), this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), this.listAll(), this.isRecursive(), getTags()); ListResponse response = new ListResponse(); List projectResponses = new ArrayList(); - for (Project project : projects) { + for (Project project : projects.first()) { ProjectResponse projectResponse = _responseGenerator.createProjectResponse(project); projectResponses.add(projectResponse); } - response.setResponses(projectResponses); + response.setResponses(projectResponses, projects.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java index c6acf97c214..a49c5fe6b79 100644 --- a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java +++ b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java @@ -30,6 +30,7 @@ import com.cloud.api.response.IPAddressResponse; import com.cloud.api.response.ListResponse; import com.cloud.async.AsyncJob; import com.cloud.network.IpAddress; +import com.cloud.utils.Pair; @Implementation(description="Lists all public ip addresses", responseObject=IPAddressResponse.class) @@ -141,16 +142,16 @@ public class ListPublicIpAddressesCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List result = _mgr.searchForIPAddresses(this); + Pair, Integer> result = _mgr.searchForIPAddresses(this); ListResponse response = new ListResponse(); List ipAddrResponses = new ArrayList(); - for (IpAddress ipAddress : result) { + for (IpAddress ipAddress : result.first()) { IPAddressResponse ipResponse = _responseGenerator.createIPAddressResponse(ipAddress); ipResponse.setObjectName("publicipaddress"); ipAddrResponses.add(ipResponse); } - response.setResponses(ipAddrResponses); + response.setResponses(ipAddrResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListRemoteAccessVpnsCmd.java b/api/src/com/cloud/api/commands/ListRemoteAccessVpnsCmd.java index 4260e3a3ee3..9dd16448086 100644 --- a/api/src/com/cloud/api/commands/ListRemoteAccessVpnsCmd.java +++ b/api/src/com/cloud/api/commands/ListRemoteAccessVpnsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.RemoteAccessVpnResponse; import com.cloud.network.RemoteAccessVpn; +import com.cloud.utils.Pair; @Implementation(description="Lists remote access vpns", responseObject=RemoteAccessVpnResponse.class) public class ListRemoteAccessVpnsCmd extends BaseListProjectAndAccountResourcesCmd { @@ -64,15 +65,15 @@ public class ListRemoteAccessVpnsCmd extends BaseListProjectAndAccountResourcesC @Override public void execute(){ - List vpns = _ravService.searchForRemoteAccessVpns(this); + Pair, Integer> vpns = _ravService.searchForRemoteAccessVpns(this); ListResponse response = new ListResponse(); List vpnResponses = new ArrayList(); - if (vpns != null && !vpns.isEmpty()) { - for (RemoteAccessVpn vpn : vpns) { + if (vpns.first() != null && !vpns.first().isEmpty()) { + for (RemoteAccessVpn vpn : vpns.first()) { vpnResponses.add(_responseGenerator.createRemoteAccessVpnResponse(vpn)); } } - response.setResponses(vpnResponses); + response.setResponses(vpnResponses, vpns.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListRoutersCmd.java b/api/src/com/cloud/api/commands/ListRoutersCmd.java index 72a9144edda..8bf9ba818dd 100644 --- a/api/src/com/cloud/api/commands/ListRoutersCmd.java +++ b/api/src/com/cloud/api/commands/ListRoutersCmd.java @@ -30,6 +30,7 @@ import com.cloud.api.response.DomainRouterResponse; import com.cloud.api.response.ListResponse; import com.cloud.async.AsyncJob; import com.cloud.network.router.VirtualRouter; +import com.cloud.utils.Pair; @Implementation(description="List routers.", responseObject=DomainRouterResponse.class) public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @@ -129,16 +130,16 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @Override public void execute(){ - List result = _mgr.searchForRouters(this); + Pair, Integer> result = _mgr.searchForRouters(this); ListResponse response = new ListResponse(); List routerResponses = new ArrayList(); - for (VirtualRouter router : result) { + for (VirtualRouter router : result.first()) { DomainRouterResponse routerResponse = _responseGenerator.createDomainRouterResponse(router); routerResponse.setObjectName("router"); routerResponses.add(routerResponse); } - response.setResponses(routerResponses); + response.setResponses(routerResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListSSHKeyPairsCmd.java b/api/src/com/cloud/api/commands/ListSSHKeyPairsCmd.java index 30675542457..8a6cb2730a4 100644 --- a/api/src/com/cloud/api/commands/ListSSHKeyPairsCmd.java +++ b/api/src/com/cloud/api/commands/ListSSHKeyPairsCmd.java @@ -22,13 +22,13 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListProjectAndAccountResourcesCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.SSHKeyPairResponse; import com.cloud.user.SSHKeyPair; +import com.cloud.utils.Pair; @Implementation(description="List registered keypairs", responseObject=SSHKeyPairResponse.class) public class ListSSHKeyPairsCmd extends BaseListProjectAndAccountResourcesCmd { @@ -66,16 +66,16 @@ public class ListSSHKeyPairsCmd extends BaseListProjectAndAccountResourcesCmd { @Override public void execute() { - List resultList = _mgr.listSSHKeyPairs(this); + Pair, Integer> resultList = _mgr.listSSHKeyPairs(this); List responses = new ArrayList(); - for (SSHKeyPair result : resultList) { + for (SSHKeyPair result : resultList.first()) { SSHKeyPairResponse r = new SSHKeyPairResponse(result.getName(), result.getFingerprint()); r.setObjectName("sshkeypair"); responses.add(r); } ListResponse response = new ListResponse(); - response.setResponses(responses); + response.setResponses(responses, resultList.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java index d7b2c9e05f9..cc2aad8f0e1 100644 --- a/api/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/api/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -30,6 +30,7 @@ import com.cloud.api.response.ListResponse; import com.cloud.api.response.SnapshotResponse; import com.cloud.async.AsyncJob; import com.cloud.storage.Snapshot; +import com.cloud.utils.Pair; @Implementation(description="Lists all available snapshots for the account.", responseObject=SnapshotResponse.class) @@ -98,15 +99,15 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List result = _snapshotService.listSnapshots(this); + Pair, Integer> result = _snapshotService.listSnapshots(this); ListResponse response = new ListResponse(); List snapshotResponses = new ArrayList(); - for (Snapshot snapshot : result) { + for (Snapshot snapshot : result.first()) { SnapshotResponse snapshotResponse = _responseGenerator.createSnapshotResponse(snapshot); snapshotResponse.setObjectName("snapshot"); snapshotResponses.add(snapshotResponse); } - response.setResponses(snapshotResponses); + response.setResponses(snapshotResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java b/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java index 3cd828678f3..93b533e6f6f 100644 --- a/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java +++ b/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java @@ -26,6 +26,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.StaticRouteResponse; import com.cloud.network.vpc.StaticRoute; +import com.cloud.utils.Pair; @Implementation(description="Lists all static routes", responseObject=StaticRouteResponse.class) public class ListStaticRoutesCmd extends BaseListTaggedResourcesCmd { @@ -68,15 +69,15 @@ public class ListStaticRoutesCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List result = _vpcService.listStaticRoutes(this); + Pair, Integer> result = _vpcService.listStaticRoutes(this); ListResponse response = new ListResponse(); List routeResponses = new ArrayList(); - for (StaticRoute route : result) { + for (StaticRoute route : result.first()) { StaticRouteResponse ruleData = _responseGenerator.createStaticRouteResponse(route); routeResponses.add(ruleData); } - response.setResponses(routeResponses); + response.setResponses(routeResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java b/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java index 6208dcd5691..7199b0b25ec 100644 --- a/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java +++ b/api/src/com/cloud/api/commands/ListStoragePoolsCmd.java @@ -26,11 +26,11 @@ import com.cloud.api.BaseListCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.response.ListResponse; import com.cloud.api.response.StoragePoolResponse; import com.cloud.async.AsyncJob; import com.cloud.storage.StoragePool; +import com.cloud.utils.Pair; @Implementation(description="Lists storage pools.", responseObject=StoragePoolResponse.class) public class ListStoragePoolsCmd extends BaseListCmd { @@ -114,16 +114,16 @@ public class ListStoragePoolsCmd extends BaseListCmd { @Override public void execute(){ - List pools = _mgr.searchForStoragePools(this); + Pair, Integer> pools = _mgr.searchForStoragePools(this); ListResponse response = new ListResponse(); List poolResponses = new ArrayList(); - for (StoragePool pool : pools) { + for (StoragePool pool : pools.first()) { StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolResponse(pool); poolResponse.setObjectName("storagepool"); poolResponses.add(poolResponse); } - response.setResponses(poolResponses); + response.setResponses(poolResponses, pools.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListSystemVMsCmd.java b/api/src/com/cloud/api/commands/ListSystemVMsCmd.java index 03e19855e0c..44391971469 100644 --- a/api/src/com/cloud/api/commands/ListSystemVMsCmd.java +++ b/api/src/com/cloud/api/commands/ListSystemVMsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.SystemVmResponse; import com.cloud.async.AsyncJob; +import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine; @Implementation(description="List system virtual machines.", responseObject=SystemVmResponse.class) @@ -121,16 +122,16 @@ public class ListSystemVMsCmd extends BaseListCmd { @Override public void execute(){ - List systemVMs = _mgr.searchForSystemVm(this); + Pair, Integer> systemVMs = _mgr.searchForSystemVm(this); ListResponse response = new ListResponse(); List vmResponses = new ArrayList(); - for (VirtualMachine systemVM : systemVMs) { + for (VirtualMachine systemVM : systemVMs.first()) { SystemVmResponse vmResponse = _responseGenerator.createSystemVmResponse(systemVM); vmResponse.setObjectName("systemvm"); vmResponses.add(vmResponse); } - response.setResponses(vmResponses); + response.setResponses(vmResponses, systemVMs.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListTagsCmd.java b/api/src/com/cloud/api/commands/ListTagsCmd.java index 7206b1c882c..b832b423fd0 100644 --- a/api/src/com/cloud/api/commands/ListTagsCmd.java +++ b/api/src/com/cloud/api/commands/ListTagsCmd.java @@ -27,6 +27,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.ResourceTagResponse; import com.cloud.server.ResourceTag; +import com.cloud.utils.Pair; @Implementation(description = "List resource tag(s)", responseObject = ResourceTagResponse.class, since = "Burbank") public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd{ @@ -55,14 +56,14 @@ public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd{ @Override public void execute() { - List tags = _taggedResourceService.listTags(this); + Pair, Integer> tags = _taggedResourceService.listTags(this); ListResponse response = new ListResponse(); List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { + for (ResourceTag tag : tags.first()) { ResourceTagResponse tagResponse = _responseGenerator.createResourceTagResponse(tag, false); tagResponses.add(tagResponse); } - response.setResponses(tagResponses); + response.setResponses(tagResponses, tags.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListTrafficTypesCmd.java b/api/src/com/cloud/api/commands/ListTrafficTypesCmd.java index 59ad2a745a4..671d406e289 100755 --- a/api/src/com/cloud/api/commands/ListTrafficTypesCmd.java +++ b/api/src/com/cloud/api/commands/ListTrafficTypesCmd.java @@ -31,6 +31,7 @@ import com.cloud.api.response.ProviderResponse; import com.cloud.api.response.TrafficTypeResponse; import com.cloud.network.PhysicalNetworkTrafficType; import com.cloud.user.Account; +import com.cloud.utils.Pair; @Implementation(description="Lists traffic types of a given physical network.", responseObject=ProviderResponse.class, since="3.0.0") @@ -72,15 +73,15 @@ public class ListTrafficTypesCmd extends BaseListCmd { @Override public void execute(){ - List trafficTypes = _networkService.listTrafficTypes(getPhysicalNetworkId()); + Pair, Integer> trafficTypes = _networkService.listTrafficTypes(getPhysicalNetworkId()); ListResponse response = new ListResponse(); List trafficTypesResponses = new ArrayList(); - for (PhysicalNetworkTrafficType trafficType : trafficTypes) { + for (PhysicalNetworkTrafficType trafficType : trafficTypes.first()) { TrafficTypeResponse trafficTypeResponse = _responseGenerator.createTrafficTypeResponse(trafficType); trafficTypesResponses.add(trafficTypeResponse); } - response.setResponses(trafficTypesResponses); + response.setResponses(trafficTypesResponses, trafficTypes.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListUsersCmd.java b/api/src/com/cloud/api/commands/ListUsersCmd.java index ec3a1bb54f1..03db56d7187 100644 --- a/api/src/com/cloud/api/commands/ListUsersCmd.java +++ b/api/src/com/cloud/api/commands/ListUsersCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.UserResponse; import com.cloud.user.UserAccount; +import com.cloud.utils.Pair; @Implementation(description="Lists user accounts", responseObject=UserResponse.class) public class ListUsersCmd extends BaseListAccountResourcesCmd { @@ -85,14 +86,14 @@ public class ListUsersCmd extends BaseListAccountResourcesCmd { @Override public void execute(){ - List result = _accountService.searchForUsers(this); + Pair, Integer> result = _accountService.searchForUsers(this); ListResponse response = new ListResponse(); List userResponses = new ArrayList(); - for (UserAccount user : result) { + for (UserAccount user : result.first()) { UserResponse userResponse = _responseGenerator.createUserResponse(user); userResponses.add(userResponse); } - response.setResponses(userResponses); + response.setResponses(userResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVMGroupsCmd.java b/api/src/com/cloud/api/commands/ListVMGroupsCmd.java index 33cc9273f04..34a5e195a3e 100644 --- a/api/src/com/cloud/api/commands/ListVMGroupsCmd.java +++ b/api/src/com/cloud/api/commands/ListVMGroupsCmd.java @@ -28,6 +28,7 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.response.InstanceGroupResponse; import com.cloud.api.response.ListResponse; +import com.cloud.utils.Pair; import com.cloud.vm.InstanceGroup; @Implementation(description="Lists vm groups", responseObject=InstanceGroupResponse.class) @@ -70,16 +71,16 @@ public class ListVMGroupsCmd extends BaseListProjectAndAccountResourcesCmd { @Override public void execute(){ - List groups = _mgr.searchForVmGroups(this); + Pair, Integer> groups = _mgr.searchForVmGroups(this); ListResponse response = new ListResponse(); List responses = new ArrayList(); - for (InstanceGroup group : groups) { + for (InstanceGroup group : groups.first()) { InstanceGroupResponse groupResponse = _responseGenerator.createInstanceGroupResponse(group); groupResponse.setObjectName("instancegroup"); responses.add(groupResponse); } - response.setResponses(responses); + response.setResponses(responses, groups.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVMsCmd.java b/api/src/com/cloud/api/commands/ListVMsCmd.java index 37dfcd32620..2f6f9886563 100755 --- a/api/src/com/cloud/api/commands/ListVMsCmd.java +++ b/api/src/com/cloud/api/commands/ListVMsCmd.java @@ -33,6 +33,8 @@ import com.cloud.api.response.UserVmResponse; import com.cloud.async.AsyncJob; import com.cloud.exception.InvalidParameterValueException; import com.cloud.uservm.UserVm; +import com.cloud.utils.Pair; + @Implementation(description="List the virtual machines owned by the account.", responseObject=UserVmResponse.class) public class ListVMsCmd extends BaseListTaggedResourcesCmd { @@ -197,17 +199,17 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List result = _userVmService.searchForUserVMs(this); + Pair, Integer> result = _userVmService.searchForUserVMs(this); ListResponse response = new ListResponse(); EnumSet details = getDetails(); List vmResponses; if (details.contains(VMDetails.all)){ // for all use optimized version - vmResponses = _responseGenerator.createUserVmResponse("virtualmachine", result.toArray(new UserVm[result.size()])); + vmResponses = _responseGenerator.createUserVmResponse("virtualmachine", result.first().toArray(new UserVm[result.first().size()])); } else { - vmResponses = _responseGenerator.createUserVmResponse("virtualmachine", getDetails(), result.toArray(new UserVm[result.size()])); + vmResponses = _responseGenerator.createUserVmResponse("virtualmachine", getDetails(), result.first().toArray(new UserVm[result.first().size()])); } - response.setResponses(vmResponses); + response.setResponses(vmResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVlanIpRangesCmd.java b/api/src/com/cloud/api/commands/ListVlanIpRangesCmd.java index 039628ab361..5cefa65cb24 100644 --- a/api/src/com/cloud/api/commands/ListVlanIpRangesCmd.java +++ b/api/src/com/cloud/api/commands/ListVlanIpRangesCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.VlanIpRangeResponse; import com.cloud.dc.Vlan; +import com.cloud.utils.Pair; @Implementation(description="Lists all VLAN IP ranges.", responseObject=VlanIpRangeResponse.class) public class ListVlanIpRangesCmd extends BaseListCmd { @@ -132,16 +133,16 @@ public class ListVlanIpRangesCmd extends BaseListCmd { @Override public void execute(){ - List vlans = _mgr.searchForVlans(this); + Pair, Integer> vlans = _mgr.searchForVlans(this); ListResponse response = new ListResponse(); List vlanResponses = new ArrayList(); - for (Vlan vlan : vlans) { + for (Vlan vlan : vlans.first()) { VlanIpRangeResponse vlanResponse = _responseGenerator.createVlanIpRangeResponse(vlan); vlanResponse.setObjectName("vlaniprange"); vlanResponses.add(vlanResponse); } - response.setResponses(vlanResponses); + response.setResponses(vlanResponses, vlans.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVolumesCmd.java b/api/src/com/cloud/api/commands/ListVolumesCmd.java index e0393a9b76b..7875c83aced 100755 --- a/api/src/com/cloud/api/commands/ListVolumesCmd.java +++ b/api/src/com/cloud/api/commands/ListVolumesCmd.java @@ -30,6 +30,7 @@ import com.cloud.api.response.ListResponse; import com.cloud.api.response.VolumeResponse; import com.cloud.async.AsyncJob; import com.cloud.storage.Volume; +import com.cloud.utils.Pair; @Implementation(description="Lists all volumes.", responseObject=VolumeResponse.class) @@ -117,17 +118,17 @@ public class ListVolumesCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - List volumes = _storageService.searchForVolumes(this); + Pair, Integer> volumes = _storageService.searchForVolumes(this); ListResponse response = new ListResponse(); List volResponses = new ArrayList(); - for (Volume volume : volumes) { + for (Volume volume : volumes.first()) { VolumeResponse volResponse = _responseGenerator.createVolumeResponse(volume); volResponse.setObjectName("volume"); volResponses.add(volResponse); } - response.setResponses(volResponses); + response.setResponses(volResponses, volumes.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVpnConnectionsCmd.java b/api/src/com/cloud/api/commands/ListVpnConnectionsCmd.java index 512f9458f27..c7d5523d7b2 100644 --- a/api/src/com/cloud/api/commands/ListVpnConnectionsCmd.java +++ b/api/src/com/cloud/api/commands/ListVpnConnectionsCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.Site2SiteVpnConnectionResponse; import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.utils.Pair; @Implementation(description="Lists site to site vpn connection gateways", responseObject=Site2SiteVpnConnectionResponse.class) public class ListVpnConnectionsCmd extends BaseListProjectAndAccountResourcesCmd { @@ -72,20 +73,19 @@ public class ListVpnConnectionsCmd extends BaseListProjectAndAccountResourcesCmd @Override public void execute(){ - List conns = _s2sVpnService.searchForVpnConnections(this); + Pair, Integer> conns = _s2sVpnService.searchForVpnConnections(this); ListResponse response = new ListResponse(); List connResponses = new ArrayList(); - if (conns != null && !conns.isEmpty()) { - for (Site2SiteVpnConnection conn : conns) { - if (conn == null) { - continue; - } - Site2SiteVpnConnectionResponse site2SiteVpnConnectonRes = _responseGenerator.createSite2SiteVpnConnectionResponse(conn); - site2SiteVpnConnectonRes.setObjectName("vpnconnection"); - connResponses.add(site2SiteVpnConnectonRes); + for (Site2SiteVpnConnection conn : conns.first()) { + if (conn == null) { + continue; } + Site2SiteVpnConnectionResponse site2SiteVpnConnectonRes = _responseGenerator.createSite2SiteVpnConnectionResponse(conn); + site2SiteVpnConnectonRes.setObjectName("vpnconnection"); + connResponses.add(site2SiteVpnConnectonRes); } - response.setResponses(connResponses); + + response.setResponses(connResponses, conns.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVpnCustomerGatewaysCmd.java b/api/src/com/cloud/api/commands/ListVpnCustomerGatewaysCmd.java index 1e8b06ba81e..51fde93976e 100644 --- a/api/src/com/cloud/api/commands/ListVpnCustomerGatewaysCmd.java +++ b/api/src/com/cloud/api/commands/ListVpnCustomerGatewaysCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.Site2SiteCustomerGatewayResponse; import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.utils.Pair; @Implementation(description="Lists site to site vpn customer gateways", responseObject=Site2SiteCustomerGatewayResponse.class) public class ListVpnCustomerGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { @@ -64,20 +65,19 @@ public class ListVpnCustomerGatewaysCmd extends BaseListProjectAndAccountResourc @Override public void execute(){ - List gws = _s2sVpnService.searchForCustomerGateways(this); + Pair, Integer> gws = _s2sVpnService.searchForCustomerGateways(this); ListResponse response = new ListResponse(); List gwResponses = new ArrayList(); - if (gws != null && !gws.isEmpty()) { - for (Site2SiteCustomerGateway gw : gws) { - if (gw == null) { - continue; - } - Site2SiteCustomerGatewayResponse site2SiteCustomerGatewayRes = _responseGenerator.createSite2SiteCustomerGatewayResponse(gw); - site2SiteCustomerGatewayRes.setObjectName("vpncustomergateway"); - gwResponses.add(site2SiteCustomerGatewayRes); + for (Site2SiteCustomerGateway gw : gws.first()) { + if (gw == null) { + continue; } + Site2SiteCustomerGatewayResponse site2SiteCustomerGatewayRes = _responseGenerator.createSite2SiteCustomerGatewayResponse(gw); + site2SiteCustomerGatewayRes.setObjectName("vpncustomergateway"); + gwResponses.add(site2SiteCustomerGatewayRes); } - response.setResponses(gwResponses); + + response.setResponses(gwResponses, gws.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVpnGatewaysCmd.java b/api/src/com/cloud/api/commands/ListVpnGatewaysCmd.java index 63b212b0e31..ec0c054fdb7 100644 --- a/api/src/com/cloud/api/commands/ListVpnGatewaysCmd.java +++ b/api/src/com/cloud/api/commands/ListVpnGatewaysCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.Site2SiteVpnGatewayResponse; import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.utils.Pair; @Implementation(description="Lists site 2 site vpn gateways", responseObject=Site2SiteVpnGatewayResponse.class) public class ListVpnGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { @@ -71,20 +72,19 @@ public class ListVpnGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { @Override public void execute(){ - List gws = _s2sVpnService.searchForVpnGateways(this); + Pair, Integer> gws = _s2sVpnService.searchForVpnGateways(this); ListResponse response = new ListResponse(); List gwResponses = new ArrayList(); - if (gws != null && !gws.isEmpty()) { - for (Site2SiteVpnGateway gw : gws) { - if (gw == null) { - continue; - } - Site2SiteVpnGatewayResponse site2SiteVpnGatewayRes = _responseGenerator.createSite2SiteVpnGatewayResponse(gw); - site2SiteVpnGatewayRes.setObjectName("vpngateway"); - gwResponses.add(site2SiteVpnGatewayRes); - } + for (Site2SiteVpnGateway gw : gws.first()) { + if (gw == null) { + continue; + } + Site2SiteVpnGatewayResponse site2SiteVpnGatewayRes = _responseGenerator.createSite2SiteVpnGatewayResponse(gw); + site2SiteVpnGatewayRes.setObjectName("vpngateway"); + gwResponses.add(site2SiteVpnGatewayRes); } - response.setResponses(gwResponses); + + response.setResponses(gwResponses, gws.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/ListVpnUsersCmd.java b/api/src/com/cloud/api/commands/ListVpnUsersCmd.java index 9bc77ffb805..9280ed59f0a 100644 --- a/api/src/com/cloud/api/commands/ListVpnUsersCmd.java +++ b/api/src/com/cloud/api/commands/ListVpnUsersCmd.java @@ -29,6 +29,7 @@ import com.cloud.api.Parameter; import com.cloud.api.response.ListResponse; import com.cloud.api.response.VpnUsersResponse; import com.cloud.network.VpnUser; +import com.cloud.utils.Pair; @Implementation(description="Lists vpn users", responseObject=VpnUsersResponse.class) public class ListVpnUsersCmd extends BaseListProjectAndAccountResourcesCmd { @@ -69,15 +70,15 @@ public class ListVpnUsersCmd extends BaseListProjectAndAccountResourcesCmd { @Override public void execute(){ - List vpnUsers = _ravService.searchForVpnUsers(this); + Pair, Integer> vpnUsers = _ravService.searchForVpnUsers(this); ListResponse response = new ListResponse(); List vpnResponses = new ArrayList(); - for (VpnUser vpnUser : vpnUsers) { + for (VpnUser vpnUser : vpnUsers.first()) { vpnResponses.add(_responseGenerator.createVpnUserResponse(vpnUser)); } - response.setResponses(vpnResponses); + response.setResponses(vpnResponses, vpnUsers.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/com/cloud/api/commands/RemoveVpnUserCmd.java b/api/src/com/cloud/api/commands/RemoveVpnUserCmd.java index 57a4301c8aa..151b3512273 100644 --- a/api/src/com/cloud/api/commands/RemoveVpnUserCmd.java +++ b/api/src/com/cloud/api/commands/RemoveVpnUserCmd.java @@ -108,12 +108,12 @@ public class RemoveVpnUserCmd extends BaseAsyncCmd { @Override public void execute(){ Account owner = _accountService.getAccount(getEntityOwnerId()); - boolean result = _ravService.removeVpnUser(owner.getId(), userName); + boolean result = _ravService.removeVpnUser(owner.getId(), userName, UserContext.current().getCaller()); if (!result) { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to remove vpn user"); } - if (!_ravService.applyVpnUsers(owner.getId())) { + if (!_ravService.applyVpnUsers(owner.getId(), userName)) { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to apply vpn user removal"); } SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/com/cloud/api/commands/UpdatePhysicalNetworkCmd.java b/api/src/com/cloud/api/commands/UpdatePhysicalNetworkCmd.java index 30fa5325f0d..a6abc039042 100644 --- a/api/src/com/cloud/api/commands/UpdatePhysicalNetworkCmd.java +++ b/api/src/com/cloud/api/commands/UpdatePhysicalNetworkCmd.java @@ -22,11 +22,9 @@ import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; import com.cloud.api.BaseAsyncCmd; -import com.cloud.api.BaseCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; import com.cloud.api.response.PhysicalNetworkResponse; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; @@ -99,13 +97,9 @@ public class UpdatePhysicalNetworkCmd extends BaseAsyncCmd { @Override public void execute(){ PhysicalNetwork result = _networkService.updatePhysicalNetwork(getId(),getNetworkSpeed(), getTags(), getVlan(), getState()); - if (result != null) { - PhysicalNetworkResponse response = _responseGenerator.createPhysicalNetworkResponse(result); - response.setResponseName(getCommandName()); - this.setResponseObject(response); - }else { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update physical network"); - } + PhysicalNetworkResponse response = _responseGenerator.createPhysicalNetworkResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); } @Override diff --git a/api/src/com/cloud/api/response/IPAddressResponse.java b/api/src/com/cloud/api/response/IPAddressResponse.java index a9c1769406f..ea5b793b7fb 100644 --- a/api/src/com/cloud/api/response/IPAddressResponse.java +++ b/api/src/com/cloud/api/response/IPAddressResponse.java @@ -62,7 +62,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR @SerializedName(ApiConstants.FOR_VIRTUAL_NETWORK) @Param(description="the virtual network for the IP address") private Boolean forVirtualNetwork; - @SerializedName(ApiConstants.VLAN_ID) @Param(description="the ID of the VLAN associated with the IP address") + @SerializedName(ApiConstants.VLAN_ID) @Param(description="the ID of the VLAN associated with the IP address." + + " This parameter is visible to ROOT admins only") private IdentityProxy vlanId = new IdentityProxy("vlan"); @SerializedName("vlanname") @Param(description="the VLAN associated with the IP address") diff --git a/api/src/com/cloud/api/response/ListResponse.java b/api/src/com/cloud/api/response/ListResponse.java index 47f76a52afa..ebba4020ccb 100644 --- a/api/src/com/cloud/api/response/ListResponse.java +++ b/api/src/com/cloud/api/response/ListResponse.java @@ -22,6 +22,7 @@ import com.cloud.api.ResponseObject; public class ListResponse extends BaseResponse { List responses; + private transient Integer count; public List getResponses() { return responses; @@ -30,12 +31,22 @@ public class ListResponse extends BaseResponse { public void setResponses(List responses) { this.responses = responses; } + + public void setResponses(List responses, Integer count) { + this.responses = responses; + this.count = count; + } + public Integer getCount() { + if (count != null) { + return count; + } + if (responses != null) { return responses.size(); - } else { - return null; } + + return null; } } diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java index a4158f16323..0917cfafdef 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -77,7 +77,7 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName("related") @Param(description="related to what other network configuration") private IdentityProxy related = new IdentityProxy("networks"); - @SerializedName("broadcasturi") @Param(description="broadcast uri of the network") + @SerializedName("broadcasturi") @Param(description="broadcast uri of the network. This parameter is visible to ROOT admins only") private String broadcastUri; @SerializedName(ApiConstants.DNS1) @Param(description="the first DNS for the network") @@ -89,7 +89,7 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.TYPE) @Param(description="the type of the network") private String type; - @SerializedName(ApiConstants.VLAN) @Param(description="the vlan of the network") + @SerializedName(ApiConstants.VLAN) @Param(description="The vlan of the network. This parameter is visible to ROOT admins only") private String vlan; @SerializedName(ApiConstants.ACL_TYPE) @Param(description="acl type - access type to the network") diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index e84a40379ad..9e6b36b780b 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -291,4 +291,9 @@ public class EventTypes { public static final String EVENT_TAGS_CREATE = "CREATE_TAGS"; public static final String EVENT_TAGS_DELETE = "DELETE_TAGS"; + // external network device events + public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD"; + public static final String EVENT_EXTERNAL_NVP_CONTROLLER_DELETE = "PHYSICAL.NVPCONTROLLER.DELETE"; + public static final String EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE = "PHYSICAL.NVPCONTROLLER.CONFIGURE"; + } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 6bbc36c75ac..a20056152eb 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -82,7 +82,7 @@ public interface NetworkService { PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List isolationMethods, String broadcastDomainRange, Long domainId, List tags, String name); - List searchPhysicalNetworks(Long id, Long zoneId, String keyword, + Pair, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name); PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List tags, @@ -97,7 +97,7 @@ public interface NetworkService { PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId, List enabledServices); - List listNetworkServiceProviders(Long physicalNetworkId, String name, + Pair, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize); PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List enabledServices); @@ -123,7 +123,7 @@ public interface NetworkService { boolean deletePhysicalNetworkTrafficType(Long id); - List listTrafficTypes(Long physicalNetworkId); + Pair, Integer> listTrafficTypes(Long physicalNetworkId); PhysicalNetwork getDefaultPhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType); diff --git a/api/src/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/com/cloud/network/VirtualNetworkApplianceService.java index d0fb527037b..300c9932829 100644 --- a/api/src/com/cloud/network/VirtualNetworkApplianceService.java +++ b/api/src/com/cloud/network/VirtualNetworkApplianceService.java @@ -21,6 +21,7 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.router.VirtualRouter; +import com.cloud.user.Account; public interface VirtualNetworkApplianceService { /** @@ -60,6 +61,6 @@ public interface VirtualNetworkApplianceService { VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException; - VirtualRouter destroyRouter(long routerId) throws ResourceUnavailableException, ConcurrentOperationException; + VirtualRouter destroyRouter(long routerId, Account caller, Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException; } diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java index ec8e7bce2e8..10ea5095b58 100644 --- a/api/src/com/cloud/network/element/NetworkElement.java +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -104,10 +104,11 @@ public interface NetworkElement extends Adapter { /** * The network is being destroyed. * @param network + * @param context TODO * @return * @throws ConcurrentOperationException */ - boolean destroy(Network network) throws ConcurrentOperationException, ResourceUnavailableException; + boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; /** * Check if the instances of this Element are configured to be used on the physical network referred by this provider. diff --git a/api/src/com/cloud/network/element/VpcProvider.java b/api/src/com/cloud/network/element/VpcProvider.java index e4593e9dbdd..aa5d2245a44 100644 --- a/api/src/com/cloud/network/element/VpcProvider.java +++ b/api/src/com/cloud/network/element/VpcProvider.java @@ -41,11 +41,12 @@ public interface VpcProvider extends NetworkElement{ /** * @param vpc + * @param context TODO * @return * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException; + boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException; diff --git a/api/src/com/cloud/network/firewall/FirewallService.java b/api/src/com/cloud/network/firewall/FirewallService.java index 6eb9f9943ac..07c2fb5a838 100644 --- a/api/src/com/cloud/network/firewall/FirewallService.java +++ b/api/src/com/cloud/network/firewall/FirewallService.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.network.firewall; + import java.util.List; import com.cloud.api.commands.ListFirewallRulesCmd; @@ -23,11 +24,12 @@ import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.FirewallRule; import com.cloud.user.Account; +import com.cloud.utils.Pair; public interface FirewallService { FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException; - List listFirewallRules(ListFirewallRulesCmd cmd); + Pair, Integer> listFirewallRules(ListFirewallRulesCmd cmd); /** * Revokes a firewall rule diff --git a/api/src/com/cloud/network/firewall/NetworkACLService.java b/api/src/com/cloud/network/firewall/NetworkACLService.java index 1977088881c..10896b6dc74 100644 --- a/api/src/com/cloud/network/firewall/NetworkACLService.java +++ b/api/src/com/cloud/network/firewall/NetworkACLService.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.network.firewall; + import java.util.List; import com.cloud.api.commands.ListNetworkACLsCmd; @@ -23,6 +24,7 @@ import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.FirewallRule; import com.cloud.user.Account; +import com.cloud.utils.Pair; public interface NetworkACLService { FirewallRule getNetworkACL(long ruleId); @@ -43,6 +45,6 @@ public interface NetworkACLService { * @param listNetworkACLsCmd * @return */ - List listNetworkACLs(ListNetworkACLsCmd cmd); + Pair, Integer> listNetworkACLs(ListNetworkACLsCmd cmd); } diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java index d30195db5b9..0cf2ef94ace 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java @@ -30,6 +30,8 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.StickinessPolicy; import com.cloud.uservm.UserVm; +import com.cloud.utils.Pair; + public interface LoadBalancingRulesService { /** @@ -90,7 +92,7 @@ public interface LoadBalancingRulesService { * by id, name, public ip, and vm instance id * @return list of load balancers that match the criteria */ - List searchForLoadBalancers(ListLoadBalancerRulesCmd cmd); + Pair, Integer> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd); /** * List stickiness policies based on the given criteria @@ -105,4 +107,4 @@ public interface LoadBalancingRulesService { LoadBalancer findById(long LoadBalancer); -} +} \ No newline at end of file diff --git a/api/src/com/cloud/network/rules/RulesService.java b/api/src/com/cloud/network/rules/RulesService.java index 9dd602bc330..8eadfba7712 100644 --- a/api/src/com/cloud/network/rules/RulesService.java +++ b/api/src/com/cloud/network/rules/RulesService.java @@ -23,9 +23,10 @@ import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; +import com.cloud.utils.Pair; public interface RulesService { - List searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId, Long projectId, boolean isRecursive, boolean listAll); + Pair, Integer> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId, Long projectId, boolean isRecursive, boolean listAll); /** * Creates a port forwarding rule between two ip addresses or between @@ -60,7 +61,7 @@ public interface RulesService { * the command object holding the criteria for listing port forwarding rules (the ipAddress) * @return list of port forwarding rules on the given address, empty list if no rules exist */ - public List listPortForwardingRules(ListPortForwardingRulesCmd cmd); + public Pair, Integer> listPortForwardingRules(ListPortForwardingRulesCmd cmd); boolean applyPortForwardingRules(long ipAdddressId, Account caller) throws ResourceUnavailableException; diff --git a/api/src/com/cloud/network/security/SecurityGroupService.java b/api/src/com/cloud/network/security/SecurityGroupService.java index bace6bbcd26..4a4b1712aba 100644 --- a/api/src/com/cloud/network/security/SecurityGroupService.java +++ b/api/src/com/cloud/network/security/SecurityGroupService.java @@ -18,13 +18,13 @@ package com.cloud.network.security; import java.util.List; -import com.cloud.api.commands.AuthorizeSecurityGroupIngressCmd; import com.cloud.api.commands.AuthorizeSecurityGroupEgressCmd; +import com.cloud.api.commands.AuthorizeSecurityGroupIngressCmd; import com.cloud.api.commands.CreateSecurityGroupCmd; import com.cloud.api.commands.DeleteSecurityGroupCmd; import com.cloud.api.commands.ListSecurityGroupsCmd; -import com.cloud.api.commands.RevokeSecurityGroupIngressCmd; import com.cloud.api.commands.RevokeSecurityGroupEgressCmd; +import com.cloud.api.commands.RevokeSecurityGroupIngressCmd; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceInUseException; diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java index 7d8de553897..c13e37f1b55 100644 --- a/api/src/com/cloud/network/vpc/VpcService.java +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -34,6 +34,7 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.user.Account; import com.cloud.user.User; +import com.cloud.utils.Pair; public interface VpcService { @@ -190,7 +191,7 @@ public interface VpcService { * @param listPrivateGatewaysCmd * @return */ - public List listPrivateGateway(ListPrivateGatewaysCmd listPrivateGatewaysCmd); + public Pair, Integer> listPrivateGateway(ListPrivateGatewaysCmd listPrivateGatewaysCmd); /** * @param routeId @@ -223,7 +224,7 @@ public interface VpcService { * @param listStaticRoutesCmd * @return */ - public List listStaticRoutes(ListStaticRoutesCmd cmd); + public Pair, Integer> listStaticRoutes(ListStaticRoutesCmd cmd); /** * @param id diff --git a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java index b1c07a113cf..4d820a7a258 100644 --- a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java +++ b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java @@ -24,21 +24,23 @@ import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VpnUser; +import com.cloud.user.Account; +import com.cloud.utils.Pair; public interface RemoteAccessVpnService { RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, long networkId) throws NetworkRuleConflictException; - void destroyRemoteAccessVpn(long vpnServerAddressId) throws ResourceUnavailableException; + void destroyRemoteAccessVpn(long vpnServerAddressId, Account caller) throws ResourceUnavailableException; RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException; VpnUser addVpnUser(long vpnOwnerId, String userName, String password); - boolean removeVpnUser(long vpnOwnerId, String userName); + boolean removeVpnUser(long vpnOwnerId, String userName, Account caller); List listVpnUsers(long vpnOwnerId, String userName); - boolean applyVpnUsers(long vpnOwnerId); + boolean applyVpnUsers(long vpnOwnerId, String userName); - List searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd); - List searchForVpnUsers(ListVpnUsersCmd cmd); + Pair, Integer> searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd); + Pair, Integer> searchForVpnUsers(ListVpnUsersCmd cmd); List listRemoteAccessVpns(long networkId); diff --git a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java index 0e98b9e8786..69eab1a13f6 100644 --- a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java +++ b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java @@ -31,10 +31,10 @@ import com.cloud.api.commands.ResetVpnConnectionCmd; import com.cloud.api.commands.UpdateVpnCustomerGatewayCmd; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.IpAddress; import com.cloud.network.Site2SiteCustomerGateway; import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.utils.Pair; public interface Site2SiteVpnService { Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd); @@ -46,8 +46,8 @@ public interface Site2SiteVpnService { boolean deleteVpnGateway(DeleteVpnGatewayCmd deleteVpnGatewayCmd); boolean deleteVpnConnection(DeleteVpnConnectionCmd deleteVpnConnectionCmd) throws ResourceUnavailableException; Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd resetVpnConnectionCmd) throws ResourceUnavailableException; - List searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd); - List searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd); - List searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd); + Pair, Integer> searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd); + Pair, Integer> searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd); + Pair, Integer> searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd); Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCmd updateVpnCustomerGatewayCmd); } diff --git a/api/src/com/cloud/projects/ProjectService.java b/api/src/com/cloud/projects/ProjectService.java index c792f268e01..ea143b7e868 100644 --- a/api/src/com/cloud/projects/ProjectService.java +++ b/api/src/com/cloud/projects/ProjectService.java @@ -24,6 +24,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.projects.ProjectAccount.Role; import com.cloud.user.Account; +import com.cloud.utils.Pair; public interface ProjectService { /** @@ -60,7 +61,7 @@ public interface ProjectService { */ Project getProject(long id); - List listProjects(Long id, String name, String displayText, String state, String accountName, + Pair, Integer> listProjects(Long id, String name, String displayText, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, boolean isRecursive, Map tags); ProjectAccount assignAccountToProject(Project project, long accountId, Role accountRole); @@ -79,9 +80,9 @@ public interface ProjectService { boolean deleteAccountFromProject(long projectId, String accountName); - List listProjectAccounts(long projectId, String accountName, String role, Long startIndex, Long pageSizeVal); + Pair, Integer> listProjectAccounts(long projectId, String accountName, String role, Long startIndex, Long pageSizeVal); - List listProjectInvitations(Long id, Long projectId, String accountName, Long domainId, String state, boolean activeOnly, Long startIndex, Long pageSizeVal, boolean isRecursive, + Pair, Integer> listProjectInvitations(Long id, Long projectId, String accountName, Long domainId, String state, boolean activeOnly, Long startIndex, Long pageSizeVal, boolean isRecursive, boolean listAll); boolean updateInvitation(long projectId, String accountName, String token, boolean accept); @@ -93,4 +94,6 @@ public interface ProjectService { Project enableProject(long projectId); boolean deleteProjectInvitation(long invitationId); + + Project findByProjectAccountIdIncludingRemoved(long projectAccountId); } diff --git a/api/src/com/cloud/resource/ResourceState.java b/api/src/com/cloud/resource/ResourceState.java index bb4c7e96ee8..6e0afa6c06c 100755 --- a/api/src/com/cloud/resource/ResourceState.java +++ b/api/src/com/cloud/resource/ResourceState.java @@ -113,6 +113,7 @@ public enum ResourceState { s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.Disable, ResourceState.Disabled); s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.DeleteHost, ResourceState.Disabled); s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.InternalEnterMaintenance, ResourceState.Maintenance); + s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.AdminCancelMaintenance, ResourceState.Enabled); s_fsm.addTransition(ResourceState.Error, Event.InternalCreated, ResourceState.Error); } } diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 8dcc3983599..7532cae2a64 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -114,7 +114,7 @@ public interface ManagementService { * * @return map of configuration name/values */ - List searchForConfigurations(ListCfgsByCmd c); + Pair, Integer> searchForConfigurations(ListCfgsByCmd c); /** * Searches for Service Offerings by the specified search criteria Can search by: "name" @@ -130,7 +130,7 @@ public interface ManagementService { * @param c * @return */ - List searchForClusters(ListClustersCmd c); + Pair, Integer> searchForClusters(ListClustersCmd c); /** * Searches for Clusters by the specified zone Id. @@ -145,7 +145,7 @@ public interface ManagementService { * @param cmd * @return List of Pods */ - List searchForPods(ListPodsByCmd cmd); + Pair, Integer> searchForPods(ListPodsByCmd cmd); /** * Searches for servers by the specified search criteria Can search by: "name", "type", "state", "dataCenterId", @@ -184,7 +184,7 @@ public interface ManagementService { * @param cmd * @return List of DomainRouters. */ - List searchForRouters(ListRoutersCmd cmd); + Pair, Integer> searchForRouters(ListRoutersCmd cmd); /** * Obtains a list of IP Addresses by the specified search criteria. Can search by: "userId", "dataCenterId", @@ -194,21 +194,21 @@ public interface ManagementService { * the command that wraps the search criteria * @return List of IPAddresses */ - List searchForIPAddresses(ListPublicIpAddressesCmd cmd); + Pair, Integer> searchForIPAddresses(ListPublicIpAddressesCmd cmd); /** * Obtains a list of all guest OS. * * @return list of GuestOS */ - List listGuestOSByCriteria(ListGuestOsCmd cmd); + Pair, Integer> listGuestOSByCriteria(ListGuestOsCmd cmd); /** * Obtains a list of all guest OS categories. * * @return list of GuestOSCategories */ - List listGuestOSCategoriesByCriteria(ListGuestOsCategoriesCmd cmd); + Pair, Integer> listGuestOSCategoriesByCriteria(ListGuestOsCategoriesCmd cmd); VirtualMachine stopSystemVM(StopSystemVmCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException; @@ -235,7 +235,7 @@ public interface ManagementService { * @param c * @return List of Alerts */ - List searchForAlerts(ListAlertsCmd cmd); + Pair, Integer> searchForAlerts(ListAlertsCmd cmd); /** * list all the capacity rows in capacity operations table @@ -283,7 +283,7 @@ public interface ManagementService { * the command that wraps the search criteria (zone, pod, name, IP address, path, and cluster id) * @return a list of storage pools that match the given criteria */ - List searchForStoragePools(ListStoragePoolsCmd cmd); + Pair, Integer> searchForStoragePools(ListStoragePoolsCmd cmd); /** * List system VMs by the given search criteria @@ -292,7 +292,7 @@ public interface ManagementService { * the command that wraps the search criteria (host, name, state, type, zone, pod, and/or id) * @return the list of system vms that match the given criteria */ - List searchForSystemVm(ListSystemVMsCmd cmd); + Pair, Integer> searchForSystemVm(ListSystemVMsCmd cmd); /** * Returns back a SHA1 signed response @@ -307,7 +307,7 @@ public interface ManagementService { InstanceGroup updateVmGroup(UpdateVMGroupCmd cmd); - List searchForVmGroups(ListVMGroupsCmd cmd); + Pair, Integer> searchForVmGroups(ListVMGroupsCmd cmd); Map listCapabilities(ListCapabilitiesCmd cmd); @@ -354,7 +354,7 @@ public interface ManagementService { * @param cmd * @return List of Vlans */ - List searchForVlans(ListVlanIpRangesCmd cmd); + Pair, Integer> searchForVlans(ListVlanIpRangesCmd cmd); /** * Search for async jobs by account and/or startDate @@ -363,7 +363,7 @@ public interface ManagementService { * the command specifying the account and start date parameters * @return the list of async jobs that match the criteria */ - List searchForAsyncJobs(ListAsyncJobsCmd cmd); + Pair, Integer> searchForAsyncJobs(ListAsyncJobsCmd cmd); /** * Generates a random password that will be used (initially) by newly created and started virtual machines @@ -383,7 +383,7 @@ public interface ManagementService { * The api command class. * @return The list of key pairs found. */ - List listSSHKeyPairs(ListSSHKeyPairsCmd cmd); + Pair, Integer> listSSHKeyPairs(ListSSHKeyPairsCmd cmd); /** * Registers a key pair for a given public key. @@ -439,7 +439,7 @@ public interface ManagementService { String[] listEventTypes(); - List listHypervisorCapabilities(Long id, HypervisorType hypervisorType, String keyword, Long startIndex, Long pageSizeVal); + Pair, Integer> listHypervisorCapabilities(Long id, HypervisorType hypervisorType, String keyword, Long startIndex, Long pageSizeVal); HypervisorCapabilities updateHypervisorCapabilities(Long id, Long maxGuestsLimit, Boolean securityGroupEnabled); diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java index dd1b1c6b4ee..dce799e5ca2 100644 --- a/api/src/com/cloud/server/TaggedResourceService.java +++ b/api/src/com/cloud/server/TaggedResourceService.java @@ -21,6 +21,7 @@ import java.util.Map; import com.cloud.api.commands.ListTagsCmd; import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.utils.Pair; public interface TaggedResourceService { @@ -46,7 +47,7 @@ public interface TaggedResourceService { * @param listTagsCmd * @return */ - List listTags(ListTagsCmd listTagsCmd); + Pair, Integer> listTags(ListTagsCmd listTagsCmd); /** * @param resourceIds diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index 4fb3b55f057..587c138465a 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -32,6 +32,8 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceInUseException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; +import com.cloud.utils.Pair; public interface StorageService{ /** @@ -71,7 +73,6 @@ public interface StorageService{ */ Volume createVolume(CreateVolumeCmd cmd); - boolean deleteVolume(long volumeId) throws ConcurrentOperationException; /** * Delete the storage pool @@ -114,7 +115,7 @@ public interface StorageService{ Volume migrateVolume(Long volumeId, Long storagePoolId) throws ConcurrentOperationException; - List searchForVolumes(ListVolumesCmd cmd); + Pair, Integer> searchForVolumes(ListVolumesCmd cmd); /** * Uploads the volume to secondary storage @@ -125,4 +126,6 @@ public interface StorageService{ */ Volume uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException; + boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException; + } diff --git a/api/src/com/cloud/storage/snapshot/SnapshotService.java b/api/src/com/cloud/storage/snapshot/SnapshotService.java index 0500061670a..84388e9cfe6 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotService.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotService.java @@ -26,7 +26,9 @@ import com.cloud.api.commands.ListSnapshotsCmd; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.Snapshot; +import com.cloud.storage.Volume; import com.cloud.user.Account; +import com.cloud.utils.Pair; public interface SnapshotService { @@ -38,7 +40,7 @@ public interface SnapshotService { * @return list of snapshots * @throws PermissionDeniedException */ - List listSnapshots(ListSnapshotsCmd cmd); + Pair, Integer> listSnapshots(ListSnapshotsCmd cmd); /** * Delete specified snapshot from the specified. If no other policies are assigned it calls destroy snapshot. This @@ -97,4 +99,10 @@ public interface SnapshotService { * @return the Snapshot that was created */ Snapshot createSnapshot(Long volumeId, Long policyId, Long snapshotId, Account snapshotOwner); + + /** + * @param vol + * @return + */ + Long getHostIdForSnapshotOperation(Volume vol); } diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index 53383d3c7c3..90e35519578 100755 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -191,9 +191,9 @@ public interface AccountService { public String[] createApiKeyAndSecretKey(RegisterCmd cmd); - List searchForAccounts(ListAccountsCmd cmd); + Pair, Integer> searchForAccounts(ListAccountsCmd cmd); - List searchForUsers(ListUsersCmd cmd) + Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException; UserAccount getUserByApiKey(String apiKey); diff --git a/api/src/com/cloud/user/DomainService.java b/api/src/com/cloud/user/DomainService.java index 362f87ea0be..83f362264b0 100644 --- a/api/src/com/cloud/user/DomainService.java +++ b/api/src/com/cloud/user/DomainService.java @@ -22,6 +22,7 @@ import com.cloud.api.commands.ListDomainChildrenCmd; import com.cloud.api.commands.ListDomainsCmd; import com.cloud.domain.Domain; import com.cloud.exception.PermissionDeniedException; +import com.cloud.utils.Pair; public interface DomainService { @@ -39,10 +40,10 @@ public interface DomainService { boolean deleteDomain(long domainId, Boolean cleanup); - List searchForDomains(ListDomainsCmd cmd) + Pair, Integer> searchForDomains(ListDomainsCmd cmd) throws PermissionDeniedException; - List searchForDomainChildren(ListDomainChildrenCmd cmd) + Pair, Integer> searchForDomainChildren(ListDomainChildrenCmd cmd) throws PermissionDeniedException; } diff --git a/api/src/com/cloud/user/UserAccount.java b/api/src/com/cloud/user/UserAccount.java index 734e16b0f8f..2a6bd4f33e3 100644 --- a/api/src/com/cloud/user/UserAccount.java +++ b/api/src/com/cloud/user/UserAccount.java @@ -56,4 +56,6 @@ public interface UserAccount { String getRegistrationToken(); boolean isRegistered(); + + int getLoginAttempts(); } diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 6635657042f..02682b0c6f3 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -53,6 +53,7 @@ import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; +import com.cloud.utils.Pair; import com.cloud.utils.exception.ExecutionException; public interface UserVmService { @@ -378,7 +379,7 @@ public interface UserVmService { * the API command that wraps the search criteria * @return List of UserVMs. */ - List searchForUserVMs(ListVMsCmd cmd); + Pair, Integer> searchForUserVMs(ListVMsCmd cmd); HypervisorType getHypervisorTypeOfUserVM(long vmid); diff --git a/awsapi/LICENSE.txt b/awsapi/LICENSE.txt deleted file mode 100644 index 6b0b1270ff0..00000000000 --- a/awsapi/LICENSE.txt +++ /dev/null @@ -1,203 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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/awsapi/NOTICE.txt b/awsapi/NOTICE.txt deleted file mode 100644 index bd396930715..00000000000 --- a/awsapi/NOTICE.txt +++ /dev/null @@ -1,26 +0,0 @@ -========================================================================= -== NOTICE file corresponding to the section 4 d of == -== the Apache License, Version 2.0, == -== in this case for the Apache Axis2 distribution. == -========================================================================= - -This product includes software developed by -The Apache Software Foundation (http://www.apache.org/). -Portions Copyright 2006 International Business Machines Corp. -Portions Copyright 2005-2007 WSO2, Inc. - -This product also includes schemas and specification developed by: -- the W3C consortium (http://www.w3c.org) - -This product also includes WS-* schemas developed by International -Business Machines Corporation, Microsoft Corporation, BEA Systems, -TIBCO Software, SAP AG, Sonic Software, and VeriSign - -This product also includes a WSDL developed by salesforce.com -- Copyright 1999-2006 salesforce.com, inc. - -Portions of the included xmlbeans library were originally based on the following: -- software copyright (c) 2000-2003, BEA Systems, . - -Please read the different LICENSE files present in the lib directory of -this distribution. diff --git a/awsapi/README.txt b/awsapi/README.txt deleted file mode 100644 index 99788bf81e1..00000000000 --- a/awsapi/README.txt +++ /dev/null @@ -1,75 +0,0 @@ -====================================================== -Apache Axis2 1.6.2 build (17-04-2012) - -http://axis.apache.org/axis2/java/core/ ------------------------------------------------------- - -___________________ -Building -=================== - -We use Maven 2 (http://maven.apache.org) to build, and you'll find a -pom.xml in each module, as well as at the top level. Use "mvn install" -(or "mvn clean install" to clean up first) to build. - -IMPORTANT: the *first* time you build a given version of Axis2, you will not -be able to do a regular "mvn install" from the top level - this is because -we have a couple of custom Maven plugins that (due to some dependency- -resolution issues in Maven) must be built and installed in your local -repository before a build will succeed. This means you need to do one -of the following: - - 1) Use ant (http://ant.apache.org) to build the first time. There is - a build.xml at the top level which automatically builds the plugins - first and then runs a regular "mvn install". - - 2) Manually "mvn install" both of the plugins in the following places: - - modules/tool/axis2-mar-maven-plugin - modules/tool/axis2-aar-maven-plugin - -___________________ -Documentation -=================== - -Documentation can be found in the 'docs' distribution of this release -and in the main site. - -___________________ -Deploying -=================== - -To deploy a new Web service in Axis2 the following three steps must -be performed: - 1) Create the Web service implementation class, supporting classes - and the services.xml file, - 2) Archive the class files into a jar with the services.xml file in - the META-INF directory - 3) Drop the jar file to the $AXIS2_HOME/WEB-INF/services directory - where $AXIS2_HOME represents the install directory of your Axis2 - runtime. (In the case of a servelet container this would be the - "axis2" directory inside "webapps".) - -To verify the deployment please go to http://:/axis2/ and -follow the "Services" Link. - -For more information please refer to the User's Guide. - -___________________ -Support -=================== - -Any problem with this release can be reported to Axis mailing list -or in the JIRA issue tracker. If you are sending an email to the mailing -list make sure to add the [Axis2] prefix to the subject. - -Mailing list subscription: - java-dev-subscribe@axis.apache.org - -Jira: - http://issues.apache.org/jira/browse/AXIS2 - - -Thank you for using Axis2! - -The Axis2 Team. diff --git a/awsapi/conf/cloud-bridge.properties b/awsapi/conf/cloud-bridge.properties index 4d1b23f86e7..d0820e840ec 100644 --- a/awsapi/conf/cloud-bridge.properties +++ b/awsapi/conf/cloud-bridge.properties @@ -1,25 +1,25 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -host=http://localhost:7080/awsapi -storage.root=/Users/john1/S3-Mount -storage.multipartDir=__multipart__uploads__ -bucket.dns=false -serviceEndpoint=localhost:7080 - - - +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +host=http://localhost:7080/awsapi +storage.root=/Users/john1/S3-Mount +storage.multipartDir=__multipart__uploads__ +bucket.dns=false +serviceEndpoint=localhost:7080 + + + diff --git a/awsapi/docs/AmazonEC2/EC2-API-tool-setup.txt b/awsapi/docs/AmazonEC2/EC2-API-tool-setup.txt deleted file mode 100644 index d75fcee61c1..00000000000 --- a/awsapi/docs/AmazonEC2/EC2-API-tool-setup.txt +++ /dev/null @@ -1,68 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. - ------------------------------------------------------------ - - -1. Get the EC2 API tool -http://s3.amazonaws.com/ec2-downloads/ec2-api-tools-1.3-62308.zip. Install it by unzipping it - -2. Prepare a API request certificate, if you have Amazon account, Amazon has the service to let you generate and download a X509 certificate and its associated private key - -3. Prepare EC2 command running environment - -Set following environment variables and make them point to the right location. - -EC2_ACCESS_KEY= -EC2_SECRET_KEY= -EC2_HOME: -EC2_CERT: -EC2_PRIVATE_KEY: -EC2_URL: http:///bridge/AmazonEC2 - -4. Generate CloudStack API key -Login to CloudStack management console, you can generate an API key and its secret key pair there. - -5. Inform CloudBridge about the API/security key pair to use - -http:///bridge/rest/AmazonEC2?Action=SetUserKeys&accesskey=&secretkey= - -6. Upload certificate and associate it with the API key -There is not a convenient tool to do that, this has to be done in manual step. following HTML form can be used to submit the certificate, be sure to replace the content -matching with your setup though. -to ec2-service.properties - - - -Save the cert into Cloud's EC2 Service: -

-

- - - - - - - - - -

- -

- - - diff --git a/awsapi/docs/AmazonEC2/EC2-implementation-guide.html b/awsapi/docs/AmazonEC2/EC2-implementation-guide.html deleted file mode 100644 index 737c669dcbd..00000000000 --- a/awsapi/docs/AmazonEC2/EC2-implementation-guide.html +++ /dev/null @@ -1,164 +0,0 @@ - - - -Cloud.com's EC2 API Implementation Guide - - -

Cloud.com's EC2 API Implementation Guide

-3/24/2011 -

Table of Contents

- -

-

1. Configuration Parameters

-Several configuration parameters are required to make Cloud.com's EC2 service work properly. -The following parameters are defined in the file:
<install directory>"/apache-tomcat-6.0.18/conf/ec2-service.properties": -
-managementServer=192.168.154.36
-cloudAPIPort=8080
-WSDLVersion=2010-08-31
-keystore=xes.keystore
-keystorePass=apache
-dbName=cloudsbridge
-dbUser=root
-dbPassword=
-pollInterval1=100
-pollInterval2=100
-pollInterval3=100
-pollInterval4=1000
-pollInterval5=100
-pollInterval6=100
-
-managementServer - FQDN or IP address of a Cloud.com management server. This is the address that -the EC2 service makes Cloud.com REST API calls against.
-cloudAPIPort - The TCP port that the CloudStack, User API is running on. If this property is not defined, -then no port is used by the EC2 service when it queries the CloudStack.
-WSDLVersion - The string that defines the WSDL used by the SOAP API which the REST API also implements. -This string is compared to the "Version=" parameter on each and every authorized REST request.
-keystore - The file name of the keystore used by EC2 which must be placed at the directory: -"../apache-tomcat-6.0.18/webapps/bridge/WEB-INF/classes"
-keystorePass - The password to the EC2 keystore specified by the "keystore" parameter.
-dbName - The MySql database name holding the EC2 service's required tables.
-dbUser= - The user name used to access the "dbName" MySql database.
-dbPassword - The password (if any) the "dbUser" needs to access the EC2 MySql database.
-pollInterval1 - Time in milliseconds between asynchronous job completion polling for the following Cloud.com -API call: createTemplate. Default value is 100.
-pollInterval2 - Time in milliseconds between asynchronous job completion polling for the following Cloud.com -API call: deployVirtualMachine. Default value is 100.
-pollInterval3 - Time in milliseconds between asynchronous job completion polling for the following Cloud.com -API call: createVolume. Default value is 100.
-pollInterval4 - Time in milliseconds between asynchronous job completion polling for the following Cloud.com -API call: createSnapshot. Default value is 1000.
-pollInterval5 - Time in milliseconds between asynchronous job completion polling for the following Cloud.com -API calls: deleteSnapshot, deleteTemplate, deleteVolume, attachVolume, detachVolume, disassociateIpAddress, enableStaticNat, disableStaticNat. Default value is 100.
-pollInterval6 - Time in milliseconds between asynchronous job completion polling for the following Cloud.com -API calls: startVirtualMachine, destroyVirtualMachine, stopVirtualMachine. Default value is 100.
-

-
-The following REST calls are used to configure a mapping between Amazon's instance types and CloudStack service offerings: -

-http://<fqdn-or-ip>:<port>/bridge/rest/AmazonEC2?Action=SetOfferMapping&amazonoffer=m1.large&cloudoffer=1
-

-The 'amazonoffer' parameter defines the standard Amazon instance types while the 'cloudoffer' parameter defines its associated -CloudStack service offering identifer. The result of this REST call is to save the defined relationship. A second call with the -same value for amazonoffer but with a different cloudoffer value will overwrite a previously saved setting. -
-SetOfferMapping is an authenticated REST call using the same authentication scheme as all other EC2 REST calls. This means that the following standard EC2 REST paramters must also be part of the request: Signature, SignatureMethod, Version, SignatureVersion, and Expires. -A HTTP 200 result code is returned on success and a 404 on failure. -

-http://<fqdn-or-ip>:<port>/bridge/rest/AmazonEC2?Action=DeleteOfferMapping&amazonoffer=m1.large
-

-The result of this REST call is to delete any relationship previously defined by a call to the SetOfferMapping call for the -value passed in the 'amazonoffer' parameter.
-DeleteOfferMapping is an authenticated REST call using the same authentication scheme as all other EC2 REST calls. This means that the following standard EC2 REST paramters must also be part of the request: Signature, SignatureMethod, Version, SignatureVersion, and Expires. -A HTTP 200 result code is returned on success and a 404 on failure. -

-Examples of other Amazon instance types are: -{ "m1.small", "m1.large", "m1.xlarge", "c1.medium", "c1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge" }.
-Service offering IDs can be obtained from the following Cloud.com API calls: listServiceOfferings. -Cloud.com's service offerings are configurable and thus can be different per installation, and they -can also be viewed from the Cloud.com's Admin UI. -

-

2. Required 3rd Party Software

-Cloud.com's EC2 service has been built and tested on the following set of 3rd party software: -
-MySql
-apache-tomcat 6.0.18
-axis2 1.5.1
-rampart 1.5 (installed into axis2 for WS-Security)
-used for testing: ec2-api-tools-1.3-53907
-
-

-

3. Maintenance

-As a result of the SetCertificate REST call [1], X509 Certificates used for SOAP authentication are -stored in the following keystore: -
-<install directory>/apache-tomcat-6.0.18/webapps/bridge/WEB-INF/classes/xes.keystore
-
-The keytool [2] command line tool can be used to delete certificates no longer in use. -

-As a result of the SetUserKeys REST call [1], entries are inserted into -the "usercredentials" table of the "cloudbridge" MySql database. -The MySql command line client can be used to delete usercredentials entries no longer in use. -

-

4. Installation Instructions

-

-On the very first install an EC2/S3 MySql database is created by running the following -scripts in the given order: cloudsbridge_db.sql, cloudsbridge_schema.sql, cloudbridge_index.sql -

-After a successful installation the following directory and file structure should exist: -

-<install directory>
-   apache-tomcat-6.0.18
-      conf
-        ec2-service.properties  (EC2 service's configuration parameters)
-        server.xml		
-      lib
-        <many axis2 jar files>	  
-      webapps
-        bridge
-          WEB-INF
-            classes
-               crypto.properties
-               xes.keystore  (holds X509 certificates for SOAP authentication)
-            modules
-               cloud-auth-ec2.mar
-               rampart-1.5.mar 
-               rahas-1.5.mar   
-               addressing-1.5.1.mar
-            services
-               cloud-ec2.aar  (the Axis2 EC2 service)
-
-The "../modules/cloud-auth-ec2.mar" module performs a mapping from an X509 certificate appearing in a SOAP -request (since its signed via WS-Security) to a matching user's Cloud.com API access and secret keys. This association -is first created via the SetUserKeys and SetCertificate REST calls [1]. -

-

5. References

-
    -
  1. Cloud.com's EC2 API User's Guide, 7/15/2010
  2. -
  3. keytool - Key and Certificate Management Tool
  4. -
- - diff --git a/awsapi/docs/AmazonEC2/EC2-local-deploy-using-ant.html b/awsapi/docs/AmazonEC2/EC2-local-deploy-using-ant.html deleted file mode 100644 index 07ba3aa4222..00000000000 --- a/awsapi/docs/AmazonEC2/EC2-local-deploy-using-ant.html +++ /dev/null @@ -1,92 +0,0 @@ - - - -Cloud.com's EC2 local deployment Guide - - -

Cloud.com's EC2 local deployment Guide

-8/30/2010 -8/25/2011 (updated) -

Table of Contents

- -

-

1. Required 3rd Party Software

-1) Following software has to be installed in order to deploy and run cloud-bridge tool: -
-apache-tomcat-6.0.32
-axis2 1.5.1 (http://apache.imghat.com//ws/axis2/1_5/axis2-1.5-bin.zip)
-ant
-java
-mysql
-
-2) Set following environment variables: -
-ANT_HOME
-CATALINA_HOME
-export ANT_HOME
-export JAVA_HOME
-
-3) Go to CATALINA_HOME directory and excute “mkdir temp” (this directory is used for storing temporary axis files) -

-

2. Clone repository

-Clone cloud-bridge repository: -
-git clone git@github.com:alena11081/cloud-bridge.git
-
-

-

3. Build, deploy and run cloud-bridge with ant

-Deployment procedure using ant (build.xml and build-cloud-bridge.xml are config files), execute from cloned cloud-bridge directory:. -
- 
-* ant clean - removes dist directory
-* ant clean-tomcat - cleans up $CATALINA_HOME/webapps/bridge directory
-* ant build-cloud-bridge compiles and places the resulting jars into cloud-bridge/dist:
-
-ls dist/
-cloud-auth-ec2.mar  cloud-auth-s3.mar  cloud-bridge.jar  cloud-ec2.aar  cloud-s3.aar
-
-
-* deploy-axis - copies and unwars cloud-bridge/lib/axis2-webapp-1.5.1.war to $CATALINA_HOME/webapps/bridge directory
-
-ant deploy-cloud-bridge copies files to $CATALINA_HOME/webapps/bridge tomcat directory:
-
-
-- copy cloud-bridge/dist/cloud-ec2.aar and  cloud-s3.aar to $CATALINA_HOME/webapps/bridge/WEB-INF/services
-- copy cloud-bridge/dist/cloud-auth-ec2.mar and cloud-auth-s3.mar to $CATALINA_HOME/webapps/bridge/WEB-INF/modules
-- copy all .mar files from cloud-bridge/modules to $CATALINA_HOME/webapps/bridge/WEB-INF/modules
-- copy cloud-bridge/dist/cloud-bridge.jar to $CATALINA_HOME/webapps/bridge/WEB-INF/lib
-- copy all .jar files from cloud-bridge/lib directory to $CATALINA_HOME/webapps/bridge/WEB-INF/lib
-- copy all .jar files from cloud-bridge/rampartlib directory to $CATALINA_HOME/webapps/bridge/WEB-INF/lib 
-- copy all files from cloud-bridge/conf directory to $CATALINA_HOME/webapps/bridge/WEB-INF/conf
-- copy cloud-bridge/resource/Axis2/axis2.xml to $CATALINA_HOME/webapps/bridge/WEB-INF/conf
-- copy cloud-bridge/web/web.xml to $CATALINA_HOME/webapps/bridge/WEB-INF
-- copy cloud-bridge/resource/AmazonEC2/crypto.properties and xes.keystore to $CATALINA_HOME/webapps/bridge/WEB-INF/classes/
-- remove $CATALINA_HOME/webapps/bridge/WEB-INF/lib/dom4j-1.6.1.jar
-
-
-ant deploydb - execute cloud-bridge/db/mysql/deploy-db-bridge.sh (for Unix). If it's a windows deployment, execute db/mysql/init_db.bat script
-5) Configure ec2-service.properties (see parameters descriptions in resource/AmazonEC2/docs/EC2-implementation-guide.html).
-6) To run application execute "./catalina.sh run" from $CATALINA_HOME/bin directory.
-
-
diff --git a/awsapi/docs/AmazonEC2/EC2-users-guide.html b/awsapi/docs/AmazonEC2/EC2-users-guide.html
deleted file mode 100644
index a51923cc89d..00000000000
--- a/awsapi/docs/AmazonEC2/EC2-users-guide.html
+++ /dev/null
@@ -1,275 +0,0 @@
-
-
-
-Cloud.com's EC2 API User's Guide
-
-
-

Cloud.com's EC2 API User's Guide

-4/17/2010 -

Table of Contents

- -


-

Part 1. Cloud.com's Specific Implementation Details

-

1. User Registration

-To access Cloud.com's EC2 service via REST follow the instructions in Section 1.1. -To access Cloud.com's EC2 service via SOAP follow instructions in both Section 1.1 and 1.2 below. -

-

1.1 Setting Cloud.com API Keys

-The EC2 service needs to be given the user's Cloud.com API access and secret keys [2] so that it -can make Cloud.com API calls on the user's behalf. This is done by the following REST command. - -
-http://<fqdn-or-ip>:<port>/bridge/rest/AmazonEC2?Action=SetUserKeys&accesskey=<key>&secretkey=<key>
-
-SetUserKeys is an unauthorized REST call.
-A HTTP 200 result code is returned on success and a 401 on failure. -

-

1.2 Setting a User's X509 Certificate

-EC2 uses WS-Security [4] for authentication on SOAP access. WS-Security signs the entire SOAP request -using a public/private key pair. The user of Cloud.com's EC2 service must -generate a public/private key pair with the public key defined in an X509 -certificate. The private key is used by a SOAP client in generating -the WS-Security signature of a SOAP request. The matching public key is stored on -a server and is used to verify the signature on each request. -

-The following REST command must be used by a Cloud.com's EC2 service user to -load their certificate into the service. No access via the SOAP API is -possible until this step is performed. Also for this REST command to be -successful the instructions in Section 1.1 must be performed first. - -

-http://<fqdn-or-ip>:<port>/bridge/rest/AmazonEC2?Action=SetCertificate&AWSAccessKeyId=<Cloud.com API AccessKey>&cert=<pem encoded cert>
-
-SetCertificate is an authenticated REST call using the same authentication scheme as all other EC2 REST calls. -This means that the following standard EC2 REST paramters must also be part of the request: Signature, SignatureMethod, Version, -SignatureVersion, and Expires [3].
-A HTTP 200 result code is returned on success and a 404 on failure. -

-An example of a PEM encoded X509 Certificate is [5]: -

------BEGIN CERTIFICATE-----
-MIICdzCCAeCgAwIBAgIGAPCRHu3UMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNVBAYT
-AlVTMRMwEQYDVQQKEwpBbWF6b24uY29tMQwwCgYDVQQLEwNBV1MxITAfBgNVBAMT
-GEFXUyBMaW1pdGVkLUFzc3VyYW5jZSBDQTAeFw0xMDA2MjMxODE4MTZaFw0xMTA2
-MjMxODE4MTZaMFIxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpBbWF6b24uY29tMRcw
-FQYDVQQLEw5BV1MtRGV2ZWxvcGVyczEVMBMGA1UEAxMMZWZieDQ0eXF1d3E2MIGf
-MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw+RO1QV7t5EbluyAAD11SoZ4ats5t
-DBSta/QB3G9T0y3p2gURrYMDYVJ1BZmyel/DuMANx6UG6Vw+0o0SXOS3mH8Yu/lO
-OOH9WxWiXulGMIrpPCiUpnWMrWhIlHu8mqLLhBx+5k4I92plMfH97BySunbv9zaf
-ZRKXX3cXIYbUMwIDAQABo1cwVTAOBgNVHQ8BAf8EBAMCBaAwFgYDVR0lAQH/BAww
-CgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUCzKwCQvocPYFki/9
-NORZFTsjcZ8wDQYJKoZIhvcNAQEFBQADgYEAXmIe6+XsNHYIiLGQO6dh8nvHHzDw
-3sltNa7z6BSdNr7WDxpJg9oFUcddQVca1LZsjsqx6dIc1WxQUjPE9oOfSYqQZuMD
-/GOpWyXMb/oJ2MLI1Vp1ABKhHoHUJmPOrIou4UbCifMeD7MFZkezkKDqqH3jQMjA
-4YDNkSWLnJ9xba8=
------END CERTIFICATE-----
-
-

-To remove a previously loaded certificate the user can simply execute -the following REST command. -

-http://<fqdn-or-ip>:<port>/bridge/rest/AmazonEC2?Action=DeleteCertificate&AWSAccessKeyId=<Cloud.com API AccessKey>
-where the same value for the 'AWSAccessKeyId' parameter as was used in a previous call to SetCertificate.
-
-DeleteCertificate is an authenticated REST call using the same authentication scheme (and having all the same -required parameters) as all other EC2 REST calls.
-A HTTP 200 result code is returned on success and a 404 on failure. -

-

2. Endpoints

-For SOAP access the endpoint is: -
http://<fqdn-or-ip>:<port>/bridge/services/AmazonEC2
-For REST access the endpoint is: -
http://<fqdn-or-ip>:<port>/bridge/rest/AmazonEC2
-

- -

3. Differences between Amazon's and Cloud.com's EC2 Implementations

-EC2's RegisterImage Function -

-This function maps to the Cloud.com's API "registerTemplate" function [2]. However the registerTemplate function -requires the following additional parameters that are not present in the RegisterImage function: -

-format - the format for the template. Possible values include QCOW2, RAW, and VHD.
-osTypeId - the ID of the OS Type that best represents the OS of this template.
-zoneId - the ID of the zone the template is to be hosted on.
-
-These parameters must be provided for a successful registerTemplate call and thus a RegsiterImage call. -To accomidate these values we have redefined the "architecture" parameter defined for RegisterImage. -The Amazon defined valid values are: "i386 | x86_64" and it is of type xsd:string. Neither of these -defined values has any meaning in the context of the Cloud.com API. - -The new definition of the architecture field is a three part value of the form: -"<format>:<zoneName>:<osTypeName>", where ":" is the field delimitor. A valid example -would be: "VHD:ZONE1:Centos 4.5". Cloud.com's EC2 code translates the "zoneName" value into a valid zoneId, -and the "osTypeName" value into a matching osTypeId. In addition, whereas the architecture field -is optional in Amazon's definition of RegisterImage, it is required in Cloud.com's modified version. -

-Another difference for the RegisterImage function concerns the use of the "imageLocation" parameter. -As defined by Amazon [3]: -

-imageLocation - a full path to your AMI manifest in Amazon S3 storage.
-
-As defined for Cloud.com's EC2 implementation: -
-imageLocation - is a URL of where the template is hosted. Possible URL include http:// and https://
-
-

-EC2's DescribeInstances Function -

-Only the following list of filters are currently supported: -

-availability-zone
-hypervisor
-image-id
-instance-id
-instance-type
-instance-state-code
-instance-state-name
-ip-address	
-owner-id
-root-device-name	
-
-

-EC2's DescribeVolumes Function -

-Only the following list of filters are currently supported: -

-attachment.attach-time
-attachment.device
-attachment.instance-id
-availability-zone
-create-time
-size
-snapshot-id
-status
-volume-id	
-
-

-EC2's DescribeSnapshots Function -

-Only the following list of filters are currently supported: -

-owner-alias
-owner-id (here its the CloudStack API key)
-snapshot-id
-start-time
-status
-volume-id
-volume-size
-
-

-

-EC2's DescribeSecurityGroups Function -

-Only the following list of filters are currently supported: -

-description
-group-id
-group-name
-ip-permission.cidr
-ip-permission.from-port
-ip-permission.to-port
-ip-permission.protocol
-owner-id
-
-

-

4. Miscellaneous

-The EC2 service provides a Cloud.com extension to obtain the release version of the EC2 software. - -
-http://<fqdn-or-ip>:<port>/bridge/rest/AmazonEC2?Action=CloudEC2Version
-
-CloudEC2Version is an unauthorized REST call.
-An example of a valid response from this function is: -
-<CloudEC2Version>1.01</CloudEC2Version>
-
-


-

Part 2. Generic EC2 Details

-

List of EC2 Functions Implemented

-Refer to the Amazon EC2 documentation [3] for a description of each function. -Also see Part1, section 3 above, for differences between Amazon's and Cloud.com's EC2 implementations. -
-AllocateAddress
-AssociateAddress
-AttachVolume 
-AuthorizeSecurityGroupIngress
-CreateImage 
-CreateSecurityGroup
-CreateSnapshot
-CreateVolume
-DeleteSecurityGroup
-DeleteSnapshot  
-DeleteVolume   
-DeregisterImage   
-DescribeAvailabilityZones  
-DescribeImageAttribute   
-DescribeImages   
-DescribeInstanceAttribute  
-DescribeInstances  
-DescribeSecurityGroups
-DescribeSnapshots   
-DescribeVolumes  
-DetachVolume
-DisassociateAddress  
-ModifyImageAttribute  
-RebootInstances   
-ReleaseAddress
-RegisterImage  
-RevokeSecurityGroupIngress
-ResetImageAttribute   
-RunInstances  
-StartInstances  
-StopInstances  
-TerminateInstances  
-
-

-

Supported WSDL Version

-http://ec2.amazonaws.com/doc/2010-08-31/
-Amazon EC2 Command Line Tool used for testing was version 1.3-57419. -

-
-

References

-
    -
  1. Public-key cryptograph
  2. -
  3. Cloud.com's Developer API
  4. -
  5. Amazon's EC2 API
  6. -
  7. WS-Security
  8. -
  9. X.509 Certificates
  10. -
- - diff --git a/awsapi/docs/AmazonEC2/wsdl2java-command-line.txt b/awsapi/docs/AmazonEC2/wsdl2java-command-line.txt deleted file mode 100644 index c1b68538e9d..00000000000 --- a/awsapi/docs/AmazonEC2/wsdl2java-command-line.txt +++ /dev/null @@ -1,21 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. - ------------------------------------------------------------ - -To generate the Java AXIS2 classes from the Amazon EC2 wsdl use the following command line: -C:\axis2-1.5.1\bin>wsdl2java.bat -ss -sd -ssi -g -p com.amazon.ec2 -ns2p "http://ec2.amazonaws.com/doc/2010-08-31/"=com.amazon.ec2 -uri ec2.wsdl diff --git a/awsapi/docs/AmazonS3/S3-users-guide.html b/awsapi/docs/AmazonS3/S3-users-guide.html deleted file mode 100644 index adadd8b97fd..00000000000 --- a/awsapi/docs/AmazonS3/S3-users-guide.html +++ /dev/null @@ -1,120 +0,0 @@ - - - -Cloud.com's S3 API User's Guide - - -

Cloud.com's S3 API User's Guide

-3/4/2011 -

Table of Contents

- -


-

Part 1. Cloud.com's Specific Implementation Details

-

User Registration

-The S3 service uses the user's Cloud.com API access and secret keys [1] to implement both -the REST and SOAP authentication algorithms. This is done by re-using an EC2 provided REST command. Once -this URL is invoked the user has registered for both the S3 service and the EC2 REST service. -
-http://<fqdn-or-ip>:<port>/bridge/rest/AmazonS3?Action=SetUserKeys&accesskey=<key>&secretkey=<key>
-
-SetUserKeys is an unauthorized REST call.
-A HTTP 200 result code is returned on success and a 401 on failure. -

-

-

Endpoints

-For SOAP access the endpoint is: -
http://<fqdn-or-ip>:<port>/bridge/services/AmazonS3
- -For the SOAP PutObject function with a DIME attachment [3]: -
http://<fqdn-or-ip>:<port>/bridge/dime/AmazonS3
- -For REST access the endpoint is: -
http://<fqdn-or-ip>:<port>/bridge/rest/AmazonS3
-

- -

Part 2. Generic S3 Details

-

List of S3 Functions Implemented

-Refer to the Amazon S3 documentation [2] for a description of each function. -Also see Part1, section 3 above, for a list of unsupported S3 features. -
-REST calls:
-GET Service
-DELETE Bucket
-GET Bucket
-GET Bucket acl
-GET Bucket versioning
-PUT Bucket
-PUT Bucket acl
-PUT Bucket versioning
-List Multipart Uploads
-DELETE Object
-GET Object
-GET Object acl
-HEAD Object
-POST Object
-PUT Object
-PUT Object (Copy)
-Initiate Multipart Upload
-Upload Part
-Complete Multipart Upload
-Abort Multipart Upload
-List Parts
-
-SOAP calls:
-ListAllMyBuckets
-CreateBucket
-DeleteBucket
-ListBucket
-GetBucketAccessControlPolicy
-SetBucketAccessControlPolicy
-PutObjectInline
-PutObject
-CopyObject
-GetObject
-GetObjectExtended
-DeleteObject
-GetObjectAccessControlPolicy
-SetObjectAccessControlPolicy
-
-

-

Supported WSDL Version

-http://s3.amazonaws.com/doc/2006-03-01/
-

-
-

References

-
    -
  1. Cloud.com's Developer API
  2. -
  3. Amazon's S3 API
  4. -
  5. DIME
  6. -
- - diff --git a/awsapi/docs/AmazonS3/notes.txt b/awsapi/docs/AmazonS3/notes.txt deleted file mode 100644 index e9a796880c9..00000000000 --- a/awsapi/docs/AmazonS3/notes.txt +++ /dev/null @@ -1,29 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. - ------------------------------------------------------------ - -Example of headers for a rest call of copyObject - -Authorization: AWS Mark:djdjdjdjdjdjdjdj\n -Host: Henry2.s3.amazonaws.com\n -x-amz-copy-source: /Henry1/test1\n -x-amz-metadata-directive: REPLACE\n -x-amz-meta-hight: 55 feet\n -x-amz-meta-width: 13 yards\n -x-amz-meta-weight: 4 tons\n -x-amz-acl: public-read\n diff --git a/awsapi/docs/AmazonS3/wsdl2java-command-line.txt b/awsapi/docs/AmazonS3/wsdl2java-command-line.txt deleted file mode 100644 index d22b8529502..00000000000 --- a/awsapi/docs/AmazonS3/wsdl2java-command-line.txt +++ /dev/null @@ -1,66 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. - ------------------------------------------------------------ - -To generate the Java AXIS2 classes from the Amazon EC2 wsdl use the following command line, assuming source definitions in the local directory: -$ wsdl2java.sh -ss -sd -ssi -g -p com.amazon.s3 -ns2p "http://s3.amazonaws.com/doc/2006-03-01/"=com.amazon.s3 -uri cloud-AmazonS3.wsdl - -This runs the wsdl2java code generation tool to produce stubs with asynchronous invocation methods, such as those useful for REST using the com.amazon.s3 package. - -This creates the following java source files in the src/com/amazon/s3 subdirectory … - -AccessControlList.java ListAllMyBucketsResponse.java -AccessControlPolicy.java ListAllMyBucketsResult.java -AmazonCustomerByEmail.java ListBucket.java -AmazonS3CallbackHandler.java ListBucketResponse.java -AmazonS3MessageReceiverInOut.java ListBucketResult.java -AmazonS3Skeleton.java ListEntry.java -AmazonS3SkeletonInterface.java ListVersionsResponse.java -AmazonS3Stub.java ListVersionsResult.java -BucketLoggingStatus.java ListVersionsResultChoice_type0.java -CanonicalUser.java LocationConstraint.java -CopyObject.java LoggingSettings.java -CopyObjectResponse.java MetadataDirective.java -CopyObjectResult.java MetadataEntry.java -CreateBucket.java MfaDeleteStatus.java -CreateBucketConfiguration.java NotificationConfiguration.java -CreateBucketResponse.java Payer.java -CreateBucketResult.java Permission.java -DeleteBucket.java PostResponse.java -DeleteBucketResponse.java PrefixEntry.java -DeleteMarkerEntry.java PutObject.java -DeleteObject.java PutObjectInline.java -DeleteObjectResponse.java PutObjectInlineResponse.java -ExtensionMapper.java PutObjectResponse.java -GetBucketAccessControlPolicy.java PutObjectResult.java -GetBucketAccessControlPolicyResponse.java RequestPaymentConfiguration.java -GetBucketLoggingStatus.java Result.java -GetBucketLoggingStatusResponse.java SetBucketAccessControlPolicy.java -GetObject.java SetBucketAccessControlPolicyResponse.java -GetObjectAccessControlPolicy.java SetBucketLoggingStatus.java -GetObjectAccessControlPolicyResponse.java SetBucketLoggingStatusResponse.java -GetObjectExtended.java SetObjectAccessControlPolicy.java -GetObjectExtendedResponse.java SetObjectAccessControlPolicyResponse.java -GetObjectResponse.java Status.java -GetObjectResult.java StorageClass.java -Grant.java TopicConfiguration.java -Grantee.java User.java -Group.java VersionEntry.java -ListAllMyBuckets.java VersioningConfiguration.java -ListAllMyBucketsEntry.java VersioningStatus.java -ListAllMyBucketsList.java diff --git a/awsapi/pom.xml b/awsapi/pom.xml index a583384b126..2a492d94026 100644 --- a/awsapi/pom.xml +++ b/awsapi/pom.xml @@ -16,16 +16,15 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-awsapi - 4.0.0-SNAPSHOT Apache CloudStack AWS API Bridge + war org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT @@ -38,6 +37,11 @@ axis2 ${cs.axis2.version} + + org.apache.axis2 + axis2-adb + ${cs.axis2.version} + org.apache.axis2 axis2-webapp @@ -49,6 +53,11 @@ axiom-api ${cs.axiom.version} + + org.apache.ws.commons.axiom + axiom-impl + ${cs.axiom.version} + log4j log4j @@ -58,6 +67,16 @@ org.apache.neethi neethi ${cs.neethi.version} + + + org.apache.ws.commons.axiom + axiom-api + + + org.apache.ws.commons.axiom + axiom-impl + + com.google.code.gson @@ -93,61 +112,87 @@ org.apache.rampart rahas - 1.5 + ${cs.rampart.version} mar bouncycastle bcprov-jdk14 + + org.apache.xalan + xalan + org.apache.rampart rampart - 1.5 + ${cs.rampart.version} mar bouncycastle bcprov-jdk14 + + org.apache.xalan + xalan + org.apache.rampart rampart-core - 1.5 + ${cs.rampart.version} runtime + + + org.apache.xalan + xalan + + org.apache.rampart rampart-policy - 1.5 + ${cs.rampart.version} runtime + + + org.apache.xalan + xalan + + org.apache.rampart rampart-trust - 1.5 + ${cs.rampart.version} runtime + + + org.apache.xalan + xalan + + org.slf4j slf4j-jdk14 - 1.5.11 + 1.6.1 runtime org.slf4j slf4j-api - 1.5.11 + 1.6.1 runtime org.apache.ws.security wss4j - 1.5.8 + 1.6.1 runtime @@ -192,6 +237,27 @@ 1.45 runtime + + mysql + mysql-connector-java + 5.1.21 + runtime + + + org.antlr + antlr-runtime + 3.4 + + + dom4j + dom4j + 1.6.1 + + + javassist + javassist + 3.9.0.GA + install @@ -203,6 +269,9 @@ **/*.java + + ../utils/conf/ + @@ -254,6 +323,22 @@ + + org.mortbay.jetty + maven-jetty-plugin + 6.1.26 + + + + 7080 + 60000 + + + /awsapi + ${basedir}/web/web.xml + ${basedir}/target/cloud-awsapi-${project.version} + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.apache.maven.plugins + + + maven-antrun-plugin + + [1.7,) + + run + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + [2.0,) + + copy-dependencies + + + + + + + + + + + + diff --git a/awsapi/resource/AmazonEC2/crypto.properties b/awsapi/resource/AmazonEC2/crypto.properties index f55bea830b7..77a9eedd317 100644 --- a/awsapi/resource/AmazonEC2/crypto.properties +++ b/awsapi/resource/AmazonEC2/crypto.properties @@ -1,24 +1,24 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - - -org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin -org.apache.ws.security.crypto.merlin.keystore.type=jks -org.apache.ws.security.crypto.merlin.keystore.password=apache -org.apache.ws.security.crypto.merlin.keystore.alias=xeskey -org.apache.ws.security.crypto.merlin.alias.password=apache -org.apache.ws.security.crypto.merlin.file=xes.keystore +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + + +org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin +org.apache.ws.security.crypto.merlin.keystore.type=jks +org.apache.ws.security.crypto.merlin.keystore.password=apache +org.apache.ws.security.crypto.merlin.keystore.alias=xeskey +org.apache.ws.security.crypto.merlin.alias.password=apache +org.apache.ws.security.crypto.merlin.file=xes.keystore diff --git a/awsapi/resource/Axis2/axis2.xml b/awsapi/resource/Axis2/axis2.xml index f94540008b7..f5e9308be1a 100644 --- a/awsapi/resource/Axis2/axis2.xml +++ b/awsapi/resource/Axis2/axis2.xml @@ -1,561 +1,561 @@ - - - - - - - true - false - false - false - - - - - - - - - - - - - - - - 30000 - - - - false - - - - - - false - - admin - axis2 - - - - - - - - - - - - - - - - - - - - - - - - - false - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8080 - - - - - - - - - - - - - > - - - - - - - - - - - - - - HTTP/1.1 - chunked - - - - - - - HTTP/1.1 - chunked - - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - - - - multicast - - - apache.axis2.domain - - - apache.axis2.application.domain - - - true - - - 10 - - - 228.0.0.4 - - - 45564 - - - 500 - - - 3000 - - - 127.0.0.1 - - - 127.0.0.1 - - - 4000 - - - true - - - true - - - - - 127.0.0.1 - 4000 - - - 127.0.0.1 - 4001 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + true + false + false + false + + + + + + + + + + + + + + + + 30000 + + + + false + + + + + + false + + admin + axis2 + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 8080 + + + + + + + + + + + + + > + + + + + + + + + + + + + + HTTP/1.1 + chunked + + + + + + + HTTP/1.1 + chunked + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + + + + multicast + + + apache.axis2.domain + + + apache.axis2.application.domain + + + true + + + 10 + + + 228.0.0.4 + + + 45564 + + + 500 + + + 3000 + + + 127.0.0.1 + + + 127.0.0.1 + + + 4000 + + + true + + + true + + + + + 127.0.0.1 + 4000 + + + 127.0.0.1 + 4001 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/awsapi/scripts/run.bat b/awsapi/scripts/run.bat index 437a37f8b83..453e74f8b31 100644 --- a/awsapi/scripts/run.bat +++ b/awsapi/scripts/run.bat @@ -1,18 +1,18 @@ -rem Licensed to the Apache Software Foundation (ASF) under one -rem or more contributor license agreements. See the NOTICE file -rem distributed with this work for additional information -rem regarding copyright ownership. The ASF licenses this file -rem to you under the Apache License, Version 2.0 (the -rem "License"); you may not use this file except in compliance -rem with the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, -rem software distributed under the License is distributed on an -rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -rem KIND, either express or implied. See the License for the -rem specific language governing permissions and limitations -rem under the License. - -java -cp cloud-tool.jar;./lib/XmlSchema-1.4.3.jar;./lib/antlr-2.7.6.jar;./lib/apache-log4j-extras-1.0.jar;./lib/axiom-api-1.2.8.jar;./lib/axiom-impl-1.2.8.jar;./lib/axis2-adb-1.5.1.jar;./lib/axis2-ant-plugin-1.5.1.jar;./lib/axis2-jaxbri-1.5.1.jar;./lib/axis2-jaxws-1.5.1.jar;./lib/axis2-jibx-1.5.1.jar;./lib/axis2-json-1.5.1.jar;./lib/axis2-kernel-1.5.1.jar;./lib/axis2-transport-http-1.5.1.jar;./lib/axis2-transport-local-1.5.1.jar;./lib/commons-codec-1.3.jar;./lib/commons-collections-3.1.jar;./lib/commons-fileupload-1.2.jar;./lib/commons-httpclient-3.1.jar;./lib/commons-io-1.4.jar;./lib/commons-logging-1.1.1.jar;./lib/dom4j-1.6.1.jar;./lib/hibernate3.jar;./lib/httpcore-4.0.jar;./lib/javassist-3.9.0.GA.jar;./lib/jta-1.1.jar;./lib/junit-4.8.1.jar;./lib/log4j-1.2.15.jar;./lib/mail-1.4.jar;./lib/mysql-connector-java-5.1.7-bin.jar;./lib/neethi-2.0.4.jar;./lib/servlet-api.jar;./lib/slf4j-api-1.5.11.jar;./lib/slf4j-simple-1.5.11.jar;./lib/wsdl4j-1.6.2.jar com.cloud.gate.tool.CloudS3CmdTool %* +rem Licensed to the Apache Software Foundation (ASF) under one +rem or more contributor license agreements. See the NOTICE file +rem distributed with this work for additional information +rem regarding copyright ownership. The ASF licenses this file +rem to you under the Apache License, Version 2.0 (the +rem "License"); you may not use this file except in compliance +rem with the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, +rem software distributed under the License is distributed on an +rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +rem KIND, either express or implied. See the License for the +rem specific language governing permissions and limitations +rem under the License. + +java -cp cloud-tool.jar;./lib/XmlSchema-1.4.3.jar;./lib/antlr-2.7.6.jar;./lib/apache-log4j-extras-1.0.jar;./lib/axiom-api-1.2.8.jar;./lib/axiom-impl-1.2.8.jar;./lib/axis2-adb-1.5.1.jar;./lib/axis2-ant-plugin-1.5.1.jar;./lib/axis2-jaxbri-1.5.1.jar;./lib/axis2-jaxws-1.5.1.jar;./lib/axis2-jibx-1.5.1.jar;./lib/axis2-json-1.5.1.jar;./lib/axis2-kernel-1.5.1.jar;./lib/axis2-transport-http-1.5.1.jar;./lib/axis2-transport-local-1.5.1.jar;./lib/commons-codec-1.3.jar;./lib/commons-collections-3.1.jar;./lib/commons-fileupload-1.2.jar;./lib/commons-httpclient-3.1.jar;./lib/commons-io-1.4.jar;./lib/commons-logging-1.1.1.jar;./lib/dom4j-1.6.1.jar;./lib/hibernate3.jar;./lib/httpcore-4.0.jar;./lib/javassist-3.9.0.GA.jar;./lib/jta-1.1.jar;./lib/junit-4.8.1.jar;./lib/log4j-1.2.15.jar;./lib/mail-1.4.jar;./lib/mysql-connector-java-5.1.7-bin.jar;./lib/neethi-2.0.4.jar;./lib/servlet-api.jar;./lib/slf4j-api-1.5.11.jar;./lib/slf4j-simple-1.5.11.jar;./lib/wsdl4j-1.6.2.jar com.cloud.gate.tool.CloudS3CmdTool %* diff --git a/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java index 4a981f83336..c7b40501f79 100644 --- a/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java +++ b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java @@ -16,21 +16,6 @@ // under the License. /* Took the basic code from Axis 1.2 and modified to fit into the cloud code base */ -/* - * Copyright 2001-2004 The Apache Software Foundation. - * - * 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 com.cloud.bridge.io; import java.io.IOException; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java index c49f612bb43..63330428159 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java @@ -52,7 +52,12 @@ public class CloudStackConfigurationDaoImpl extends GenericDaoBase sc = NameSearch.create(); sc.setParameters("name", name); - return findOneBy(sc).getValue(); + CloudStackConfigurationVO configItem = findOneBy(sc); + if (configItem == null) { + s_logger.warn("No configuration item found with name " + name); + return null; + } + return configItem.getValue(); }finally { } diff --git a/awsapi/src/com/cloud/bridge/service/EC2MainServlet.java b/awsapi/src/com/cloud/bridge/service/EC2MainServlet.java index dceb665d1f2..60da11a2f1a 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2MainServlet.java +++ b/awsapi/src/com/cloud/bridge/service/EC2MainServlet.java @@ -65,7 +65,7 @@ public class EC2MainServlet extends HttpServlet{ } logger.info("Value of EC2 API Flag ::" + value); }catch(Exception e){ - throw new ServletException("Error initializing awsapi: " + e.getMessage()); + throw new ServletException("Error initializing awsapi: " + e.getMessage(), e); } } diff --git a/awsapi/test/html/certSubmit.html b/awsapi/test/html/certSubmit.html index 00cb5b7f882..edbfa68da47 100644 --- a/awsapi/test/html/certSubmit.html +++ b/awsapi/test/html/certSubmit.html @@ -1,37 +1,37 @@ - - - -Save the cert into Cloud's EC2 Service: -

-

- - - - - - - - - -

- -

- - + + + +Save the cert into Cloud's EC2 Service: +

+

+ + + + + + + + + +

+ +

+ + diff --git a/awsapi/test/html/testRestURL.txt b/awsapi/test/html/testRestURL.txt index 3153aa7715b..58ef3f247cc 100644 --- a/awsapi/test/html/testRestURL.txt +++ b/awsapi/test/html/testRestURL.txt @@ -1,44 +1,44 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. - ------------------------------------------------------------ - - http://localhost:8080/gate/rest/AmazonEC2?Action=DescribeInstances&SignatureVersion=2&SignatureMethod=HmacSHA256&Version=2009-11-30&Timestamp=2010-01-07T15%3A23%3A03Z&Expires=2010-11-07T15%3A23%3A03Z&AWSAccessKeyId=O4O0Niu98EvraLKH2o8SFNMQlXZvuE5ueMDR9CHU5WA2-qv4PEQkgMcrtrNs6eHYwpLySev4Hi03_YXiHz4gGg&Signature=lyHOvu2LNxjLHIAlQo3F0JNSDtuCtqHtAX786cCZDFI= - - - -10:44:35,804 INFO EC2RestServlet:? - Request parameter Expires:2010-11-07T15:23 -:03Z -10:44:36,197 ERROR RestAuth:? - Signature mismatch, [+fhKzW5k+O33zWoJ6dUmmo9ycZi -td62M0Lwicz2jT2s=] [lyHOvu2LNxjLHIAlQo3F0JNSDtuCtqHtAX786cCZDFI=] over [GET -localhost:8080 -/gate/rest/AmazonEC2 -AWSAccessKeyId=O4O0Niu98EvraLKH2o8SFNMQlXZvuE5ueMDR9CHU5WA2-qv4PEQkgMcrtrNs6eHYw -pLySev4Hi03_YXiHz4gGg&Action=DescribeInstances&Expires=2010-11-07T15%3A23%3A03Z& -SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2010-01-07T15%3A23%3A03Z -&Version=2009-11-30] - - -From usercredentials table: ------------------------+ -| 4 | O4O0Niu98EvraLKH2o8SFNMQlXZvuE5ueMDR9CHU5WA2-qv4PEQkgMcrtrNs6eHYwpLySev4H -i03_YXiHz4gGg | EmskZDLp5EmwPQDzHtA2CK3heW12keN-YTTrO39Iz2Qfk8fmtkFih95B7xexhAat -rlQ5ioNns4iT9qav3WzmrQ | CN=AWS Limited-Assurance CA, OU=AWS, O=Amazon.com, C=US -, serial=1033226874324 | -+----+-------------------------------------------------------------------------- - -EmskZDLp5EmwPQDzHtA2CK3heW12keN-YTTrO39Iz2Qfk8fmtkFih95B7xexhAatrlQ5ioNns4iT9qav3WzmrQ +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. + +----------------------------------------------------------- + + http://localhost:8080/gate/rest/AmazonEC2?Action=DescribeInstances&SignatureVersion=2&SignatureMethod=HmacSHA256&Version=2009-11-30&Timestamp=2010-01-07T15%3A23%3A03Z&Expires=2010-11-07T15%3A23%3A03Z&AWSAccessKeyId=O4O0Niu98EvraLKH2o8SFNMQlXZvuE5ueMDR9CHU5WA2-qv4PEQkgMcrtrNs6eHYwpLySev4Hi03_YXiHz4gGg&Signature=lyHOvu2LNxjLHIAlQo3F0JNSDtuCtqHtAX786cCZDFI= + + + +10:44:35,804 INFO EC2RestServlet:? - Request parameter Expires:2010-11-07T15:23 +:03Z +10:44:36,197 ERROR RestAuth:? - Signature mismatch, [+fhKzW5k+O33zWoJ6dUmmo9ycZi +td62M0Lwicz2jT2s=] [lyHOvu2LNxjLHIAlQo3F0JNSDtuCtqHtAX786cCZDFI=] over [GET +localhost:8080 +/gate/rest/AmazonEC2 +AWSAccessKeyId=O4O0Niu98EvraLKH2o8SFNMQlXZvuE5ueMDR9CHU5WA2-qv4PEQkgMcrtrNs6eHYw +pLySev4Hi03_YXiHz4gGg&Action=DescribeInstances&Expires=2010-11-07T15%3A23%3A03Z& +SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2010-01-07T15%3A23%3A03Z +&Version=2009-11-30] + + +From usercredentials table: +-----------------------+ +| 4 | O4O0Niu98EvraLKH2o8SFNMQlXZvuE5ueMDR9CHU5WA2-qv4PEQkgMcrtrNs6eHYwpLySev4H +i03_YXiHz4gGg | EmskZDLp5EmwPQDzHtA2CK3heW12keN-YTTrO39Iz2Qfk8fmtkFih95B7xexhAat +rlQ5ioNns4iT9qav3WzmrQ | CN=AWS Limited-Assurance CA, OU=AWS, O=Amazon.com, C=US +, serial=1033226874324 | ++----+-------------------------------------------------------------------------- + +EmskZDLp5EmwPQDzHtA2CK3heW12keN-YTTrO39Iz2Qfk8fmtkFih95B7xexhAatrlQ5ioNns4iT9qav3WzmrQ diff --git a/awsapi/web/web.xml b/awsapi/web/web.xml index 288196f943c..a5b02072c3d 100644 --- a/awsapi/web/web.xml +++ b/awsapi/web/web.xml @@ -1,145 +1,145 @@ - - - - - - - - CloudBridge - - EC2MainServlet - EC2 Main Servlet - com.cloud.bridge.service.EC2MainServlet - 1 - - - AxisServlet - Apache-Axis Servlet - org.apache.axis2.transport.http.AxisServlet - - - - - - - - - - - 2 - - - AxisAdminServlet - Apache-Axis AxisAdmin Servlet (Web Admin) - - org.apache.axis2.webapp.AxisAdminServlet - - - CloudBridgeS3Servlet - Cloud.com Bridge S3 Service REST Servlet - com.cloud.bridge.service.S3RestServlet - - readonly - false - - - - CloudBridgeEC2Servlet - Cloud.com Bridge EC2 Service REST Servlet - com.cloud.bridge.service.EC2RestServlet - - - - CloudBridgeS3Servlet - /rest/AmazonS3 - - - - CloudBridgeS3Servlet - /rest/AmazonS3/* - - - - CloudBridgeS3Servlet - /dime/AmazonS3 - - - - - CloudBridgeEC2Servlet - /rest/AmazonEC2/* - - - - - CloudBridgeEC2Servlet - /rest/AmazonEC2 - - - - AxisServlet - /servlet/AxisServlet - - - - AxisServlet - *.jws - - - - AxisServlet - /services/* - - - - AxisAdminServlet - /axis2-admin/* - - - - EC2MainServlet - / - - - EC2MainServlet - /* - - - - inc - text/plain - - - - index.jsp - index.html - /axis2-web/index.jsp - - - - 404 - /axis2-web/Error/error404.jsp - - - - 500 - /axis2-web/Error/error500.jsp - - + + + + + + + + CloudBridge + + EC2MainServlet + EC2 Main Servlet + com.cloud.bridge.service.EC2MainServlet + 1 + + + AxisServlet + Apache-Axis Servlet + org.apache.axis2.transport.http.AxisServlet + + + + + + + + + + + 2 + + + AxisAdminServlet + Apache-Axis AxisAdmin Servlet (Web Admin) + + org.apache.axis2.webapp.AxisAdminServlet + + + CloudBridgeS3Servlet + Cloud.com Bridge S3 Service REST Servlet + com.cloud.bridge.service.S3RestServlet + + readonly + false + + + + CloudBridgeEC2Servlet + Cloud.com Bridge EC2 Service REST Servlet + com.cloud.bridge.service.EC2RestServlet + + + + CloudBridgeS3Servlet + /rest/AmazonS3 + + + + CloudBridgeS3Servlet + /rest/AmazonS3/* + + + + CloudBridgeS3Servlet + /dime/AmazonS3 + + + + + CloudBridgeEC2Servlet + /rest/AmazonEC2/* + + + + + CloudBridgeEC2Servlet + /rest/AmazonEC2 + + + + AxisServlet + /servlet/AxisServlet + + + + AxisServlet + *.jws + + + + AxisServlet + /services/* + + + + AxisAdminServlet + /axis2-admin/* + + + + EC2MainServlet + / + + + EC2MainServlet + /* + + + + inc + text/plain + + + + index.jsp + index.html + /axis2-web/index.jsp + + + + 404 + /axis2-web/Error/error404.jsp + + + + 500 + /axis2-web/Error/error500.jsp + + diff --git a/build/build-aws-api.xml b/build/build-aws-api.xml index d5bf729a9c6..40ad22c2679 100644 --- a/build/build-aws-api.xml +++ b/build/build-aws-api.xml @@ -225,7 +225,7 @@ - + @@ -299,7 +299,7 @@ - + @@ -369,12 +369,26 @@ - + + + + + + + + + + + + + + + + - diff --git a/build/build-cloud.xml b/build/build-cloud.xml index 1b25fac8796..c31d00da220 100755 --- a/build/build-cloud.xml +++ b/build/build-cloud.xml @@ -527,8 +527,6 @@ - - diff --git a/build/developer.xml b/build/developer.xml index 3121813040c..fdda171aff6 100755 --- a/build/developer.xml +++ b/build/developer.xml @@ -404,6 +404,7 @@ + @@ -411,7 +412,7 @@ - + diff --git a/build/replace.properties b/build/replace.properties index 8cd0fa3c76c..c9a93c2831c 100644 --- a/build/replace.properties +++ b/build/replace.properties @@ -24,6 +24,6 @@ DBHOST=localhost AGENTLOGDIR=logs AGENTLOG=logs/agent.log MSMNTDIR=/mnt -COMPONENTS-SPEC=components-premium.xml +COMPONENTS-SPEC=components.xml AWSAPILOG=awsapi.log REMOTEHOST=localhost diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 1535c314f3a..ce76a84c9b3 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -17,8 +17,15 @@ #new labels (begin) ********************************************************************************************** - - +label.quickview=Quickview +label.migrate.to.host=Migrate to host +label.migrate.to.storage=Migrate to storage +label.stop=Stop +label.reboot=Reboot +label.destroy=Destroy +label.restore=Restore +label.isolation.uri=Isolation URI +label.broadcast.uri=Broadcast URI #new labels (end) ************************************************************************************************ @@ -1117,6 +1124,9 @@ label.lang.chinese=Chinese (Simplified) label.lang.english=English label.lang.japanese=Japanese label.lang.spanish=Spanish +label.lang.russian=Russian +label.lang.french=French +label.lang.brportugese=Brazilian Portugese label.last.disconnected=Last Disconnected label.last.name=Last Name label.level=Level @@ -1512,3 +1522,10 @@ error.menu.select=Unable to perform action due to no items being selected. error.mgmt.server.inaccessible=The Management Server is unaccessible. Please try again later. error.session.expired=Your session has expired. error.unresolved.internet.name=Your internet name cannot be resolved. + +label.add.NiciraNvp.device=Add Nvp Controller +label.delete.NiciraNvp=Remove Nvp Controller +label.nicira.controller.address=Controller Address +label.nicira.transportzoneuuid=Transport Zone Uuid +label.nicira.l3gatewayserviceuuid=L3 Gateway Service Uuid + diff --git a/client/WEB-INF/classes/resources/messages_fr_FR.properties b/client/WEB-INF/classes/resources/messages_fr_FR.properties new file mode 100644 index 00000000000..ae034cc1141 --- /dev/null +++ b/client/WEB-INF/classes/resources/messages_fr_FR.properties @@ -0,0 +1,1514 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + + +#new labels (begin) ********************************************************************************************** +# label.isolation.uri=Isolation URI +# label.broadcast.uri=Broadcast URI +#new labels (end) ************************************************************************************************ + + +#modified labels (begin) ***************************************************************************************** +# message.zoneWizard.enable.local.storage=WARNING\: If you enable local storage for this zone, you must do the following, depending on where you would like your system VMs to launch\:

1. If system VMs need to be launched in primary storage, primary storage needs to be added to the zone after creation. You must also start the zone in a disabled state.

2. If system VMs need to be launched in local storage, system.vm.use.local.storage needs to be set to true before you enable the zone.


Would you like to continue? +#modified labels (end) ******************************************************************************************* + +# label.configure.network.ACLs=Configure Network ACLs +# label.network.ACLs=Network ACLs +# label.add.network.ACL=Add network ACL +# label.private.Gateway=Private Gateway +# label.VPC.router.details=VPC router details +# label.VMs.in.tier=VMs in tier +# label.local.storage.enabled=Local storage enabled +# label.tier.details=Tier details +# label.edit.tags=Edit tags +label.action.enable.physical.network=Activer le rseau physique +label.action.disable.physical.network=Dsactiver le rseau physique +message.action.enable.physical.network=Confirmer l'activation de ce rseau physique. +message.action.disable.physical.network=Confirmer la dsactivation de ce rseau physique. + +# label.select.tier=Select Tier +# label.add.ACL=Add ACL +# label.remove.ACL=Remove ACL +# label.tier=Tier +# label.network.ACL=Network ACL +# label.network.ACL.total=Network ACL Total +# label.add.new.gateway=Add new gateway +# message.add.new.gateway.to.vpc=Please specify the information to add a new gateway to this VPC. +# label.delete.gateway=delete gateway +# message.delete.gateway=Please confirm you want to delete the gateway +# label.CIDR.of.destination.network=CIDR of destination network +# label.add.route=Add route +# label.add.static.route=Add static route +# label.remove.static.route=Remove static route +# label.site.to.site.VPN=site-to-site VPN +# label.add.VPN.gateway=Add VPN Gateway +# message.add.VPN.gateway=Please confirm that you want to add a VPN Gateway +# label.VPN.gateway=VPN Gateway +# label.delete.VPN.gateway=delete VPN Gateway +# message.delete.VPN.gateway=Please confirm that you want to delete this VPN Gateway +# label.VPN.connection=VPN Connection +# label.IPsec.preshared.key=IPsec Preshared-Key +# label.IKE.policy=IKE policy +# label.ESP.policy=ESP policy +# label.create.VPN.connection=Create VPN Connection +# label.VPN.customer.gateway=VPN Customer Gateway +# label.CIDR.list=CIDR list +# label.IKE.lifetime=IKE Lifetime (second) +# label.ESP.lifetime=ESP Lifetime(second) +# label.dead.peer.detection=Dead Peer Detection +# label.reset.VPN.connection=Reset VPN connection +# message.reset.VPN.connection=Please confirm that you want to reset VPN connection +# label.delete.VPN.connection=delete VPN connection +# message.delete.VPN.connection=Please confirm that you want to delete VPN connection +# label.add.new.tier=Add new tier +# label.add.VM.to.tier=Add VM to tier +# label.remove.tier=Remove tier + +# label.local.storage.enabled=Local storage enabled +# label.associated.network=Associated Network +# label.add.port.forwarding.rule=Add port forwarding rule +# label.dns=DNS + +# label.vpc=VPC +# label.vpc.id=VPC ID +# label.tier=Tier +# label.add.vpc=Add VPC +# label.super.cidr.for.guest.networks=Super CIDR for Guest Networks +# label.DNS.domain.for.guest.networks=DNS domain for Guest Networks +# label.configure.vpc=Configure VPC +# label.edit.vpc=Edit VPC +# label.restart.vpc=restart VPC +# message.restart.vpc=Please confirm that you want to restart the VPC +# label.remove.vpc=remove VPC +# message.remove.vpc=Please confirm that you want to remove the VPC +# label.vpn.customer.gateway=VPN Customer Gateway +# label.add.vpn.customer.gateway=Add VPN Customer Gateway +# label.IKE.encryption=IKE Encryption +# label.IKE.hash=IKE Hash +# label.IKE.DH=IKE DH +# label.ESP.encryption=ESP Encryption +# label.ESP.hash=ESP Hash +# label.perfect.forward.secrecy=Perfect Forward Secrecy +# label.IKE.lifetime=IKE Lifetime (second) +# label.ESP.lifetime=ESP Lifetime(second) +# label.dead.peer.detection=Dead Peer Detection +# label.delete.VPN.customer.gateway=delete VPN Customer Gateway +# message.delete.VPN.customer.gateway=Please confirm that you want to delete this VPN Customer Gateway + +label.network.domain.text=Texte du domaine rseau +label.memory.mb=Mmoire +label.cpu.mhz=CPU (en MHz) + +message.action.remove.host=Supprimer le dernier/seul hte dans le cluster et le rinstaller va supprimer l'environnement/la base de donnes sur l'hte et rendre les VMs invites inutilisables. + +message.action.reboot.router=Confirmez que vous souhaitez redmarrer ce routeur. +message.action.stop.router=Confirmez que vous souhaitez arrter ce routeur. +message.restart.network=Confirmer le redmarrage du rseau + + +label.ipaddress=Adresse IP +label.vcdcname=Nom du DC vCenter +label.vcipaddress=Adresse IP vCenter +label.vsmctrlvlanid=VLAN ID Controle +label.vsmpktvlanid=VLAN ID Paquet +label.vsmstoragevlanid=VLAN ID Stockage +label.nexusVswitch=Nexus Vswitch +label.action.delete.nexusVswitch=Supprimer le NexusVswitch +label.action.enable.nexusVswitch=Activer le NexusVswitch +label.action.disable.nexusVswitch=Dsactiver le NexusVswitch +label.action.list.nexusVswitch=Lister les NexusVswitch +message.action.delete.nexusVswitch=Confirmer la suppression de ce NexusVswitch. +message.action.enable.nexusVswitch=Confirmer l'activation de ce NexusVswitch. +message.action.disable.nexusVswitch=Confirmer la dsactivation de ce NexusVswitch. +message.specify.url=Renseigner l'URL +label.select.instance.to.attach.volume.to=Slectionner l'instance laquelle rattacher ce volume +label.upload=Charger +label.upload.volume=Charger un volume +label.virtual.routers=Routeurs virtuels +label.primary.storage.count=Groupes de stockage primaire +label.secondary.storage.count=Groupes de stokage secondaire +label.number.of.system.vms=Nombre de VM systme +label.number.of.virtual.routers=Nombre de routeurs virtuels +label.action.register.iso=Enregistrer ISO +label.isolation.method=Mthode de sparation +label.action.register.template=Enregister image +label.checksum=Checksum MD5 +label.vpn=VPN +label.vlan=VLAN + + +label.management.ips=Adresses IP de management +label.devices=Machines +label.rules=Rgles +label.traffic.label=Label trafic +label.vm.state=Etat VM +# message.setup.physical.network.during.zone.creation.basic=When adding a basic zone, you can set up one physical network, which corresponds to a NIC on the hypervisor. The network carries several types of traffic.

You may also drag and drop other traffic types onto the physical network. +label.domain.router=Routeur du domaine +label.console.proxy=Console proxy +label.secondary.storage.vm=VM stockage secondaire +label.add.netScaler.device=Ajouter un Netscaler +label.add.F5.device=Ajouter un F5 +label.add.SRX.device=Ajouter un SRX +label.account.and.security.group=Compte, groupe de scurit +label.fetch.latest=Raffraichir +label.system.offering=Offre systme +message.validate.instance.name=le nom de l'instance de l'instance ne peut dpasser 63 caractres. Seuls les lettres de a z, les chiffres de 0 9 et les tirets sont accepts. Le nom doit commencer par une lettre et se terminer par une lettre ou un chiffre. + + +label.isolated.networks=Rseaux isols +label.latest.events=Derniers venements +state.Enabled=Actifs +label.system.wide.capacity=Capacit globale +label.network.service.providers=Provider de rseau +message.launch.zone=La zone est prte dmarrer; Continuer. +error.unable.to.reach.management.server=Impossible de joindre le serveur de management +label.internal.name=Nom interne +message.configure.all.traffic.types=Vous avez de multiples rseaux physiques; veuillez configurer les labels pour chaque type de trafic en cliquant sur le bouton Modifier. +message.edit.traffic.type=Spcifier le label de trafic associ avec ce type de trafic +label.edit.traffic.type=Modifer le type de trafic +label.label=Label +label.max.networks=Rseaux Max. +error.invalid.username.password=Utilisateur ou mot de passe invalide +message.enabling.security.group.provider=Activation du groupe de scurit pour le provider +message.adding.Netscaler.provider=Ajouter un Netscaler provider +message.creating.guest.network=Cration du rseau pour les instances +label.action.delete.physical.network=Supprimer le rseau physique +message.action.delete.physical.network=Confirmer la suppression du rseau physique +# message.installWizard.copy.whatIsAHost=A host is a single computer. Hosts provide the computing resources that run the guest virtual machines. Each host has hypervisor software installed on it to manage the guest VMs (except for bare metal hosts, which are a special case discussed in the Advanced Installation Guide). For example, a Linux KVM-enabled server, a Citrix XenServer server, and an ESXi server are hosts. In a Basic Installation, we use a single host running XenServer or KVM.

The host is the smallest organizational unit within a CloudStack&\#8482; deployment. Hosts are contained within clusters, clusters are contained within pods, and pods are contained within zones. + + +label.add.compute.offering=Ajouter une offre de calcul +label.compute.offering=Offre de calcul +label.compute.offerings=Offres de calcul +label.select.offering=Choisir une offre +label.menu.infrastructure=Infrastructure +label.sticky.tablesize=Taille du tableau +label.sticky.expire=Expiration +label.sticky.cookie-name=Nom du cookie +label.sticky.mode=Mode +label.sticky.length=Longueur +label.sticky.holdtime=Temps de pause +label.sticky.request-learn=Apprendre la requte +label.sticky.prefix=Prfixe +label.sticky.nocache=Pas de cache +label.sticky.indirect=Indirect +label.sticky.postonly=Aprs seulement +label.sticky.domain=Domaine +state.Allocating=Allocation en cours +state.Migrating=Migration en cours +error.please.specify.physical.network.tags=L'offre rseau ne sera pas disponible tant que des label n'auront pas t renseigner pour ce rseau physique. + + +state.Stopping=Arrt en cours +message.add.load.balancer.under.ip=La rgle de load balancer a t ajoute sous l'adresse IP \: +message.select.instance=Slectionner une instance. +label.select=Selectionner +label.select.vm.for.static.nat=Slectionner une VM pour le NAT statique +label.select.instance=Slectionner une instance. +label.nat.port.range=Plage de port NAT +label.static.nat.vm.details=NAT statique, dtails par VM +label.edit.lb.rule=Modifier la rgle LB +message.migrate.instance.to.host=Merci de confirmer la migration de l'instance vers un autre serveur +label.migrate.instance.to.host=Migration de l'instance sur un autre serveur +message.migrate.instance.to.ps=Merci de confirmer la migration de l'instance vers un autre stockage primaire +label.migrate.instance.to.ps=Migration de l'instance sur un autre stockage primaire +label.corrections.saved=Modifications enregistres +# message.installWizard.copy.whatIsSecondaryStorage=Secondary storage is associated with a zone, and it stores the following\:
  • Templates - OS images that can be used to boot VMs and can include additional configuration information, such as installed applications
  • ISO images - OS images that can be bootable or non-bootable
  • Disk volume snapshots - saved copies of VM data which can be used for data recovery or to create new templates
+# message.installWizard.copy.whatIsPrimaryStorage=A CloudStack&\#8482; cloud infrastructure makes use of two types of storage\: primary storage and secondary storage. Both of these can be iSCSI or NFS servers, or localdisk.

Primary storage is associated with a cluster, and it stores the disk volumes of each guest VM for all the VMs running on hosts in that cluster. The primary storage server is typically located close to the hosts. +# message.installWizard.copy.whatIsACluster=A cluster provides a way to group hosts. The hosts in a cluster all have identical hardware, run the same hypervisor, are on the same subnet, and access the same shared storage. Virtual machine instances (VMs) can be live-migrated from one host to another within the same cluster, without interrupting service to the user. A cluster is the third-largest organizational unit within a CloudStack&\#8482; deployment. Clusters are contained within pods, and pods are contained within zones.

CloudStack&\#8482; allows multiple clusters in a cloud deployment, but for a Basic Installation, we only need one cluster. +# message.installWizard.copy.whatIsAPod=A pod often represents a single rack. Hosts in the same pod are in the same subnet.

A pod is the second-largest organizational unit within a CloudStack&\#8482; deployment. Pods are contained within zones. Each zone can contain one or more pods; in the Basic Installation, you will have just one pod in your zone. +# message.installWizard.copy.whatIsAZone=A zone is the largest organizational unit within a CloudStack&\#8482; deployment. A zone typically corresponds to a single datacenter, although it is permissible to have multiple zones in a datacenter. The benefit of organizing infrastructure into zones is to provide physical isolation and redundancy. For example, each zone can have its own power supply and network uplink, and the zones can be widely separated geographically (though this is not required). +# message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482 is a software platform that pools computing resources to build public, private, and hybrid Infrastructure as a Service (IaaS) clouds. CloudStack&\#8482 manages the network, storage, and compute nodes that make up a cloud infrastructure. Use CloudStack&\#8482 to deploy, manage, and configure cloud computing environments.

Extending beyond individual virtual machine images running on commodity hardware, CloudStack&\#8482 provides a turnkey cloud infrastructure software stack for delivering virtual datacenters as a service - delivering all of the essential components to build, deploy, and manage multi-tier and multi-tenant cloud applications. Both open-source and Premium versions are available, with the open-source version offering nearly identical features. +message.installWizard.tooltip.addSecondaryStorage.path=Le chemin export, situ sur le serveur spcifi prcdement +message.installWizard.tooltip.addSecondaryStorage.nfsServer=Adresse IP du server NFS supportant le stockage secondaire +# message.installWizard.tooltip.addPrimaryStorage.path=(for NFS) In NFS this is the exported path from the server. Path (for SharedMountPoint). With KVM this is the path on each host that is where this primary storage is mounted. For example, "/mnt/primary". +message.installWizard.tooltip.addPrimaryStorage.server=(pour NFS, iSCSI ou PreSetup) Adresse IP ou nom DNS du stockage +message.installWizard.tooltip.addPrimaryStorage.name=Nom pour ce stockage +message.installWizard.tooltip.addHost.password=Le mot de passe pour l'utilisateur indiqu prcdement (issu de l'installation XenServer). +message.installWizard.tooltip.addHost.username=Habituellement root. +message.installWizard.tooltip.addHost.hostname=Le nom DNS ou adresse IP du serveur. +message.installWizard.tooltip.addCluster.name=Un nom pour le cluster. Ce choix est libre et n'est pas utilis par CloudStack. +# message.installWizard.tooltip.addPod.reservedSystemEndIp=This is the IP range in the private network that the CloudStack uses to manage Secondary Storage VMs and Console Proxy VMs. These IP addresses are taken from the same subnet as computing servers. +# message.installWizard.tooltip.addPod.reservedSystemStartIp=This is the IP range in the private network that the CloudStack uses to manage Secondary Storage VMs and Console Proxy VMs. These IP addresses are taken from the same subnet as computing servers. +message.installWizard.tooltip.addPod.reservedSystemNetmask=Le masque rseau que les instances utiliseront sur le rseau +message.installWizard.tooltip.addPod.reservedSystemGateway=Passerelle pour les serveurs dans ce pod +message.installWizard.tooltip.addPod.name=Nom pour le pod +# message.installWizard.tooltip.configureGuestTraffic.guestEndIp=The range of IP addresses that will be available for allocation to guests in this zone. If one NIC is used, these IPs should be in the same CIDR as the pod CIDR. +# message.installWizard.tooltip.configureGuestTraffic.guestStartIp=The range of IP addresses that will be available for allocation to guests in this zone. If one NIC is used, these IPs should be in the same CIDR as the pod CIDR. +message.installWizard.tooltip.configureGuestTraffic.guestNetmask=Le masque rseau que les instances devrait utiliser sur le rseau +message.installWizard.tooltip.configureGuestTraffic.guestGateway=La passerelle que les instances clientes doivent utiliser +message.installWizard.tooltip.configureGuestTraffic.description=Desctiption pour ce rseau +message.installWizard.tooltip.configureGuestTraffic.name=Nom pour ce rseau +# message.installWizard.tooltip.addZone.internaldns2=These are DNS servers for use by system VMs in the zone. These DNS servers will be accessed via the private network interface of the System VMs. The private IP address you provide for the pods must have a route to the DNS server named here. +# message.installWizard.tooltip.addZone.internaldns1=These are DNS servers for use by system VMs in the zone. These DNS servers will be accessed via the private network interface of the System VMs. The private IP address you provide for the pods must have a route to the DNS server named here. +# message.installWizard.tooltip.addZone.dns2=These are DNS servers for use by guest VMs in the zone. These DNS servers will be accessed via the public network you will add later. The public IP addresses for the zone must have a route to the DNS server named here. +message.installWizard.tooltip.addZone.name=Nom pour la zone +# message.installWizard.tooltip.addZone.dns1=These are DNS servers for use by guest VMs in the zone. These DNS servers will be accessed via the public network you will add later. The public IP addresses for the zone must have a route to the DNS server named here. +message.setup.successful=Installation Cloud russie \! +label.may.continue=Vous pouvez continuer. +error.installWizard.message=Une erreur s'est produite; vous pouvez retourner en arrire et corriger les erreurs +message.installWizard.now.building=Construction de votre Cloud en cours +message.installWizard.click.retry=Appuyer sur le bouton pour essayer nouveau le dmarrage. +label.launch=Dmarrer +label.installWizard.click.launch=Appuyer sur le bouton dmarrer. +label.congratulations=Flicitations \! +label.installWizard.addSecondaryStorageIntro.subtitle=Qu'est ce que le stockage secondaire ? +label.installWizard.addSecondaryStorageIntro.title=Ajoutons du stockage secondaire +label.installWizard.addPrimaryStorageIntro.subtitle=Qu'est ce que le stockage primaire ? +label.installWizard.addPrimaryStorageIntro.title=Ajoutons du stockage primaire +label.installWizard.addHostIntro.subtitle=Qu'est ce qu'un serveur ? +label.installWizard.addHostIntro.title=Ajoutons un serveur +label.installWizard.addClusterIntro.subtitle=Qu'est ce qu'un cluster ? +label.installWizard.addClusterIntro.title=Ajoutons un cluster +label.installWizard.addPodIntro.subtitle=Qu'est ce qu'un pod ? +label.installWizard.addPodIntro.title=Ajoutons un pod +label.installWizard.addZone.title=Ajouter une zone +label.installWizard.addZoneIntro.subtitle=Qu'est ce qu'une zone ? +label.installWizard.addZoneIntro.title=Ajoutons une zone +error.password.not.match=Les mot de passe ne correspondent pas +label.confirm.password=Confirmer le mot de passe +message.change.password=Merci de modifier votre mot de passe. +label.save.and.continue=Enregistrer et continuer +label.skip.guide=J'ai dj utilis CloudStack avant, passer ce tutorial +label.continue.basic.install=Continuer avec l'installation basique +label.introduction.to.cloudstack=Introduction CloudStack +label.what.is.cloudstack=Qu'est ce que CloudStack ? +label.hints=Astuces +label.installWizard.subtitle=Ce tutorial vous aidera configurer votre installation CloudStack +label.continue=Continuer +label.installWizard.title=Bonjour et bienvenue dans CloudStack +label.agree=Accepter +label.license.agreement=Accord de licence +label.license.agreement.subtitle=Merci d'accepter l'EULA CloudStack avant d'installer. +label.manage.resources=Grer les ressources +label.port.forwarding.policies=Rgles de transfert de port +label.load.balancing.policies=Rgles de rpartition de charge +label.networking.and.security=Rseau et scurit +label.bandwidth=Bande passante +label.virtual.machines=Machines virtuelles +label.compute.and.storage=Processeur et Stockage +label.task.completed=Tche termine +label.update.project.resources=Mettre jour les ressources du projet +label.remove.project.account=Supprimer le compte projet +label.item.listing=Liste des lments +message.select.item=Merci de slectionner un lment. +label.removing=Suppression +label.invite=Inviter +label.add.by=Ajout par +label.max.vms=Max VMs utilisateur +label.max.public.ips=Max IP publiques +label.max.volumes=Max volumes +label.max.snapshots=Max snapshots +label.max.templates=Max images +# label.max.vpcs=Max. VPCs +label.project.dashboard=Tableau de bord projet +label.remind.later=Rappeler moi plus tard +label.invited.accounts=Comptes invits +label.invite.to=Inviter sur +label.add.accounts.to=Ajouter des comptes sur +label.add.accounts=Ajouter des comptes +label.project.name=Nom du projet +label.create.project=Crer un projet +label.networks=Rseaux +label.launch.vm=Dmarrer VM +label.new.vm=Nouvelle VM +label.previous=Retour +label.add.to.group=Ajouter au groupe +message.vm.review.launch=Merci de vrifier les informations suivantes et de confirmer que votre instance virtuelle est correcte avant de la dmarrer. +message.select.security.groups=Merci de slectionner un(des) groupe(s) de scurit pour la nouvelle VM +label.new=Nouveau +message.please.select.networks=Selectionner les rseaux pour votre instance. +message.please.proceed=Continuer vers la prochaine tape. +message.zone.no.network.selection=La zone slectionne ne propose pas le rseau choisi +label.no.thanks=Non merci +label.my.templates=Mes images +message.select.template=Slectionner une image pour votre nouvelle instance virtuelle. +message.select.iso=Slectionner une ISO pour votre nouvelle instance virtuelle. +message.template.desc=Image OS pouvant tre utilise pour dmarrer une VM +message.iso.desc=Image ISO contenant des donnes ou des binaires de dmarrage +label.select.iso.or.template=Slectionner une ISO ou une image +message.select.a.zone=Une zone corespond en gnral un seul datacenter. Des zones multiples peuvent permettre de rendre votre cloud plus fiable en apportant une isolation physique et de la redondance. +label.select.a.zone=Slectionner une zone +label.review=Revoir +label.select.a.template=Slectionner une image +label.setup=Configuration +state.Allocated=Allou +changed.item.properties=Proprits de l'lment modifies +label.apply=Appliquer +label.default=Par dfaut +label.viewing=Consultation en cours +label.move.to.top=Placer au dessus +label.move.up.row=Monter d'un cran +label.move.down.row=Descendre d'un cran +# label.move.to.bottom=Move to bottom +label.drag.new.position=Dplacer sur une autre position +label.order=Ordre +label.no.data=Aucune donne +label.change.value=Modifier la valeur +label.clear.list=Purger la liste +label.full.path=Chemin complet +message.add.domain=Spcifier le sous domaine que vous souhaitez crer sous ce domaine +message.delete.user=Confirmer la suppression de l'utilisateur. +message.enable.user=Confirmer l'activation de cet utilisateur. +message.disable.user=Confirmer la dsactivation de l'utilisateur. +message.generate.keys=Confirmer la gnration de nouvelles clefs pour cet utilisateur. +message.update.resource.count=Confirmer la mise jour des ressources pour ce compte. +message.edit.account=Modifier ("-1" signifie pas de limite de ressources) +label.total.of.vm=Total VM +label.total.of.ip=Total adresses IP +state.enabled=Actif +message.action.download.iso=Confirmer le tlchargement de l'ISO +message.action.download.template=Confirmer le tlchargement de l'image +label.destination.zone=Zone destination +label.keyboard.type=Type de clavier +label.nic.adapter.type=Type de carte rseau +label.root.disk.controller=Controlleur disque principal +label.community=Communaut +label.remove.egress.rule=Supprimer la rgle sortante +label.add.egress.rule=Ajouter la rgle sortante +label.egress.rule=Rgle sortante +label.remove.ingress.rule=Supprimer la rgle entrante +label.delete.vpn.user=Supprimer l'utilisateur VPN +label.add.vpn.user=Ajouter un utilisateur VPN +label.remove.pf=Supprimer la rgle de transfert de port +label.remove.vm.from.lb=Supprimer la VM de la rgle de rpartition de charge +label.add.vms.to.lb=Ajouter une/des VM(s) la rgle de rpartition de charge +label.add.vm=Ajouter VM +label.remove.static.nat.rule=Supprimer le NAT statique +label.remove.rule=Supprimer la rgle +label.add.static.nat.rule=Ajouter une rgle de NAT statique +label.add.rule=Ajouter rgle +label.configuration=Configuration +message.disable.vpn=Etes vous sr de vouloir dsactiver le VPN ? +label.disable.vpn=Dsactiver le VPN +message.enable.vpn=Confirmer l'activation de l'accs VPN pour cette adresse IP. +label.enable.vpn=Activer VPN +message.acquire.new.ip=Confirmer l'ajout d'une nouvelle adresse IP pour ce rseau. +label.elastic=Elastique +label.my.network=Mon rseau +label.add.vms=Ajouter VMs +label.configure=Configurer +label.stickiness=Fidlit +label.source=Origine +label.least.connections=Le moins de connexions +label.round.robin=Alatoire +label.restart.required=Rdmarrage ncessaire +label.clean.up=Nettoyage +label.restart.network=Redmarrage du rseau +label.edit.network.details=Modifier les paramtres rseau +label.add.guest.network=Ajout d'un rseau pour les VM +label.guest.networks=Rseau pour les VM +message.ip.address.changed=Vos adresses IP ont peut tre changes; Voulez vous raffraichir la liste ? Dans ce cas, le panneau de dtail se fermera. +state.BackingUp=Sauvegarde en cours +state.BackedUp=Sauvegard +label.done=Termin +label.vm.name=Nom de la VM +message.migrate.volume=Confirmer la migration du volume vers un autre stockage primaire. +label.migrate.volume=Migration du volume vers un autre stockage primaire +message.create.template=Voulez vous crer l'image ? +label.create.template=Cration d'image +message.download.volume.confirm=Confirmer le tlchargement du volume +message.detach.disk=Voulez vous dtacher ce disque ? +state.ready=Prt +state.Ready=Prt +label.vm.display.name=Nom d'affichage de la VM +label.select-view=Slectionner la vue +label.local.storage=Stockage local +label.direct.ips=IP directes +label.view.all=Voir tout +label.zone.details=Dtails de la zone +message.alert.state.detected=Etat d'alerte dtect +state.Starting=Dmarrage en cours +state.Expunging=Purge en cours +state.Creating=Cration en cours +message.decline.invitation=Voulez vous refuser cette invitation au projet ? +label.decline.invitation=Refuser l'invitation +message.confirm.join.project=Confirmer l'invitation au projet +message.join.project=Vous avez rejoint un projet. Slectionnez la vue Projet pour le voir. +label.accept.project.invitation=Accepter l'invitation au projet +label.token=Jeton unique +label.project.id=ID projet +message.enter.token=Entrer le jeton unique reu dans le message d'invitation. +label.enter.token=Entrez le jeton unique +state.Accepted=Accept +state.Pending=En attente +state.Completed=Termin +state.Declined=Refus +label.project=Projet +label.invitations=Invitations +label.delete.project=Supprimer projet +message.delete.project=Confirmer la suppression du projet +message.activate.project=Confirmer l'activation de ce projet +label.activate.project=Activer projet +label.suspend.project=Suspendre projet +message.suspend.project=Confirmer la suspension de ce projet +state.Suspended=Suspendu +label.edit.project.details=Modifier les dtails du projet +label.new.project=Nouveau projet +state.Active=Actif +state.Disabled=Dsactiv +label.projects=Projets +label.make.project.owner=Devenir propritaire du projet +label.remove.project.account=Supprimer le compte projet +message.project.invite.sent=Invitation envoye; les utilisateurs seront ajouts aprs acceptation de l'invitation +label.add.account.to.project=Ajouter un compte au projet +label.revoke.project.invite=Revoquer l'invitation +label.project.invite=Inviter sur le projet +label.select.project=Slectionner un projet +message.no.projects=Vous n'avez pas de projet.
Vous pouvez en crer un depuis la section projets. +message.no.projects.adminOnly=Vous n'avez pas de projet.
Contacter votre administrateur pour ajouter un projet. +message.pending.projects.1=Vous avez des invitations projet en attente \: +message.pending.projects.2=Pour les visualiser, aller dans la section projets, puis slectionner invitation dans la liste droulante. +message.instanceWizard.noTemplates=Vous n'avez pas de image disponible; Ajouter une image compatible puis relancer l'assistant de cration d'instance. +label.view=Voir +instances.actions.reboot.label=Redmarrer l'instance +label.filterBy=Filtrer par +label.ok=OK +notification.reboot.instance=Redmarrer l'instance +notification.start.instance=Dmarrer l'instance +notification.stop.instance=Stopper l'instance +label.display.name=Nom d'affichage +label.zone.name=Nom de la zone +ui.listView.filters.all=Tous +ui.listView.filters.mine=Mon +state.Running=Dmarre +state.Stopped=Arrte +state.Destroyed=Supprime +state.Error=Erreur +message.reset.password.warning.notPasswordEnabled=L'image de cette instance a t cre sans la gestion de mot de passe +message.reset.password.warning.notStopped=Votre instance doit tre arrete avant de changer son mot de passe +label.notifications=Messages +label.default.view=Vue par dfaut +label.project.view=Vue projet + +message.add.system.service.offering=Ajouter les informations suivantes pour crer une nouvelle offre systme. +message.action.delete.system.service.offering=Confirmer la suppression de l'offre systme. +label.action.delete.system.service.offering=Supprimer l'offre systme +label.hypervisor.capabilities=Fonctions hyperviseur +label.hypervisor.version=Version hyperviseur +label.max.guest.limit=Nombre maximum d'instances +label.add.network.offering=Ajouter une offre rseau +label.supported.services=Services supports +label.service.capabilities=Fonctions disponibles +label.guest.type=Type d'instance +label.specify.IP.ranges=Plages IP +label.conserve.mode=Conserver le mode +label.created.by.system=Cr par le system +label.menu.system.service.offerings=Offres systme +label.add.system.service.offering=Ajouter une offre de service systme +label.redundant.router.capability=Router redondant +label.supported.source.NAT.type=Type de NAT support +label.elastic.LB=Rpartition de charge extensible +label.LB.isolation=Rpartition de charge isole +label.elastic.IP=IP extensible +label.network.label.display.for.blank.value=Utiliser la passerelle par dfaut +label.xen.traffic.label=Label pour le trafic Xenserver +label.kvm.traffic.label=Label pour le trafic KVM +label.vmware.traffic.label=Label pour le trafic VMware +label.start.IP=Dmarrer l'IP +label.end.IP=Rsilier l'IP +label.remove.ip.range=Supprimer la plage IP +label.ip.ranges=Plages IP +label.start.vlan=VLAN de dpart +label.end.vlan=VLAN de fin +label.broadcast.domain.range=Plage de brodcast domaine +label.compute=Processeur +message.add.guest.network=Confirmer l'ajout du rseau +label.subdomain.access=Accs au sous domaine +label.guest.start.ip=Adresse IP de dbut pour les instances +label.guest.end.ip=Adresse IP de fin pour les instances +label.virtual.router=Routeur Virtuel +label.physical.network.ID=ID du rseau physique +label.destination.physical.network.id=ID du rseau physique de destination +label.dhcp=DHCP +label.destroy.router=Supprimer le routeur +message.confirm.destroy.router=Confirmer la suppression du routeur +label.change.service.offering=Modifier l'offre de service +label.view.console=Voir la console +label.redundant.state=Etat redondant +label.enable.provider=Activer le provider +message.confirm.enable.provider=Confirmer l'activation de ce provider +label.disable.provider=Dsactiver ce provider +message.confirm.disable.provider=Confirmer la dsactivation de ce provider +label.shutdown.provider=Eteindre le provider +message.confirm.shutdown.provider=Confirmer l'extinction de ce provider +label.netScaler=Netscaler +label.add.new.NetScaler=Ajouter Netscaler +label.capacity=Capacit +label.dedicated=Ddi +label.f5=F5 +label.add.new.F5=Ajouter un F5 +label.srx=SRX +label.providers=Fournisseurs +label.add.new.SRX=Ajouter un SRX +label.timeout=Expiration +label.public.network=Rseau public +label.private.network=Rseau priv +label.enable.swift=Activer Swift +confirm.enable.swift=Remplir les informations suivantes pour activer Swift +message.after.enable.swift=Swift configur. Remarque \: une fois quitter cette page, il ne sera plus possible de reconfigur Swift une nouvelle fois. +label.key=Clef +label.delete.NetScaler=Supprimer Netscaler +message.confirm.delete.NetScaler=Confirmer la suppression du Netscaler +label.delete.F5=Supprimer F5 +message.confirm.delete.F5=Confirmer la suppression du F5 +label.delete.SRX=Supprimer SRX +message.confirm.delete.SRX=Confirmer la suppression du SRX +label.pods=Pods +label.pod.name=Nom du pod +label.reserved.system.gateway=Gateway systme rserve +label.reserved.system.netmask=Masque rseau systme rserv +label.start.reserved.system.IP=Adresse IP de dmarrage rserve pour le systme +label.end.reserved.system.IP=Adresse IP de fin rserve pour le systme +label.clusters=Clusters +label.cluster.name=Nom du cluster +label.host.MAC=MAC serveur +label.agent.username=Compte de l'agent +label.agent.password=Mot de passe de l'agent +message.confirm.action.force.reconnect=Confirmer que reconnection force de ce serveur. +label.resource.state=Etat des ressources +label.LUN.number=N LUN +message.confirm.remove.IP.range=Confirmer la suppression de cette plage d'adresses IP +message.tooltip.zone.name=Nom pour la zone. +message.tooltip.dns.1=Nom d'un serveur DNS utilis par les VM de la zone. Les adresses IP publiques de cette zones doivent avoir une route vers ce serveur. +message.tooltip.dns.2=Nom d'un serveur DNS secondaire utilis par les VM de la zone. Les adresses IP publiques de cette zones doivent avoir une route vers ce serveur. +message.tooltip.internal.dns.1=Nom d'un serveur DNS que CloudStack peut utiliser pour les VM systme dans cette zone. Les adresses IP prives des pods doivent avoir une route vers ce serveur. +message.tooltip.internal.dns.2=Nom d'un serveur DNS que CloudStack peut utiliser pour les VM systme dans cette zone. Les adresses IP prives des pods doivent avoir une route vers ce serveur. +message.tooltip.network.domain=Suffixe DNS pour les noms de domaine personnaliss accd par les intances. +message.tooltip.pod.name=Nom pour le pod. +message.tooltip.reserved.system.gateway=La passerelle pour les serveur du pod. +message.tooltip.reserved.system.netmask=Le prfixe rseau utilis par le sous-rseau du pod. Au format CIDR. +message.creating.zone=Cration de la zone +message.creating.physical.networks=Cration des rseaux physiques +message.configuring.physical.networks=Configuration des rseaux physiques +message.adding.Netscaler.device=Ajout du Netscaler +message.creating.pod=Cration d'un pod +message.configuring.public.traffic=Configuration du rseau public +message.configuring.storage.traffic=Configuration du rseau de stockage +message.configuring.guest.traffic=Configuration du rseau VM +message.creating.cluster=Cration du cluster +message.adding.host=Ajout du serveur +message.creating.primary.storage=Cration du stockage primaire +message.creating.secondary.storage=Cration du stockage secondaire +message.Zone.creation.complete=Cration de la zone termine +message.enabling.zone=Activation de la zone +error.something.went.wrong.please.correct.the.following=Erreur; corriger le point suivant +error.could.not.enable.zone=Impossible d'activer la zone +message.zone.creation.complete.would.you.like.to.enable.this.zone=Cration de la zone termine. Voulez vous l'activer ? +message.please.add.at.lease.one.traffic.range=Ajouter au moins une plage rseau +message.you.must.have.at.least.one.physical.network=Vous devez avoir au moins un rseau physique +message.please.select.a.different.public.and.management.network.before.removing=Slectionner un rseau publique et management diffrent avant de supprimer + +label.zone.type=Type de zone +label.setup.zone=Configurer la zone +label.setup.network=Configurer le rseau +label.add.resources=Ajouter des resssources +label.launch=Dmarrer +label.set.up.zone.type=configurer le type de zone +message.please.select.a.configuration.for.your.zone=Slectionner une configuration pour la zone. +# message.desc.basic.zone=Provide a single network where each VM instance is assigned an IP directly from the network. Guest isolation can be provided through layer-3 means such as security groups (IP address source filtering). +label.basic=Basic +# message.desc.advanced.zone=For more sophisticated network topologies. This network model provides the most flexibility in defining guest networks and providing custom network offerings such as firewall, VPN, or load balancer support. +label.advanced=Avanc +# message.desc.zone=A zone is the largest organizational unit in CloudStack, and it typically corresponds to a single datacenter. Zones provide physical isolation and redundancy. A zone consists of one or more pods (each of which contains hosts and primary storage servers) and a secondary storage server which is shared by all pods in the zone. +label.physical.network=Rseau physique +label.public.traffic=Trafic public +label.guest.traffic=Trafic invit +label.storage.traffic=Trafic stockage +# message.setup.physical.network.during.zone.creation=When adding an advanced zone, you need to set up one or more physical networks. Each network corresponds to a NIC on the hypervisor. Each physical network can carry one or more types of traffic, with certain restrictions on how they may be combined.

Drag and drop one or more traffic types onto each physical network. +label.add.physical.network=Ajouter un rseau physique +label.traffic.types=Type de trafic +label.management=Management +label.guest=Invit +label.please.specify.netscaler.info=Renseigner les informations sur le Netscaler +# message.public.traffic.in.advanced.zone=Public traffic is generated when VMs in the cloud access the internet. Publicly-accessible IPs must be allocated for this purpose. End users can use the CloudStack UI to acquire these IPs to implement NAT between their guest network and their public network.

Provide at least one range of IP addresses for internet traffic. +# message.public.traffic.in.basic.zone=Public traffic is generated when VMs in the cloud access the Internet or provide services to clients over the Internet. Publicly accessible IPs must be allocated for this purpose. When a instance is created, an IP from this set of Public IPs will be allocated to the instance in addition to the guest IP address. Static 1-1 NAT will be set up automatically between the public IP and the guest IP. End users can also use the CloudStack UI to acquire additional IPs to implement static NAT between their instances and the public IP. +# message.add.pod.during.zone.creation=Each zone must contain in one or more pods, and we will add the first pod now. A pod contains hosts and primary storage servers, which you will add in a later step. First, configure a range of reserved IP addresses for CloudStack's internal management traffic. The reserved IP range must be unique for each zone in the cloud. +# message.guest.traffic.in.advanced.zone=Guest network traffic is communication between end-user virtual machines. Specify a range of VLAN IDs to carry guest traffic for each physical network. +# message.guest.traffic.in.basic.zone=Guest network traffic is communication between end-user virtual machines. Specify a range of IP addresses that CloudStack can assign to guest VMs. Make sure this range does not overlap the reserved system IP range. +# message.storage.traffic=Traffic between CloudStack's internal resources, including any components that communicate with the Management Server, such as hosts and CloudStack system VMs. Please configure storage traffic here. +# message.desc.cluster=Each pod must contain one or more clusters, and we will add the first cluster now. A cluster provides a way to group hosts. The hosts in a cluster all have identical hardware, run the same hypervisor, are on the same subnet, and access the same shared storage. Each cluster consists of one or more hosts and one or more primary storage servers. +# message.desc.host=Each cluster must contain at least one host (computer) for guest VMs to run on, and we will add the first host now. For a host to function in CloudStack, you must install hypervisor software on the host, assign an IP address to the host, and ensure the host is connected to the CloudStack management server.

Give the host's DNS or IP address, the user name (usually root) and password, and any labels you use to categorize hosts. +# message.desc.primary.storage=Each cluster must contain one or more primary storage servers, and we will add the first one now. Primary storage contains the disk volumes for all the VMs running on hosts in the cluster. Use any standards-compliant protocol that is supported by the underlying hypervisor. +# message.desc.secondary.storage=Each zone must have at least one NFS or secondary storage server, and we will add the first one now. Secondary storage stores VM templates, ISO images, and VM disk volume snapshots. This server must be available to all hosts in the zone.

Provide the IP address and exported path. +label.launch.zone=Dmarrer la zone +message.please.wait.while.zone.is.being.created=Patienter pendant la cration de la zone, cela peut prendre du temps... + +label.load.balancing=Load Balancing +label.static.nat.enabled=NAT statique activ +label.zones=Zones +label.view.more=Voir plus +label.number.of.zones=Nombre de zones +label.number.of.pods=Nombre de Pods +label.number.of.clusters=Nombre de clusters +label.number.of.hosts=Nombre de serveurs +label.total.hosts=Total serveurs +label.total.CPU=Capacit Totale en CPU +label.total.memory=Total mmoire +label.total.storage=Total stockage +label.purpose=Rle + + + + +label.action.migrate.router=Migration routeur +label.action.migrate.router.processing=Migration routeur en cours... +message.migrate.router.confirm=Confirmer la migration du routeur vers \: +label.migrate.router.to=Migrer le routeur vers + +label.action.migrate.systemvm=Migration VM systme +label.action.migrate.systemvm.processing=Migration VM systme en cours ... +message.migrate.systemvm.confirm=Confirmer la migration de la VM systme vers \: +label.migrate.systemvm.to=Miger la VM systme vers + + +mode=Mode +side.by.side=Cte cote +inline=Align + +extractable=Dcompressable + +label.ocfs2=OCFS2 + +label.action.edit.host=Modifier l'hte + +network.rate=Dbit Rseau + +ICMP.type=Type ICMP +ICMP.code=Code ICMP + +image.directory=Rpertoire d'images + +label.action.create.template.from.vm=Crer un modle depuis la VM +label.action.create.template.from.volume=Crer un modle depuis le volume + +message.vm.create.template.confirm=Crer un modle va redmarrer la VM automatiquement + +label.action.manage.cluster=Grer le Cluster +message.action.manage.cluster=Confirmez que vous voulez grer le cluster +label.action.manage.cluster.processing=Gestion du cluster... + +label.action.unmanage.cluster=Ne plus grer le Cluster +message.action.unmanage.cluster=Confirmez que vous ne voulez plus grer le cluster +label.action.unmanage.cluster.processing=Arrt de la gestion du Cluster + +label.allocation.state=Etat de l'allocation +managed.state=Etat de la gestion + +label.default.use=Utilisation par dfaut +label.host.tags=Labels Server + +label.cidr=CIDR +label.cidr.list=CIDR Source + +label.storage.tags=Etiquettes de stockage + +label.redundant.router=Routeur redondant +label.is.redundant.router=Redondant + +force.delete=Forcer la suppression +force.delete.domain.warning=Attention\: Choisir cette opion entrainera la suppression de tous les domaines issus et l'ensemble des comptes associes, ainsi que de leur ressources + +force.remove=Forcer la suppression +force.remove.host.warning=Attention\: Choisir cette option entrainera CloudStack arrter l'ensemble des machines virtuelles avant d'enlever l'hte du cluster + +force.stop=Forcer l'arrt +force.stop.instance.warning=Attention \: un arrt forc sur cette instance est l'option ultime. Cela peut engendrer des pertes de donnes et/ou un comportement inconsitent de votre instance. + +label.PreSetup=PreSetup +label.SR.name = Nom du point de montage +label.SharedMountPoint=Point de montage partag +label.clvm=CLVM +label.volgroup=Volume Group +label.VMFS.datastore=datastore VMFS + +label.network.device=Equipement Rseau +label.add.network.device=Ajouter un quipement rseau +label.network.device.type=Type d'quipement rseau +label.DHCP.server.type=Serveur DHCP +label.Pxe.server.type=Serveur PXE +label.PING.storage.IP=adresse PING (stockage) +label.PING.dir=rpertoire PING +label.TFTP.dir=rpertoire TFTP +label.PING.CIFS.username=utilisateur CIFS PING +label.PING.CIFS.password=mot de passe CIFS PING +label.CPU.cap=Utilisation maximum du CPU + + +label.action.enable.zone=Activer la zone +label.action.enable.zone.processing=Activation de la zone... +message.action.enable.zone=Confirmez que vous voulez activer cette zone +label.action.disable.zone=Dsactivation de la zone +label.action.disable.zone.processing=Désactivation de la zone... +message.action.disable.zone=Confirmez que vous voulez dsactiver cette zone + +label.action.enable.pod=Activer le Pod +label.action.enable.pod.processing=Activation du Pod... +message.action.enable.pod=Confirmez que vous souhaitez activer ce Pod +label.action.disable.pod=Dsactiver le Pod +label.action.disable.pod.processing=Dsactivation du Pod... +message.action.disable.pod=Confirmez que vous voulez dsactiver ce Pod + +label.action.enable.cluster=Activer le cluster +label.action.enable.cluster.processing=Activation du cluster... +message.action.enable.cluster=Confirmez que vous souhaitez activer ce cluster +label.action.disable.cluster=Dsactiver le cluster +label.action.disable.cluster.processing=Dsactivation du cluster... +message.action.disable.cluster=Confirmez que vous souhaitez dsactiver ce cluster + +label.account.id=ID du Compte +label.account.name=Nom du compte +label.account.specific=Spcifique au compte +label.account=Compte +label.accounts=Comptes +label.acquire.new.ip=Acqurir une nouvelle adresse IP +label.show.ingress.rule=Montrer la rgle Ingress +label.hide.ingress.rule=Cacher la rgle Ingress +label.action.attach.disk.processing=Attachement du Disque... +label.action.attach.disk=Attacher un disque +label.action.attach.iso.processing=Attachement de l'image ISO +label.action.attach.iso=Attacher une image ISO +label.action.cancel.maintenance.mode.processing=Annulation du mode maintenance... +label.action.cancel.maintenance.mode=Annuler le mode maintenance +label.action.change.password=Changer le mot de passe +label.action.change.service.processing=Changement de d'offre de service... +label.action.change.service=Changer d'offre de service +label.action.copy.ISO.processing=Copie de l'image ISO... +label.action.copy.ISO=Copier une image ISO +label.action.copy.template.processing=Copie du Modle... +label.action.copy.template=Copier un modle +label.action.create.template.processing=Cration du Modle... +label.action.create.template=Crer un modle +label.action.create.vm.processing=Cration de la VM.. +label.action.create.vm=Crer une VM +label.action.create.volume.processing=Cration du Volume... +label.action.create.volume=Crer un Volume +label.action.delete.IP.range.processing=Suppression de la plage IP... +label.action.delete.IP.range=Supprimer la plage IP +label.action.delete.ISO.processing=Suppression de l'image ISO... +label.action.delete.ISO=Supprimer l'image ISO +label.action.delete.account.processing=Suppression du compte... +label.action.delete.account=Supprimer un compte +label.action.delete.cluster.processing=Suppression du Cluster... +label.action.delete.cluster=Supprimer le Cluster +label.action.delete.disk.offering.processing=Suppression de l'offre Disque... +label.action.delete.disk.offering=Supprimer l'offre Disque + +label.action.update.resource.count=Mettre jour le compte d'utilisation des ressources +label.action.update.resource.count.processing=Mise jour du compteur... + +label.action.delete.domain=Supprimer le domaine +label.action.delete.domain.processing=Suppression du domaine... + +label.action.delete.firewall.processing=Suppression du Parefeu... +label.action.delete.firewall=Supprimer la rgle de firewall +label.action.delete.ingress.rule.processing=Suppression de la rgle Ingress.. +label.action.delete.ingress.rule=Supprimer la rgle Ingress +label.action.delete.load.balancer.processing=Suppression de l'quilibreur de charge... +label.action.delete.load.balancer=Supprimer la rgle de load balancer +label.action.edit.network.processing=Modification du Rseau... +label.action.edit.network=Modifier le rseau +label.action.delete.network.processing=Suppression du rseau... +label.action.delete.network=Supprimer le rseau +label.action.delete.pod.processing=Suppression du pod... +label.action.delete.pod=Supprimer le Pod +label.action.delete.primary.storage.processing=Suppression du stockage primaire... +label.action.delete.primary.storage=Supprimer le stockage primaire +label.action.delete.secondary.storage.processing=Suppression du stockage secondaire... +label.action.delete.secondary.storage=Supprimer le stockage secondaire +label.action.delete.security.group.processing=Suppression du groupe de scurit +label.action.delete.security.group=Supprimer le groupe de scurit +label.action.delete.service.offering.processing=Suppression de l'offre de service... +label.action.delete.service.offering=Supprimer l'offre de service +label.action.delete.snapshot.processing=Suppresison de l'instantan... +label.action.delete.snapshot=Supprimer l'instantan +label.action.delete.template.processing=Suppression du modle... +label.action.delete.template=Supprimer le modle +label.action.delete.user.processing=Suppression de l'utilisateur... +label.action.delete.user=Supprimer l'utilisateur +label.action.delete.volume.processing=Suppression du volume... +label.action.delete.volume=Supprimer le volume +label.action.delete.zone.processing=Suppression de la zone... +label.action.delete.zone=Supprimer la zone +label.action.destroy.instance.processing=Suppression de l'instance... +label.action.destroy.instance=Supprimer l'instance +label.action.destroy.systemvm.processing=Suppression de la VM Systme... +label.action.destroy.systemvm=Supprimer la VM Systme +label.action.detach.disk.processing=Dtachement du disque... +label.action.detach.disk=Dtacher le disque +label.action.detach.iso.processing=Dtachement de l'image ISO... +label.action.detach.iso=Dtacher l'image ISO +label.action.disable.account.processing=Dsactivation du compte... +label.action.disable.account=Dsactiver le compte +label.action.disable.static.NAT.processing=Dsactivation du NAT Statique... +label.action.disable.static.NAT=Dsactiver le NAT Statique +label.action.disable.user.processing=Dsactivation du l'utilisateur... +label.action.disable.user=Dsactiver l'utilisateur +label.action.download.ISO=Tlcharger une image ISO +label.action.download.template=Tlcharger un modle +label.action.download.volume.processing=Tlchargement du volume... +label.action.download.volume=Tlcharger un volume +label.action.edit.ISO=Modifier l'image ISO +label.action.edit.account=Modifier le Compte +label.action.edit.disk.offering=Modifier l'offre de disque +label.action.edit.domain=Modifier le domaine +label.action.edit.global.setting=Modifier la configuration globale +label.action.edit.instance=Modifier l'instancer +label.action.edit.network.offering=Modifier l'offre de service rseau +label.action.edit.pod=Modifier le pod +label.action.edit.primary.storage=Modifier le stockage primaire +label.action.edit.resource.limits=Modifier les limites de ressources +label.action.edit.service.offering=Modifier l'offre de service +label.action.edit.template=Modifier le modle +label.action.edit.user=Modifier l'utilisateur +label.action.edit.zone=Modifier la zone +label.action.enable.account.processing=Activation du compte... +label.action.enable.account=Activer le compte +label.action.enable.maintenance.mode.processing=Activation du mode maintenance... +label.action.enable.maintenance.mode=Activer le mode maintenance +label.action.enable.static.NAT.processing=Activation du NAT Statique... +label.action.enable.static.NAT=Activer le NAT Statique +label.action.enable.user.processing=Activation de l'utilisateur... +label.action.enable.user=Activer l'utilisateur +label.action.force.reconnect.processing=Reconnexion en cours... +label.action.force.reconnect=Forcer la reconnexion +label.action.generate.keys.processing=Gnration des cls... +label.action.generate.keys=Gnrer les cls +label.action.lock.account.processing=Blocage du compte... +label.action.lock.account=Bloquer le compte +label.action.migrate.instance=Migrer l'instance +label.action.migrate.instance.processing=Migration de l'instance... +label.action.reboot.instance.processing=Redmarrage de l'instance... +label.action.reboot.instance=Redmarrer l'instance +label.action.reboot.router.processing=Redmarrage du routeur... +label.action.reboot.router=Redmarrer le routeur +label.action.reboot.systemvm.processing=Redmarrage de la VM Systme... +label.action.reboot.systemvm=Redmarre la VM Systme +label.action.recurring.snapshot=Snapshots rcurrents +label.action.release.ip.processing=Libration de l'adresse IP... +label.action.release.ip=Librer l'adresse IP +label.action.remove.host.processing=Suppression de l'hte... +label.action.remove.host=Supprimer l'hte +label.action.reset.password.processing=Rinitialisation le mot de passe... +label.action.reset.password=Rinitialiser le mot de passe +label.action.resource.limits=Limites de ressources +label.action.restore.instance.processing=Restauration de l'instance... +label.action.restore.instance=Restaurer l'instance +label.action.start.instance.processing=Dmarrage de l'instance +label.action.start.instance=Dmarrer l'instance +label.action.start.router.processing=Dmarrage du routeur... +label.action.start.router=Dmarrer le routeur +label.action.start.systemvm.processing=Dmarrage de la VM systme +label.action.start.systemvm=Dmarrer la VM systme +label.action.stop.instance.processing=Arrt de l'Instance... +label.action.stop.instance=Arrter l'Instance +label.action.stop.router.processing=Arrt du routeur... +label.action.stop.router=Arrter le routeur +label.action.stop.systemvm.processing=Arrt de la VM systme... +label.action.stop.systemvm=Arrter la VM systme +label.action.take.snapshot.processing=Prise de l'instantan +label.action.take.snapshot=Prendre un instantan +label.action.update.OS.preference.processing=Mise jour des prfrences d'OS... +label.action.update.OS.preference=Mettre jour les prfrences d'OS +label.actions=Actions +label.active.sessions=Sessions actives +label.add.account=Ajouter un compte +label.add.by.cidr=Ajouter par CIDR +label.add.by.group=Ajouter par groupe +label.add.cluster=Ajouter un cluster +label.add.direct.iprange=Ajouter une plage d'adresse IP directe +label.add.disk.offering=Ajouter une offre disque +label.add.domain=Ajouter un domaine +label.add.firewall=Ajouter une rgle firewall +label.add.host=Ajouter un hte +label.add.ingress.rule=Ajouter une rgle Ingress +label.add.ip.range=Ajouter une plage IP +label.add.load.balancer=Ajouter un partageur de charge +label.add.more=Ajouter plus +label.add.network=Ajouter un rseau +label.add.pod=Ajouter un pod +label.add.primary.storage=Ajouter un stockage primaire +label.add.secondary.storage=Ajouter un stockage secondaire +label.add.security.group=Ajouter un groupe de scurit +label.add.service.offering=Ajouter un offre de service +label.add.template=Ajouter un modle +label.add.user=Ajouter un utilisateur +label.add.vlan=Ajouter un vlan +label.add.volume=Ajouter un volume +label.add.zone=Ajouter une zone +label.add=Ajouter +label.adding.cluster=Ajout du Cluster +label.adding.failed=Echec de l'ajout +label.adding.pod=Ajout du Pod +label.adding.processing=Ajout... +label.adding.succeeded=Ajout russi +label.adding.user=Ajout de l'utilisateur +label.adding.zone=Ajout de la zone +label.adding=Ajout +label.additional.networks=Rseaux additionnels +label.admin.accounts=Comptes Administrateur +label.admin=Administrateur +label.advanced.mode=Mode avanc +label.advanced.search=Recherche avance +label.advanced=Avanc +label.alert=Alerte +label.algorithm=Algorithme +label.allocated=Allou +label.api.key=Cl d'API +label.assign.to.load.balancer=Assigner l'instance au partageur de charge +label.assign=Assigner +label.associated.network.id=ID du rseau associ +label.attached.iso=Image ISO attache +label.availability.zone=Zone de disponibilit +label.availability=Disponibilit +label.available.public.ips=Adresses IP publiques disponibles +label.available=Disponible +label.back=Retour +label.basic.mode=Mode basique +label.bootable=Bootable +label.broadcast.domain.type=Type de domaine de broadcast +label.by.account=Par compte +label.by.availability=Par disponibilit +label.by.domain=Par domaine +label.by.end.date=Par date de fin +label.by.level=Par niveau +label.by.pod=Par Pod +label.by.role=Par role +label.by.start.date=Par date de dbut +label.by.state=Par tat +label.by.traffic.type=Par type de traffic +label.by.type.id=Par type d'ID +label.by.type=Par type +label.by.zone=Par zone +label.bytes.received=Octets reus +label.bytes.sent=Octets envoys +label.cancel=Annuler +label.certificate=Certificat +label.privatekey=Cl prive PKCS\#8 +label.domain.suffix=Suffixe de domaine DNS (i.e., xyz.com) +label.character=Caractre +label.cidr.account=CIDR ou Compte/Groupe de scurit +label.close=Fermer +label.cloud.console=Console de gestion du cloud +label.cloud.managed=Gr par Cloud.com +label.cluster.type=Type de Cluster +label.cluster=Cluster +label.code=Code +label.confirmation=Confirmation +label.cpu.allocated.for.VMs=CPU allou aux VMs +label.cpu.allocated=CPU allou +label.cpu.utilized=CPU utilis +label.cpu=CPU +label.created=Cr +label.cross.zones=Multi Zones +label.custom.disk.size=Taille de disque personnalise +label.daily=Quotidien +label.data.disk.offering=Offre de disque de donnes +label.date=Date +label.day.of.month=Jour du mois +label.day.of.week=Jour de la semaine +label.delete=Supprimer +label.deleting.failed=Suppression choue +label.deleting.processing=Suppression... +label.description=Description +label.detaching.disk=Dtacher le disque +label.details=Details +label.device.id=ID du priphrique +label.disabled=Dsactiv +label.disabling.vpn.access=Dsactiver l'accs VPN +label.disk.allocated=Disque Allou +label.disk.offering=Offre de Disque +label.disk.size.gb=Taille du disque (en Go) +label.disk.size=Taille du disque +label.disk.total=Espace disque total +label.disk.volume=Volume disque +label.display.text=Texte affich +label.dns.1=DNS1 +label.dns.2=DNS2 +label.domain.admin=Administrateur du domaine +label.domain.id=ID du domaine +label.domain.name=Nom de domaine +label.domain=Domaine +label.double.quotes.are.not.allowed=Les guillemets ne sont pas autoriss +label.download.progress=Progression du tlchargement +label.edit=Modifier +label.email=Email +label.enabling.vpn.access=Activation de l'accs VPN +label.enabling.vpn=Activation du VPN +label.end.port=Port de fin +label.endpoint.or.operation=Terminaison ou Opration +label.error.code=Code d'erreur +label.error=Erreur +label.esx.host=Hte ESX/ESXi +label.example=Exemple +label.failed=Echou +label.featured=Sponsoris +label.firewall=Parefeu +label.first.name=Prnom +label.format=Format +label.friday=Vendredi +label.full=Complet +label.gateway=Passerelle +label.general.alerts=Alertes gnrales +label.generating.url=Gnration de l'URL +label.go.step.2=Aller l'tape 2 +label.go.step.3=Aller l'tape 3 +label.go.step.4=Aller l'tape 4 +label.go.step.5=Aller l'tape 5 +label.group.optional=Groupe (optionnel) +label.group=Groupe +label.guest.cidr=CIDR invits +label.guest.gateway=Passerelle pour les invits +label.guest.ip.range=Plage d'adresses IP des invits +label.guest.ip=Adresse IP des invits +label.guest.netmask=Masque de rseau des invits +label.ha.enabled=Haute disponibilit active +label.help=Aide +label.host.alerts=Alertes des htes +label.host.name=Nom d'hte +label.host=Serveur +label.hosts=Serveurs +label.hourly=A l'heure +label.hypervisor.type=Type d'hyperviseur +label.hypervisor=Hyperviseur +label.id=ID +label.info=Information +label.ingress.rule=Rgle Ingress +label.initiated.by=Initi par +label.instance.limits=Limites des instances +label.instance.name=Nom de lnstance +label.instance=Instance +label.instances=Instances +label.internal.dns.1=DNS interne 1 +label.internal.dns.2=DNS interne 2 +label.interval.type=Type d'ntervalle +label.invalid.integer=Nombre entier invalide +label.invalid.number=Nombre invalide +label.ip.address=Adresse IP +label.ip.allocations=Allocations de IPs +label.ip.limits=Limite de IPs publiques +label.ip.or.fqdn=IP ou FQDN +label.ip.range=Plage IP +label.ip=IP +label.ips=IPs +label.is.default=Est par dfaut +label.is.shared=Est partag +label.is.system=Type systme +label.iscsi=iSCSI +label.iso.boot=Dmarrage par ISO +label.iso=ISO +label.isolation.mode=Mode d'isolation +label.keep=Conserver +label.lang.chinese=Chinois (simplifi) +label.lang.english=Anglais +label.lang.japanese=Japonais +label.lang.spanish=Espagnol +label.last.disconnected=Dernire Dconnexion +label.last.name=Nom de famille +label.level=Niveau +label.linklocal.ip=Adresse IP de lien local +label.load.balancer=Partageur de charge +label.loading=Chargement en cours +label.local=Local +# label.local.storage.enabled=Local storage enabled +label.login=Connexion +label.logout=Dconnexion +label.lun=LUN +label.manage=Gr +label.maximum=Maximum +label.memory.allocated=Mmoire alloue +label.memory.total=Mmoire totale +label.memory.used=Mmoire utilise +label.memory=Mmoire (en MB) +label.menu.accounts=Comptes +label.menu.alerts=Alertes +label.menu.all.accounts=Tout les comptes +label.menu.all.instances=Toutes les instances +label.menu.community.isos=ISO de la communaut +label.menu.community.templates=Modles de la communaut +label.menu.configuration=Configuration +label.menu.dashboard=Tableau de bord +label.menu.destroyed.instances=Instances dtruites +label.menu.disk.offerings=Offres de disque +label.menu.domains=Domaines +label.menu.events=Evnements +label.menu.featured.isos=ISOs Sponsorises +label.menu.featured.templates=Modles sponsoriss +label.menu.global.settings=Paramtres globaux +label.menu.instances=Instances +label.menu.ipaddresses=Adresses IP +label.menu.isos=ISOs +label.menu.my.accounts=Mes comptes +label.menu.my.instances=Mes instances +label.menu.my.isos=Mes ISOs +label.menu.my.templates=Mes modles +label.menu.network.offerings=Offres de Service Rseau +label.menu.network=Rseau +label.menu.physical.resources=Ressources physiques +label.menu.running.instances=Instances actives +label.menu.security.groups=Groupes de scurit +label.menu.service.offerings=Offres de Service +label.menu.snapshots=Instantans +label.menu.stopped.instances=Instances Arrtes +label.menu.storage=Stockage +label.menu.system.vms=\ VMs Systmes +label.menu.system=Systme +label.menu.templates=Modles +label.menu.virtual.appliances=Appliances Virtuelles +label.menu.virtual.resources=Ressources Virtuelles +label.menu.volumes=Volumes +label.migrate.instance.to=Migrer l'instance vers +label.minimum=Minimum +label.minute.past.hour=minute(s) +label.monday=Lundi +label.monthly=Mensuel +label.more.templates=Plus de modles +label.my.account=Mon compte +label.name.optional=Nom (optionnel) +label.name=Nom +label.netmask=Masque de rseau +label.network.desc=Description rseau +label.network.domain=Nom de domaine +label.network.id=ID rseau +label.network.name=Nom du rseau +label.network.offering.display.text=Texte affich d'Offre de Rseau +label.network.offering.id=ID de l'Offre de Service Rseau +label.network.offering.name=Nom de l'Offre de Service Rseau +label.network.offering=Offre de Service Rseau +label.network.rate=Dbit rseau +label.network.read=Lecture rseau +label.network.type=Type de rseau +label.network.write=criture rseau +label.network=Rseau +label.new.password=Nouveau mot de passe +label.next=Suivant +label.nfs.server=Serveur NFS +label.nfs.storage=Stockage NFS +label.nfs=NFS +label.nics=Cartes NIC +label.no.actions=Aucune action disponibles +label.no.alerts=Aucune alerte rcentes +label.no.errors=Aucune erreur rcentes +label.no.isos=Aucun ISOs disponibles +label.no.items=Aucun lment disponibles +label.no.security.groups=Aucun groupe de scurit disponibles +label.no.thanks=Non merci +label.no=Non +label.none=Aucun +label.not.found=Introuvable +label.num.cpu.cores=Nombre de c\u0153urs de processeur +label.numretries=Nombre de tentatives +label.offer.ha=Offrir la haute disponibilit +label.optional=Facultatif +label.os.preference=Prfrence du OS +label.os.type=Type du OS +label.owned.public.ips=Addresses IP Publique dtenues +label.owner.account=Compte propritaire +label.owner.domain=Propritaire du domaine +label.parent.domain=Domaine Parent +label.password.enabled=Mot de passe activ +label.password=Mot de passe +label.path=Chemin +label.please.wait=Patientez s'il vous plait +label.pod=Pod +label.port.forwarding=Redirection de port +label.port.range=Plage de ports +label.prev=Prcdent +label.primary.allocated=Stockage primaire allou +label.primary.network=Rseau primaire +label.primary.storage=Stockage primaire +label.primary.used=Stockage primaire utilis +label.private.interface=Interface prive +label.private.ip.range=Plage d'adresses IP Prives +label.private.ip=Adresse IP Prive +label.private.ips=Adresses IP Prives +label.private.port=Port priv +label.private.zone=Zone Prive +label.protocol=Protocole +label.public.interface=Interface publique +label.public.ip=Adresse IP publique +label.public.ips=Adresses IP publiques +label.public.port=Port public +label.public.zone=Zone publique +label.public=Publique +label.recent.errors=Erreurs rcentes +label.refresh=Actualiser +label.related=Connexes +label.remove.from.load.balancer=Supprimer l'instance du partageur de charge +label.removing.user=Retrait de l'utilisateur +label.required=Requis +label.reserved.system.ip=Adresse IP Systme rserv +label.resource.limits=Limite des ressources +label.resource=Ressource +label.resources=Ressources +label.role=Rle +label.root.disk.offering=Offre de disque racine +label.running.vms=VMs actives +label.saturday=Samedi +label.save=Sauvegarder +label.saving.processing=Sauvegarde en cours.... +label.scope=Porte +label.search=Rechercher +label.secondary.storage=Stockage secondaire +label.secondary.used=Stockage secondaire utilis +label.secret.key=cl prive +label.security.group.name=Nom du groupe de scurit +label.security.group=Groupe de scurit +label.security.groups.enabled=Groupes de scurit Activs +label.security.groups=Groupes de scurit +label.sent=Envoyer +label.server=Serveur +label.service.offering=Offre de Service +label.system.service.offering=Offre de Service Systme +label.session.expired=Session expir +label.shared=En partage +label.size=Taille +label.snapshot.limits=Limite d'instantans +label.snapshot.name=Nom de l'instantan +label.snapshot.s=Instantan(s) +label.snapshot.schedule=Configurer un snapshot rcurrent +label.snapshot=Instantan +label.snapshots=Instantans +label.source.nat=NAT Source +label.specify.vlan=Prcisez le VLAN +label.start.port=Port de +label.state=tat +label.static.nat.to=NAT Static vers +label.static.nat=NAT Static +label.statistics=Statistiques +label.status=Statut +label.step.1.title=Etape 1 \: Slectionnez un modle +label.step.1=tape 1 +label.step.2.title=Etape 2\: Offre de Service +label.step.2=tape 2 +label.step.3.title=Etape 3\: Slectionnez une offre de service +label.step.3=tape 3 +label.step.4.title=Etape 4\: Rseau +label.step.4=tape 4 +label.step.5.title=Etape 5\: Vrification +label.step.5=tape 5 +label.stopped.vms=VMs arrts +label.storage.type=Type de stockage +label.storage=Stockage +label.submit=Envoyer +label.submitted.by=[Soumis par\: ] +label.succeeded=Russi +label.sunday=Dimanche +label.system.capacity=Capacit systme +label.system.vm.type=Type de VM systme +label.system.vm=VM Systme +label.system.vms=\ VMs systmes +label.tagged=Tagg +label.tags=Tags +label.target.iqn=IQN de la Cible +label.template.limits=Limites des modles +label.template=Modle +label.theme.default=Thme par dfaut +label.theme.grey=Personnalis - Gris +label.theme.lightblue=Personnalis - Blue clair +label.thursday=Jeudi +label.time.zone=Fuseau horaire +label.time=Temps +label.timeout.in.second = Timeout (secondes) +label.timezone=Fuseau horaire +label.total.cpu=Capacit Totale en CPU +label.total.vms=Nombre total de VMs +label.traffic.type=Type de Traffic +label.tuesday=Mardi +label.type.id=ID du Type +label.type=Type +label.unavailable=Indisponible +label.unlimited=Illimit +label.untagged=Non Tagg +label.update.ssl.cert=Mettre jour le certificate SSL +label.update.ssl=Mettre jour le certificate SSL +label.updating=Mise jour +label.url=URL +label.usage.interface=Interface d'Usage +label.used=Utilis +label.user=Utilisateur +label.username=Nom d'Utilisateur +label.users=Utilisateurs +label.value=Valeur +label.vcenter.cluster=Cluster vCenter +label.vcenter.datacenter=Datacenter vCenter +label.vcenter.datastore=Datastore vCenter +label.vcenter.host=Hte Vcenter +label.vcenter.password=Mot de passe vCenter +label.vcenter.username=Nom d'utilisateur vCenter +label.version=Version +label.virtual.appliance=Appliance Virtuelle +label.virtual.appliances=Appliances Virtuelles +label.virtual.network=Rseau virtuel +label.vlan.id=ID du VLAN +label.vlan.range=Plage du VLAN +label.vm.add=Ajouter une instance +label.vm.destroy=Dtruire +label.vm.reboot=Redmarrer +label.vm.start=Dmarrer +label.vm.stop=Arrtez +label.vmfs=VMFS +label.vms=VMs +label.volume.limits=Limites des volumes +label.volume.name=Nom du volume +label.volume=Volume +label.volumes=Volumes +label.vsphere.managed=Gre par vSphere +label.waiting=En attente +label.warn=Avertir +label.wednesday=Mercredi +label.weekly=Hebdomadaire +label.welcome.cloud.console=Bienvenue dans la console de gestion +label.welcome=Bienvenue +label.yes=Oui +label.zone.id=ID de la zone +label.zone.step.1.title=Etape 1\: Slectionnez un rseau +label.zone.step.2.title=Etape 2\: Ajoutez une zone +label.zone.step.3.title=Etape 3\: Ajoutez un Pod +label.zone.step.4.title=Etape 4\: Ajoutez une plage d'adresses IP +label.zone.wide=Transverse la zone +label.zone=Zone + +#Messages +message.acquire.public.ip=Slectionnez la zone dans laquelle vous voulez acqurir votre nouvelle adresse IP. +message.action.cancel.maintenance.mode=Confirmer que vous souhaitez annuler cette maintenance. +message.action.cancel.maintenance=Votre hte a t annule de la maintenance. Ce processus peut prendre jusqu' plusieurs minutes. +message.action.delete.ISO.for.all.zones=L'ISO est utilis par toutes les zones. S'il vous plat confirmer que vous voulez le supprimer de toutes les zones. +message.action.delete.ISO=Confirmer que vous souhaitez supprimer cette ISO. +message.action.delete.cluster=Confirmer que vous voulez supprimer ce cluster. +message.action.delete.disk.offering=Confirmer que vous souhaitez supprimer cette offre de disque. +message.action.delete.domain=Confirmer que vous voulez supprimer ce domaine. +message.action.delete.external.firewall=Confirmer que vous souhaitez supprimer ce pare-feu externe. Attention\: Si vous prvoyez de rajouter le mme pare-feu externe de nouveau, vous devez rinitialiser les donnes d'utilisation sur l'appareil. +message.action.delete.external.load.balancer=Confirmez que vous souhaitez supprimer ce partageur de charge externe. Attention \: Si vous pensez ajouter le mme partageur de charge plus tard, vous devez remettre zro les statistiques d'usage de cet quipement. +message.action.delete.ingress.rule=Confirmez que vous souhaitez supprimer cette rgle Ingress +message.action.delete.network=Confirmer que vous voulez supprimer ce rseau. +message.action.delete.pod=Confirmez que vous souhaitez supprimer ce pod. +message.action.delete.primary.storage=Confirmer que vous voulez supprimer ce stockage primaire. +message.action.delete.secondary.storage=Confirmez que vous souhaitez supprimer ce stockage secondaire. +message.action.delete.security.group=Confirmez que vous souhaitez supprimer ce groupe de scurit. +message.action.delete.service.offering=Confirmez que vous souhaitez supprimer cette offre de service. +message.action.delete.snapshot=Confirmez que vous souhaitez supprimer cet instantan +message.action.delete.template.for.all.zones=Ce modle est utilis par toutes les zones. Confirmez que vous souhaitez le supprimer de toutes les zones. +message.action.delete.template=Confirmez que vous souhaitez supprimer ce modle. +message.action.delete.volume=Confirmez que vous souhaitez supprimer ce volume. +message.action.delete.zone=Confirmez que vous souhaitez supprimer cette zone. +message.action.destroy.instance=Confirmez que vous souhaitez supprimer cette instance. +message.action.destroy.systemvm=Confirmez que vous souhaitez supprimer cette VM Systme. +message.action.disable.static.NAT=Confirmez que vous souhaitez dsactiver le NAT statique. +message.action.enable.maintenance=Votre hte a t mis en mode maintenance avec succs. Ce processus peut durer plusieurs minutes ou plus suivant le nombre de VMs actives sur cet hte. +message.action.force.reconnect=Votre hte a t forc se reconnecter avec succs. Ce processus peut prendre jusqu' plusieurs minutes. +message.action.host.enable.maintenance.mode=Activer le mode maintenance va causer la migration chaud de l'ensemble des instances de cet hte sur les autres htes disponibles. +message.action.instance.reset.password=Confirmer le changement du mot de passe ROOT pour cette machine virtuelle. +message.action.primarystorage.enable.maintenance.mode=Attention \: placer ce stockage primaire en mode maintenance que l'ensemble des VMs utilisant des volumes sur ce stockage. Souhaitez vous continuer ? +message.action.reboot.instance=Confirmez que vous souhaitez redmarrer cette instance. +message.action.reboot.systemvm=Confirmez que vous souhaitez redmarrer cette VM Systme +message.action.release.ip=Confirmez que vous souhaitez librer cette IP. +message.action.remove.host=Supprimer le dernier/seul hte dans le cluster et le rinstaller va supprimer l'environnement/la base de donnes sur l'hte et rendre les VMs invites inutilisables. +message.action.restore.instance=Confirmez que vous souhaitez restaurer cette instance. +message.action.start.instance=Confirmez que vous souhaitez dmarrer cette instance. +message.action.start.router=Confirmez que vous souhaitez dmarrer ce routeur. +message.action.start.systemvm=Confirmez que vous souhaitez redmarrer cette VM systme. +message.action.stop.instance=Confirmez que vous souhaitez arrter cette instance. +message.action.stop.systemvm=Confirmez que vous souhaitez arrter cette VM. +message.action.take.snapshot=Confirmer la prise d'un snapshot pour ce volume. +message.add.cluster.zone=Ajouter un cluster d'hyperviseurs gr pour cette zone +message.add.cluster=Ajouter un cluster d'hyperviseurs gr pour cette zone , pod +message.add.disk.offering=Renseignez les paramtres suivants pour ajouter un offre de service de disques +message.add.firewall=Ajouter un parefeu cette zone +message.add.host=Renseignez les paramtres suivant pour ajouter un hte +message.add.ip.range.direct.network=Ajouter une plage IP au rseau direct dans la zone +message.add.ip.range.to.pod=

Ajouter une plage IP pour le pod\:

+message.add.ip.range=Ajouter une plage IP pour le rseau publique dans la zone +message.add.load.balancer=Ajouter un partageur de charge la zone +message.add.network=Ajouter un nouveau rseau la zone\: +message.add.pod=Ajouter un nouveau pod la zone +message.add.primary.storage=Ajouter un nouveau stockage primaire la zone , pod +message.add.primary=Renseignez les paramtres suivants pour ajouter un sotckage primaire +message.add.secondary.storage=Ajouter un nouveau stockage pour la zone +message.add.service.offering=Renseigner les informations suivantes pour ajouter une nouvelle offre de service computing. +message.add.template=Renseignez les informations suivantes pour crer votre nouveau modle +message.add.volume=Renseignez les informations suivantes pour ajouter un nouveau volume +message.additional.networks.desc=Slectionnez le(s) rseau(x) additionnel(s) au(x)quel(s) sera connecte votre instance. +message.advanced.mode.desc=Choisissez ce modle de rseau si vous souhaitez bnficier du support des VLANs. Ce mode de rseau donne le plus de flexibilit aux administrateurs pour fournir des offres de service rseau personnalises comme fournir des parefeux, vpn, partageurs de charge ou galement activer des rseaux virtuels ou directs. +message.advanced.security.group=Choisissez ceci si vous souhaitez utiliser les groupes de scurit pour fournir l'isolation des VMs invites. +message.advanced.virtual=Choisissez ceci si vous souhaitez utiliser des VLANs pour fournir l'isolation des VMs invites. +message.allow.vpn.access=Entrez un nom d'utilisateur et un mot de passe pour l'utilisateur que vous souhaitez autoris utiliser l'accs VPN. +message.attach.iso.confirm=Confirmez que vous souhaitez attacher l'image ISO cette instance. +message.attach.volume=Renseignez les donnes suivante pour attacher un nouveau volume. Si vous attachez un volume disque une machine virtuelle sous Windows, vous aurez besoin de redmarrer l'instance pour voir le nouveau disque. +message.basic.mode.desc=Choisissez ce modle de rseau si vous *ne voulez pas* activer le support des VLANs. Toutes les instances cres avec ce modle de rseau se verront assignes une adresse IP et les groupes de scurit seront utiliss pour fournir l'isolation entre les VMs.\n +message.change.offering.confirm=Confirmez que vous souhaitez changer l'offre de service de cette instance. +message.copy.iso.confirm=Confirmez que vous souhaitez copier votre image ISO vers +message.copy.template=Copier le modle XXX de la zone vers +message.create.template.vm=Crer la VM depuis le modle +message.create.template.volume=Renseignez les informations suivantes avec de crer un modle partir de votre volume de disque\:. La cration du modle peut prendre plusieurs minutes suivant la taille du volume. +message.delete.account=Confirmez que vous souhaitez supprimer ce compte. +message.detach.iso.confirm=Confirmez que vous souhaitez dtacher l'image ISO de cette instance. +# message.disable.account=Please confirm that you want to disable this account. By disabling the account, all users for this account will no longer have access to their cloud resources. All running virtual machines will be immediately shut down. +message.disable.vpn.access=Confirmez que vous souhaitez dsactiver l'accs VPN. +message.download.ISO=Cliquer le lien 00000 pour tlcharger une image ISO +message.download.template=Cliquer le lien 00000 pour tlcharger une template +message.download.volume=Cliquez sur 00000 pour tlcharger le volume +message.edit.confirm=Confirmer les changement avant de cliquer sur "Enregistrer". +message.edit.limits=Renseignez les limites pour les ressources suivantes. "-1" indique qu'il n'y a pas de limites pour la cration de ressources. +message.enable.account=Confirmez que vous souhaitez activer ce compte. +message.enable.vpn.access=Le VPN est dsactiv pour cette adresse IP. Voulez vous activer l'accs VPN ? +message.enabled.vpn.ip.sec=Votre cl partage IPSec est +message.enabled.vpn=Votre accs VPN est activ et peut tre accd par l'IP +message.launch.vm.on.private.network=Souhaitez vous dmarrer cette instance sur votre propre rseau priv ? +message.lock.account=Confirmez que vous souhaitez verrouiller ce compte. En le verrouillant, les utilisateurs de ce compte ne seront plus capable de grer leurs ressources. Les ressources existantes resteront toutefois accessibles. +message.migrate.instance.confirm=Confirmez l'hte vers lequel vous souhaitez migrer cette instance +message.new.user=Renseigner les informations suivantes pour ajouter un nouveau compte utilisateur +message.no.network.support.configuration.not.true=Il n'y a pas de zone avec la fonction groupe de scurit active. Ds lors, pas de fonction rseau supplmentaires disponibles. Continuer l'tape 5. +message.no.network.support=Slectionnez l'hyperviseur. vSphere, n'a pas de fonctionnalits supplmentaires pour le rseau. Continuez l'tape 5. +message.number.clusters=

\# of Clusters

+message.number.hosts=

\# of Htes

+message.number.pods=

\# of Pods

+message.number.storage=

\# of Volumes de Stockage Primaire

+message.number.zones=

\# of Zones

+message.remove.vpn.access=Confirmez que vous souhaitez supprimer l'accs VPN l'utilisateur suivant. +message.restart.mgmt.server=Redmarrez votre(vos) serveur(s) de management pour appliquer les nouveaux paramtres. +message.restart.mgmt.usage.server=Redmarrer le ou les management server et usage server pour que les nouveaux paramtres soient pris en compte. +message.security.group.usage=(Utilisez Ctrl-clic pour slctionner les groupes de scurit viss) +message.snapshot.schedule=Vous pouvez mettre en place les politiques de gnration d'instantans en slectionnant les options disponibles ci-dessous et en appliquant votre politique. +message.step.1.continue=Slectionnez un modle ou une image ISO pour continuer +message.step.1.desc=Slectionnez un template pour votre nouvelle instance virtuelle. Vous pouvez galement choisir un modle vierge sur lequel une image ISO pourra tre install. +message.step.2.continue=Slectionnez une offre de service pour continuer +message.step.2.desc= +message.step.3.continue=Slectionnez un offre de service de disque pour continuer +message.step.3.desc= +message.step.4.continue=Slectionnez au moins un rseau pour continuer +message.step.4.desc=Slectionnez le rseau principal auquel votre instance va tre connect. +message.update.os.preference=Choisissez votre OS prfr pour cet hte. Toutes les instances avec des prfrences similaires seront d'abord alloues cet hte avant d'en choisir un autre. +message.update.ssl=Soumettez un nouveau certificat SSL compatible X.509 qui sera mis jour sur l'ensemble de instance de proxy console. +message.virtual.network.desc=Un rseau virtuel ddi pour votre compte. Ce domaine de broadcast est contenu dans un VLAN et l'ensemble de accs rseau publique sont routs par un routeur virtuel. +message.volume.create.template.confirm=Confirmez que vous souhaitez crer un modle pour ce disque. La cration peut prendre plusieurs minutes, voire plus, selon la taille du volume. +message.zone.step.1.desc=Slectionnez un modle de rseau pour votre zone. +message.zone.step.2.desc=Renseigner les informations suivantes pour ajouter une nouvelle zone +message.zone.step.3.desc=Renseigner les informations suivantes pour ajouter un nouveau pod +message.apply.snapshot.policy=Vous avez mis jour votre politique d'instantans avec succs. +message.disable.snapshot.policy=Vous avez dsactiv votre politique de snapshots avec succs. +message.action.change.service.warning.for.instance=Votre instance doit tre arrte avant d'essayer de changer son offre de service. +message.action.change.service.warning.for.router=Votre routeur doit tre arrt avant d'essayer de changer son offre de service. +message.action.reset.password.warning=Votre instance doit tre arrte avant d'essayer de changer son mot de passe. +message.action.reset.password.off=Votre instance ne supporte pas pour le moment cette fonctionnalit. + +#Errors +error.login=Votre nom d'utilisateur /mot de passe ne correspond pas nos donnes. +error.menu.select=Echec de l'action car il n'y a aucun lment slectionn. +error.mgmt.server.inaccessible=Le serveur de management est indisponible. Essayez plus tard. +error.session.expired=Votre session a expir. +error.unresolved.internet.name=Votre nom internet ne peut pas tre rsolu. diff --git a/client/WEB-INF/classes/resources/messages_pt_BR.properties b/client/WEB-INF/classes/resources/messages_pt_BR.properties new file mode 100644 index 00000000000..2b6a5d3ce45 --- /dev/null +++ b/client/WEB-INF/classes/resources/messages_pt_BR.properties @@ -0,0 +1,1514 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + + +#new labels (begin) ********************************************************************************************** +# label.isolation.uri=Isolation URI +# label.broadcast.uri=Broadcast URI +#new labels (end) ************************************************************************************************ + + +#modified labels (begin) ***************************************************************************************** +# message.zoneWizard.enable.local.storage=WARNING\: If you enable local storage for this zone, you must do the following, depending on where you would like your system VMs to launch\:

1. If system VMs need to be launched in primary storage, primary storage needs to be added to the zone after creation. You must also start the zone in a disabled state.

2. If system VMs need to be launched in local storage, system.vm.use.local.storage needs to be set to true before you enable the zone.


Would you like to continue? +#modified labels (end) ******************************************************************************************* + +# label.configure.network.ACLs=Configure Network ACLs +# label.network.ACLs=Network ACLs +# label.add.network.ACL=Add network ACL +# label.private.Gateway=Private Gateway +# label.VPC.router.details=VPC router details +# label.VMs.in.tier=VMs in tier +# label.local.storage.enabled=Local storage enabled +# label.tier.details=Tier details +# label.edit.tags=Edit tags +label.action.enable.physical.network=Habilitar rede fsica +label.action.disable.physical.network=Desabilitar rede fsica +message.action.enable.physical.network=Por favor confirme que voc deseja habilitar esta rede fsica. +message.action.disable.physical.network=Por favor confirme que voc deseja desabilitar esta rede fsica. + +# label.select.tier=Select Tier +# label.add.ACL=Add ACL +# label.remove.ACL=Remove ACL +# label.tier=Tier +# label.network.ACL=Network ACL +# label.network.ACL.total=Network ACL Total +# label.add.new.gateway=Add new gateway +# message.add.new.gateway.to.vpc=Please specify the information to add a new gateway to this VPC. +# label.delete.gateway=delete gateway +# message.delete.gateway=Please confirm you want to delete the gateway +# label.CIDR.of.destination.network=CIDR of destination network +# label.add.route=Add route +# label.add.static.route=Add static route +# label.remove.static.route=Remove static route +# label.site.to.site.VPN=site-to-site VPN +# label.add.VPN.gateway=Add VPN Gateway +# message.add.VPN.gateway=Please confirm that you want to add a VPN Gateway +# label.VPN.gateway=VPN Gateway +# label.delete.VPN.gateway=delete VPN Gateway +# message.delete.VPN.gateway=Please confirm that you want to delete this VPN Gateway +# label.VPN.connection=VPN Connection +# label.IPsec.preshared.key=IPsec Preshared-Key +# label.IKE.policy=IKE policy +# label.ESP.policy=ESP policy +# label.create.VPN.connection=Create VPN Connection +# label.VPN.customer.gateway=VPN Customer Gateway +# label.CIDR.list=CIDR list +# label.IKE.lifetime=IKE Lifetime (second) +# label.ESP.lifetime=ESP Lifetime(second) +# label.dead.peer.detection=Dead Peer Detection +# label.reset.VPN.connection=Reset VPN connection +# message.reset.VPN.connection=Please confirm that you want to reset VPN connection +# label.delete.VPN.connection=delete VPN connection +# message.delete.VPN.connection=Please confirm that you want to delete VPN connection +# label.add.new.tier=Add new tier +# label.add.VM.to.tier=Add VM to tier +# label.remove.tier=Remove tier + +# label.local.storage.enabled=Local storage enabled +# label.associated.network=Associated Network +# label.add.port.forwarding.rule=Add port forwarding rule +# label.dns=DNS + +# label.vpc=VPC +# label.vpc.id=VPC ID +# label.tier=Tier +# label.add.vpc=Add VPC +# label.super.cidr.for.guest.networks=Super CIDR for Guest Networks +# label.DNS.domain.for.guest.networks=DNS domain for Guest Networks +# label.configure.vpc=Configure VPC +# label.edit.vpc=Edit VPC +# label.restart.vpc=restart VPC +# message.restart.vpc=Please confirm that you want to restart the VPC +# label.remove.vpc=remove VPC +# message.remove.vpc=Please confirm that you want to remove the VPC +# label.vpn.customer.gateway=VPN Customer Gateway +# label.add.vpn.customer.gateway=Add VPN Customer Gateway +# label.IKE.encryption=IKE Encryption +# label.IKE.hash=IKE Hash +# label.IKE.DH=IKE DH +# label.ESP.encryption=ESP Encryption +# label.ESP.hash=ESP Hash +# label.perfect.forward.secrecy=Perfect Forward Secrecy +# label.IKE.lifetime=IKE Lifetime (second) +# label.ESP.lifetime=ESP Lifetime(second) +# label.dead.peer.detection=Dead Peer Detection +# label.delete.VPN.customer.gateway=delete VPN Customer Gateway +# message.delete.VPN.customer.gateway=Please confirm that you want to delete this VPN Customer Gateway + +label.network.domain.text=Texto do domnio de rede +label.memory.mb=Memória +label.cpu.mhz=CPU (em MHz) + +message.action.remove.host=Remover o único/último host do cluster e reinstalar o host irá provocar a perda do ambiente/banco do host tornando os Cloud Servers inutilizáveis. + +message.action.reboot.router=Confirme que você deseja reiniciar este roteador. +message.action.stop.router=Confirme que você deseja parar este roteador. +message.restart.network=Por favor confirme que voc deseja reiniciar a rede + + +label.ipaddress=Endereço IP +label.vcdcname=Nome do vCenter DC +label.vcipaddress=Endereo IP do vCenter +label.vsmctrlvlanid=Control VLAN ID +label.vsmpktvlanid=Packet VLAN ID +label.vsmstoragevlanid=Storage VLAN ID +label.nexusVswitch=Nexus Vswitch +label.action.delete.nexusVswitch=Remover NexusVswitch +label.action.enable.nexusVswitch=Habilitar NexusVswitch +label.action.disable.nexusVswitch=Desabilitar NexusVswitch +label.action.list.nexusVswitch=Listar NexusVswitch +message.action.delete.nexusVswitch=Por favor confirme que voc deseja remover este nexusVswitch. +message.action.enable.nexusVswitch=Por favor confirme que voc deseja habilitar este nexusVswitch. +message.action.disable.nexusVswitch=Por favor confirme que voc deseja desabilitar este nexusVswitch +message.specify.url=Por favor especifique a URL +label.select.instance.to.attach.volume.to=Escolha uma instncia para conectar o volume +label.upload=Enviar +label.upload.volume=Enviar o Volume +label.virtual.routers=Roteadores Virtuais +label.primary.storage.count=Pools de Storage Primrios +label.secondary.storage.count=Pools de Storage secundrios +label.number.of.system.vms=Nmero de VMs de sistema +label.number.of.virtual.routers=Nmero de Roteadores Virtuais +label.action.register.iso=Registrar ISO +label.isolation.method=Mtodo de isolao +label.action.register.template=Registrar template +label.checksum=MD5 checksum +label.vpn=VPN +label.vlan=VLAN + + +label.management.ips=Gerenciamento de Endereos IP +label.devices=Dispositivos +label.rules=Regras +# label.traffic.label=Traffic label +label.vm.state=Estado da VM +message.setup.physical.network.during.zone.creation.basic=Quando adicionar uma zona bsica, voc pode configurar uma rede fsica, que corresponde a uma NIC no hypervisor. A rede carrega diversos tipos de trfego.

Voc pode adicionar e remover outros tipos de trfego na mesma interface de rede fsica. +label.domain.router=Roteador do Domnio +label.console.proxy=Console proxy +label.secondary.storage.vm=VM de storage secundrio +label.add.netScaler.device=Adicionar dispositivo Netscaler +label.add.F5.device=Adicionar dispositivo F5 +label.add.SRX.device=Adicionar dispositivo SRX +label.account.and.security.group=Contas, grupos de Segurana +label.fetch.latest=Obter ltimos +label.system.offering=Ofertas de Sistema +message.validate.instance.name=Nomes de instncias no podem ter mais de 63 caracteres. Somente letras ASCII a~z, A~Z, dgitos 0~9 e hfen so permitidos. Deve comear com uma letra e terminar com uma letra ou dgito. + + +label.isolated.networks=Redes Isoladas +label.latest.events=ltimos eventos +state.Enabled=Habilitado +label.system.wide.capacity=Capacidade Total do Sistema +label.network.service.providers=Provedores de Servios de Rede +message.launch.zone=A zona est pronta para ser executada; por favor continue para o prximo passo. +error.unable.to.reach.management.server=No foi possvel acessar o Servidor de Gerenciamento +label.internal.name=Nome interno +# message.configure.all.traffic.types=You have multiple physical networks; please configure labels for each traffic type by clicking on the Edit button. +# message.edit.traffic.type=Please specify the traffic label you want associated with this traffic type. +label.edit.traffic.type=Editar tipo de trfego +# label.label=Label +label.max.networks=Mx. de redes +error.invalid.username.password=Usurio ou senha invlidos +message.enabling.security.group.provider=Habilitar provider de grupo de segurana +message.adding.Netscaler.provider=Adicionando Netscaler provider +message.creating.guest.network=Criando rede guest +label.action.delete.physical.network=Deletar rede fsica +message.action.delete.physical.network=Por favor confirme que voc deseja deletar esta rede fsica +message.installWizard.copy.whatIsAHost=Um host um nico computador. Os Hosts provem os recursos computacionais para executar as mquinas virtuais. Cada host possu o software do hypervisor instalado nele para gerenciar as guest VMs (Exceto os hosts bare metal, que so um caso especial discutido no Guia Avanado de Instalao). Por exemplo, um servidor Linux com KVM habilitado, um servidor Citrix XenServer e um servidor ESXi so hosts. Na Instalao Bsica, ns utilizamos um nico host rodando XenServer ou KVM.

O host a menor unidade organizacional dentro de uma instalao CloudStack&\#8482; . Hosts esto contidos dentro de Clusters, clusters esto contidos dentro de pods e pods esto contidos dentro de zonas. + + +label.add.compute.offering=Adicionar oferta de computao +label.compute.offering=Oferta de Computao +label.compute.offerings=Ofertas de Computao +label.select.offering=Selecionar Oferta +label.menu.infrastructure=Infra-estrutura +label.sticky.tablesize=Tamanho da Tabela +label.sticky.expire=Expires +label.sticky.cookie-name=Nome do Cookie +label.sticky.mode=Modo +label.sticky.length=Tamanho +label.sticky.holdtime=Tempo de espera +# label.sticky.request-learn=Request learn +label.sticky.prefix=Prefixo +label.sticky.nocache=Sem Cache +label.sticky.indirect=Indireto +# label.sticky.postonly=Post only +label.sticky.domain=Domínio +state.Allocating=Alocando +state.Migrating=Migrando +error.please.specify.physical.network.tags=Ofertas de Rede no estaro disponveis enquanto voc no especificar tags para esta interface fsica. + + +state.Stopping=Parando +message.add.load.balancer.under.ip=A regra do balanceador de carga foi adicionada para o IP\: +message.select.instance=Por favor selecione uma instncia. +label.select=Selecionar +label.select.vm.for.static.nat=Selecionar VM para NAT esttico +label.select.instance=Selecionar instncia +label.nat.port.range=Range de Portas NAT +label.static.nat.vm.details=Detalhes de NAT esttico da VM +label.edit.lb.rule=Editar regra de LB +message.migrate.instance.to.host=Por favor confirme que voc deseja migrar a instncia para outro host. +label.migrate.instance.to.host=Migrar instncia para outro host +message.migrate.instance.to.ps=Por favor confirme que voc deseja migrar a instncia para outro storage primrio. +label.migrate.instance.to.ps=Migrar instncia para outro storage primrio +label.corrections.saved=Alteraes salvas +message.installWizard.copy.whatIsSecondaryStorage=O storage secundrio est associado a uma zona, ele responsvel por armazenar o seguinte\:
  • Imagens de Templates do SO - que podem ser utilizadas para boot das VMs e podem incluir configuraes adicionais, como por exemplo as aplicaes instaladas
  • Imagens ISO - Imagens de sistema operacional que podem ser bootveis ou no
  • Snapshots do volume de discos - cpias salvas dos dados de uma VM que pode ser utilizada para recuperao de dados ou criao de novos templates
+message.installWizard.copy.whatIsPrimaryStorage=Uma infraestrutura de Cloud CloudStack&\#8482; utiliza dois tipos de storage\: storage primrio e storage secundrio. Ambos os tipos podem ser iSCSI, NFS servers, ou disco local.

O Storage primrio est associado com um cluster, e armazena os volumes de disco de cada guest VM para todas as VMs em execuo nos hosts deste cluster. O servidor de storage primrio tipicamente encontra-se localizado perto dos hosts. +message.installWizard.copy.whatIsACluster=Um cluster prov uma maneira de agrupar hosts. Os hosts em um cluster tem hardware idntico, rodam o mesmo hypervisor, esto na mesma subnet, acessam o mesmo storage compartilhado. Instncias de mquinas virtuais (VMs) podem ser migradas a quente - live migration - de um host para outro host no mesmo cluster, sem interromper o servio para o usurio. Um Cluster a terceira maior unidade organizacional em uma instalao CloudStack&\#8482; . Clusters esto contidos em pods e pods esto contidos em zonas.

O CloudStack&\#8482; permite mltiplos clusters em uma mesma cloud, entretanto para a instalao bsica, ns iremos precisar apenas de um cluster. +message.installWizard.copy.whatIsAPod=Um pod normalmente representa um nico rack. Hosts no mesmo pod esto na mesma subrede.

Um pod a segunda maior unidade organizacional de uma instalao CloudStack&\#8482; . Pods esto contidos dentro de zonas. Cada zona, pode conter um ou mais pods; Na instalao bsica, voc ir ter apenas um pod na sua zona. +message.installWizard.copy.whatIsAZone=Uma zona a maior unidade organizacional em uma instalao CloudStack&\#8482; . Uma zona tipicamente corresponde a um nico datacenter, apesar de ser possvel ter mltiplas zonas no mesmo datacenter. O benefcio de se organizar a infra-estrutura em zonas permitir o isolamento fsico e redundncia. Por exemplo, cada zona pode possuir sua prpria alimentao de energia e link de sada de internet e zonas podem estar geograficamente separadas (apesar de no ser obrigatrio). +message.installWizard.copy.whatIsCloudStack=O CloudStack&\#8482 uma plataforma de software que agrega recursos computacionais para construir uma Cloud de Infra-estrutura como Servio (IaaS) pblica, privada ou hbrida. O CloudStack&\#8482 gerncia a rede, o storage e os recursos computacionais que compem a infra-estrutura de cloud. Utilize o CloudStack&\#8482 para instalar, gerenciar e configurar os ambientes de cloud computing.

Indo alm de imagens de mquinas virtuais individuais rodando em hardware commodity, CloudStack&\#8482 prov uma soluo completa de software de infra-estrutura de cloud para entregar datacenters virtuais como um servio - possuindo todos os componentes essenciais para contruir, instalar e gerenciar aplicaes na cloud multi-camadas e multi-tenant. Ambas as verses open-source e premium esto disponveis, com a verso opensource oferecendo praticamente os mesmos recursos. +message.installWizard.tooltip.addSecondaryStorage.path=Path exportado, localizado no servidor que voc especificou acima +message.installWizard.tooltip.addSecondaryStorage.nfsServer=O endereo IP do servidor NFS hospedando o storage secundrio +message.installWizard.tooltip.addPrimaryStorage.path=(para NFS) No NFS este o path exportado pelo servidor. Path (para SharedMountPoint). Com o KVM este o path em cada host onde o storage primrio est montado. Por exemplo, "/mnt/primary". +message.installWizard.tooltip.addPrimaryStorage.server=(para NFS, iSCSI ou PreSetup) O Endereo IP ou nome DNS do dispositivo de storage. +message.installWizard.tooltip.addPrimaryStorage.name=O Nome do dispositivo de storage. +message.installWizard.tooltip.addHost.password=Este a senha do usurio especificado acima (da sua instalao do XenServer) +message.installWizard.tooltip.addHost.username=Usualmente root. +message.installWizard.tooltip.addHost.hostname=O nome DNS ou endereo IP do host. +message.installWizard.tooltip.addCluster.name=Um nome para o cluster. Este nome pode ser um nome de sua escolha e no usado pelo CloudStack. +message.installWizard.tooltip.addPod.reservedSystemEndIp=Este o range de IP na rede privada que o CloudStack utiliza para gerenciar o storage secundrio das VMs e Proxy Console das VMs. Estes endereos IP so obtidos da mesma subrede dos servidores hosts. +message.installWizard.tooltip.addPod.reservedSystemStartIp=Este o range de IP na rede privada que o CloudStack utiliza para gerenciar as VMs de storage secundrio e as VMs de Console Proxy. Estes endereos IP devem estar na mesma subnet dos servidores de processamento. +message.installWizard.tooltip.addPod.reservedSystemNetmask=A mscara de rede est em uso na subrede que os guests iro utilizar. +message.installWizard.tooltip.addPod.reservedSystemGateway=O gateway para os hosts neste pod. +message.installWizard.tooltip.addPod.name=O nome para o pod +message.installWizard.tooltip.configureGuestTraffic.guestEndIp=O range de endereos IP que estar disponvel para alocao para os guests nesta zona. Caso uma NIC seja utilizada, estes IPs devem estar no mesmo CIDR que o CIDR do pod. +message.installWizard.tooltip.configureGuestTraffic.guestStartIp=O range de endereos IP que estar disponvel para alocao para os guests nesta zona. Caso uma NIC seja utilizada, estes IPs devem estar no mesmo CIDR que o CIDR do pod. +message.installWizard.tooltip.configureGuestTraffic.guestNetmask=A mscara de rede da subrede que os guests devem usar +message.installWizard.tooltip.configureGuestTraffic.guestGateway=O gateway que os guests devem usar +message.installWizard.tooltip.configureGuestTraffic.description=Uma descrio da sua rede +message.installWizard.tooltip.configureGuestTraffic.name=Um nome para sua rede +message.installWizard.tooltip.addZone.internaldns2=Estes so os servidores DNS utilizados pelas VMs de sistema nesta zona. Estes servidores DNS sero acessados atravs da interface de rede privada das VMs de sistema. O endereo IP privado que voc configurar para os pods deve possuir uma rota para os servidores DNS configurados aqui. +message.installWizard.tooltip.addZone.internaldns1=Estes so os servidores DNS utilizados pelas VMs de sistema nesta zona. Estes servidores DNS sero acessados atravs da interface de rede privada das VMs de sistema. O endereo IP privado que voc configurar para os pods deve possuir uma rota para os servidores DNS configurados aqui. +message.installWizard.tooltip.addZone.dns2=Estes so os servidores DNS utilizados pelas VMs convidadas nesta zona. Estes servidores DNS sero acessados pela interface de rede pblica que voc ir adicionar posteriormente. O endereo IP pblico de uma zona deve possuir uma rota para os servidores DNS configurados aqui. +message.installWizard.tooltip.addZone.name=Um nome para a zona +message.installWizard.tooltip.addZone.dns1=Estes so os servidores DNS utilizados pelas guest VMs na zona. Estes servidores DNS sero acessados pela interface de rede pblica que voc ir adicionar posteriormente. O endereo IP pblico da zona deve possuir uma rota para os servidores DNS configurados aqui. +message.setup.successful=Cloud configurada com sucesso\! +label.may.continue=Voc pode continuar agora +error.installWizard.message=Alguma coisa est errada; voc pode voltar e corrigir quaisquer erros +message.installWizard.now.building=Construindo sua cloud agora... +message.installWizard.click.retry=Click no boto para tentar executar novamente. +label.launch=Executar +label.installWizard.click.launch=Click no boto executar. +label.congratulations=Parabns\! +label.installWizard.addSecondaryStorageIntro.subtitle=Qual o storage secundrio ? +label.installWizard.addSecondaryStorageIntro.title=Vamos adicionar o storage secundrio +label.installWizard.addPrimaryStorageIntro.subtitle=Qual o storage primrio ? +label.installWizard.addPrimaryStorageIntro.title=Vamos adicionar o storage primrio +label.installWizard.addHostIntro.subtitle=O que um Host ? +label.installWizard.addHostIntro.title=Vamos adicionar um host +label.installWizard.addClusterIntro.subtitle=O que um cluster? +label.installWizard.addClusterIntro.title=Vamos adicionar um cluster +label.installWizard.addPodIntro.subtitle=O que um pod ? +label.installWizard.addPodIntro.title=Vamos adicionar um pod +label.installWizard.addZone.title=Adicionar zona +label.installWizard.addZoneIntro.subtitle=O que uma zona? +label.installWizard.addZoneIntro.title=Vamos adicionar uma zona +error.password.not.match=Os campos de senha no combinam +label.confirm.password=Confirme a senha +message.change.password=Por favor, troque sua senha. +label.save.and.continue=Salvar e continuar +label.skip.guide=Eu utilizei o CloudStack antes, pular este guia +label.continue.basic.install=Continuar com a instalao bsica +label.introduction.to.cloudstack=Introduo ao CloudStack&\#8482 +label.what.is.cloudstack=O que o CloudStack&\#8482? +label.hints=Dicas +label.installWizard.subtitle=Este tour vai auxiliar voc na configurao da sua instalao de CloudStack&\#8482 +label.continue=Continuar +label.installWizard.title=Ol, seja bem vindo ao CloudStack&\#8482 +label.agree=Concordo +label.license.agreement=Acordo de Licena +label.license.agreement.subtitle=Por favor aceite a EULA do CloudStack&\#8482 antes de instalar. +label.manage.resources=Gerenciar Recursos +label.port.forwarding.policies=Polticas de redirecionamento de portas +label.load.balancing.policies=Polticas de balanceamento de carga +label.networking.and.security=Rede e segurana +label.bandwidth=Bandwidth +label.virtual.machines=Mquinas virtuais +label.compute.and.storage=Processamento e Armazenamento +label.task.completed=Tarefa completa +label.update.project.resources=Atualizar recursos de projeto +label.remove.project.account=Remover conta de projeto +label.item.listing=Listar items +message.select.item=Por favor selecione um item. +label.removing=Removendo +label.invite=Convidar +label.add.by=Adicionado por +label.max.vms=Mx. VMs de usurio +label.max.public.ips=Mx. IPs pblicos +label.max.volumes=Mx. volumes +label.max.snapshots=Max. snapshots +label.max.templates=Mx. templates +# label.max.vpcs=Max. VPCs +label.project.dashboard=Dashboard do Projeto +label.remind.later=Me lembre depois +label.invited.accounts=Contas convidadas +label.invite.to=Convidar para +label.add.accounts.to=Adicionar contas para +label.add.accounts=Adicionar contas +label.project.name=Nome de projeto +label.create.project=Criar um projeto +label.networks=Redes +label.launch.vm=Executar VM +label.new.vm=Nova VM +label.previous=Anterior +label.add.to.group=Adicionar ao grupo +message.vm.review.launch=Por favor revise a informao abaixo e confirme que sua instncia virtual est correta antes de executa-la. +message.select.security.groups=Por favor selecione o(s) grupo(s) de segurana para sua nova VM +label.new=Novo +message.please.select.networks=Por favor selecione as redes para sua mquina virtual. +message.please.proceed=Por favor continue para o prximo passo. +message.zone.no.network.selection=A zona que voc selecionou no possui nenhuma rede para ser escolhida. +label.no.thanks=No obrigado +label.my.templates=Meus templates +message.select.template=Por favor selecione um template para sua nova instncia virtual. +message.select.iso=Por favor selecione um ISO para sua nova instncia virtual +message.template.desc=Imagem de SO que pode ser utilizada para bootar VMs +message.iso.desc=Imagem de disco contendo dados ou mdia de sistema operacional bootvel +label.select.iso.or.template=Selecione ISO ou template +message.select.a.zone=A zone tipicamente corresponde a um nico datacenter. Mltiplas zonas auxiliam a cloud a ser mais confivel provendo isolamento fsico e redundncia. +label.select.a.zone=Selecione uma zona +label.review=Revisar +label.select.a.template=Selecione um template +label.setup=Configurao +state.Allocated=Alocado +changed.item.properties=Alteradas propriedades do item +label.apply=Aplicar +label.default=Padro +label.viewing=Visualizar +label.move.to.top=Mover para o topo +label.move.up.row=Mover uma clula para cima +label.move.down.row=Mover uma clula para baixo +# label.move.to.bottom=Move to bottom +label.drag.new.position=Arrastar para uma nova posio +label.order=Ordenar +label.no.data=Sem dados para mostrar +label.change.value=Alterar valor +label.clear.list=Limpar lista +label.full.path=Path completo +message.add.domain=Por favor especifique o subdomnio que voc deseja criar neste domnio +message.delete.user=Por favor confirme que voc deseja deletar este usurio. +message.enable.user=Por favor confirme que voc deseja habilitar este usurio. +message.disable.user=Por favor confirme que voc deseja desabilitar este usurio. +message.generate.keys=Por favor confirme que voc deseja gerar novas chaves para este usurio. +message.update.resource.count=Por favor confirme que voc quer atualizar a contagem de recursos para esta conta. +message.edit.account=Editar ("-1" indica que no haver limites para a quantidade de recursos criado) +label.total.of.vm=Total de VM +label.total.of.ip=Total de endereos IP +state.enabled=Habilitado +message.action.download.iso=Por favor confirme que voc deseja baixar esta ISO. +message.action.download.template=Por favor confirme que voc deseja baixar este template. +label.destination.zone=Zona de Destino +label.keyboard.type=Tipo de Teclado +label.nic.adapter.type=Tipo de adaptador NIC +label.root.disk.controller=Controlador do disco Root +label.community=Comunidade +label.remove.egress.rule=Remover regra egress +label.add.egress.rule=Adicionar regra egress +label.egress.rule=Regra Egress +label.remove.ingress.rule=Remover regra ingress +label.delete.vpn.user=Deletar usurio VPN +label.add.vpn.user=Adicionar usurio VPN +label.remove.pf=Remover regra de redirecionamento de porta +label.remove.vm.from.lb=Remover VM da regra de balanceamento de carga +label.add.vms.to.lb=Add VM(s) na regra de balanceamento de carga +label.add.vm=Adicionar VM +label.remove.static.nat.rule=Remover regra de NAT esttico +label.remove.rule=Remover regra +label.add.static.nat.rule=Adicionar regra de NAT esttico +label.add.rule=Adicionar regra +label.configuration=Configurao +message.disable.vpn=Voc tem certeza que deseja desabilitar a VPN? +label.disable.vpn=Desabilitar VPN +message.enable.vpn=Por favor confirme que voc deseja acesso VPN habilitado para este endereo IP. +label.enable.vpn=Habilitar VPN +message.acquire.new.ip=Por favor confirme que voc gostaria de adquirir um novo IP para esta rede. +label.elastic=Elstico +label.my.network=Minha rede +label.add.vms=Adicionar VMs +label.configure=Configurar +# label.stickiness=Stickiness +label.source=Origem +label.least.connections=Least connections +label.round.robin=Round-robin +label.restart.required=Reiniciar obrigatrio +label.clean.up=Limpar +label.restart.network=Reiniciar rede +label.edit.network.details=Editar detalhes de rede +label.add.guest.network=Adicionar rede guest +label.guest.networks=Redes Guest +message.ip.address.changed=Seu endereo IP pode ter mudado; voc gostaria de atualizar a listagem ? Note que neste caso o painel de detalhes ir fechar. +# state.BackingUp=Backing Up +# state.BackedUp=Backed Up +label.done=Pronto +label.vm.name=Nome da VM +message.migrate.volume=Por favor confirme que voc deseja migrar o volume para outro storage primrio. +label.migrate.volume=Migrar volume para outro storage primrio +message.create.template=Voc tem certeza que deseja criar um template ? +label.create.template=Criar template +message.download.volume.confirm=Por favor confirme que voc quer baixar este volume +message.detach.disk=Voc tem certeza que deseja desconectar este disco ? +state.ready=Pronto +state.Ready=Pronto +label.vm.display.name=Nome de exibio da VM +label.select-view=Selecionar visualizao +label.local.storage=Storage Local +label.direct.ips=IPs Diretos +label.view.all=Visualizar tudo +label.zone.details=Detalhes de zona +message.alert.state.detected=Alerta de estado detectado +state.Starting=Iniciando +# state.Expunging=Expunging +state.Creating=Criando +message.decline.invitation=Voc tem certeza que quer rejeitar este convite de projeto ? +label.decline.invitation=Rejeitar convite +message.confirm.join.project=Por favor confirme que voc deseja entrar neste projeto +message.join.project=Voc agora entrou em um projeto. Por favor troque para a viso de Projeto para visualizar o projeto. +label.accept.project.invitation=Aceitar convite de projeto. +label.token=Token +label.project.id=ID de Projeto +message.enter.token=Por favor entre o token que voc recebeu no e-mail privado. +label.enter.token=Digite o token +state.Accepted=Aceito +state.Pending=Pendente +state.Completed=Completo +state.Declined=Recusado +label.project=Projeto +label.invitations=Convites +label.delete.project=Deletar projeto +message.delete.project=Voc tem certeza que deseja deletar este projeto ? +message.activate.project=Voc tem certeza que deseja ativar este projeto ? +label.activate.project=Ativar Projeto +label.suspend.project=Suspender Projeto +message.suspend.project=Voc tem certeza que deseja suspender este projeto ? +state.Suspended=Suspendido +label.edit.project.details=Editar detalhes do projeto +label.new.project=Novo Projeto +state.Active=Ativo +state.Disabled=Desativado +label.projects=Projetos +label.make.project.owner=Criar proprietrio de conta de projeto +label.remove.project.account=Remover conta de projeto +message.project.invite.sent=Convite enviado para o usurio; Eles sero adicionados ao projeto aps aceitarem o convite +label.add.account.to.project=Adicionar conta ao projeto +label.revoke.project.invite=Revogar convite +label.project.invite=Convidar para o projeto +label.select.project=Selecionar Projeto +message.no.projects=Voc no possui nenhum projeto.
Por favor crie um novo projeto partir da seo Projetos. +message.no.projects.adminOnly=Voc no possui nenhum projeto.
Por favor solicite ao seu administrador a criao de um novo projeto. +message.pending.projects.1=Voc possui convites de projetos pendentes\: +message.pending.projects.2=Para visualizar, por favor acesse a seo de projetos, depois selecione os convites no menu drop-down. +message.instanceWizard.noTemplates=Voc no possui nenhum template disponvel; por favor adicione um template compatvel e reinicie o wizard de instncia. +label.view=Visualizar +instances.actions.reboot.label=Reiniciar instncia +label.filterBy=Filtrar por +label.ok=OK +notification.reboot.instance=Reiniciar instncia +notification.start.instance=Iniciar instncia +notification.stop.instance=Parar instncia +label.display.name=Nome de exibio +label.zone.name=Nome da zona +ui.listView.filters.all=Todos +ui.listView.filters.mine=Meus +state.Running=Executando +state.Stopped=Parado +state.Destroyed=Destrudo +state.Error=Erro +message.reset.password.warning.notPasswordEnabled=O template desta instncia foi criado sem senha habilitada +message.reset.password.warning.notStopped=Sua instncia deve estar parada antes de tentar trocar sua senha atual +label.notifications=Notificaes +label.default.view=Viso Padro +label.project.view=Viso de Projeto + +message.add.system.service.offering=Por favor preencha os dados abaixo para adicionar uma nova oferta de servio de sistema. +message.action.delete.system.service.offering=Por favor confirme que voc deseja deletar esta oferta de servio de sistema. +label.action.delete.system.service.offering=Deletar Oferta de Servio de Sistema +label.hypervisor.capabilities=Recursos de Virtualizador +label.hypervisor.version=Verso de Virtualizador +label.max.guest.limit=Limite mx. de guest +label.add.network.offering=Adicionar oferta de rede +label.supported.services=Servios Suportados +label.service.capabilities=Recursos de servios +label.guest.type=Tipo de Guest +label.specify.IP.ranges=Especifique range de IP +# label.conserve.mode=Conserve mode +label.created.by.system=Criado pelo sistema +label.menu.system.service.offerings=Ofertas do Sistema +label.add.system.service.offering=Adicionar Plano para VM de Sistema +label.redundant.router.capability=Recurso de roteador redundante +label.supported.source.NAT.type=Tipo de Source NAT Suportado +label.elastic.LB=LB Elstico +label.LB.isolation=Isolamento de LB +label.elastic.IP=IP Elstico +label.network.label.display.for.blank.value=Utilizar gateway default +label.xen.traffic.label=Etiqueta de trfego XenServer +label.kvm.traffic.label=Etiqueta de trfego KVM +label.vmware.traffic.label=Etiqueta de trfego VMware +label.start.IP=IP do incio +label.end.IP=IP do fim +label.remove.ip.range=Remover range de IP +label.ip.ranges=Ranges de IP +label.start.vlan=Vlan do incio +label.end.vlan=Vlan do fim +label.broadcast.domain.range=Range do domnio de Broadcast +# label.compute=Compute +message.add.guest.network=Por favor confirme que voc gostaria de adicionar uma rede guest. +label.subdomain.access=Acesso ao subdomnio +label.guest.start.ip=IP de incio do guest +label.guest.end.ip=IP do fim do guest +label.virtual.router=Roteador Virtual +label.physical.network.ID=ID da rede fsica +label.destination.physical.network.id=ID de destino da rede fsica +label.dhcp=DHCP +label.destroy.router=Destruir roteador +message.confirm.destroy.router=Por favor confirme que voc gostaria de destruir este roteador +label.change.service.offering=Alterar oferta de servio +label.view.console=Visualizar Console +# label.redundant.state=Redundant state +label.enable.provider=Habilitar provider +message.confirm.enable.provider=Por favor confirme que voc gostaria de habilitar este provider +label.disable.provider=Desabilitar Provider +message.confirm.disable.provider=Por favor confirme que voc gostaria de desabilitar este provider +# label.shutdown.provider=Shutdown provider +message.confirm.shutdown.provider=Por favor confirme que voc deseja desligar este provider +label.netScaler=NetScaler +label.add.new.NetScaler=Adicionar um novo NetScaler +label.capacity=Capacidade +label.dedicated=Dedicado +label.f5=F5 +label.add.new.F5=Adicionar um novo F5 +label.srx=SRX +label.providers=Providers +label.add.new.SRX=Adicionar um novo SRX +label.timeout=Timeout +label.public.network=Rede Pblica +label.private.network=Rede Privada +label.enable.swift=Habilitar Swift +confirm.enable.swift=Por favor preencha as informaes abaixo para habilitar suporte ao Swift +message.after.enable.swift=Swift Configurado. Nota\: Aps deixar esta pgina, voc no ser capaz de reconfigurar o Swift novamente. +label.key=Chave +label.delete.NetScaler=Remover NetScaler +message.confirm.delete.NetScaler=Por favor confirme que voc deseja remover o NetScaler +label.delete.F5=Remover F5 +message.confirm.delete.F5=Por favor confirme que voc deseja remover o F5 +label.delete.SRX=Remover SRX +message.confirm.delete.SRX=Por favor confirme que voc deseja remover o SRX +label.pods=Pods +label.pod.name=Nome do Pod +label.reserved.system.gateway=Gateway de sistema reservado +label.reserved.system.netmask=Mscara de rede do sistema reservado +label.start.reserved.system.IP=Incio dos IPs reservados para o sistema +label.end.reserved.system.IP=Fim dos IPs reservados para o sistema +label.clusters=Clusters +label.cluster.name=Nome do Cluster +label.host.MAC=Host MAC +label.agent.username=Usurio do Agente +label.agent.password=Senha do Agente +message.confirm.action.force.reconnect=Por favor confirme que voc deseja forar a reconexo com este host. +label.resource.state=Estado do Recurso +label.LUN.number=LUN \# +message.confirm.remove.IP.range=Por favor confirme que voc deseja remover este range de IP. +message.tooltip.zone.name=Um nome para a zona. +# message.tooltip.dns.1=Name of a DNS server for use by VMs in the zone. The public IP addresses for the zone must have a route to this server. +message.tooltip.dns.2=Um servidor DNS secundrio para ser utilizado pelas VMs nesta zona. Os endereos IP pblicos nesta zona devem ter rota para este servidor. +message.tooltip.internal.dns.1=Nome de um servidor DNS que ser utilizado pelas VMs internas de sistema do CloudStack nesta zona. Os endereos privados dos pods devem ter uma rota para este servidor. +message.tooltip.internal.dns.2=Nome de um servidor DNS que ser utilizado pelas VMs internas de sistema do CloudStack nesta zona. Os endereos privados dos pods devem ter uma rota para este servidor. +message.tooltip.network.domain=Um sufixo DNS que ir criar um nome de domnio customizado para a rede que acessada pelas guest VMs. +message.tooltip.pod.name=Um nome para este pod. +message.tooltip.reserved.system.gateway=O gateway para os hosts neste pod. +message.tooltip.reserved.system.netmask=O prefixo de rede que define a subrede deste pod. Utilize a notao CIDR. +message.creating.zone=Criando zona. +message.creating.physical.networks=Criando redes fisicas +message.configuring.physical.networks=Configurando redes fsicas +message.adding.Netscaler.device=Adicionando dispositivo Nescaler +message.creating.pod=Criando pod +message.configuring.public.traffic=Configurando trfego pblico +message.configuring.storage.traffic=Configurando trfego de storage +message.configuring.guest.traffic=Configurando trfego do guest +message.creating.cluster=Criando cluster +message.adding.host=Adicionando host +message.creating.primary.storage=Criando storage primrio +message.creating.secondary.storage=Criando storage secundrio +message.Zone.creation.complete=Criao de zona completa +message.enabling.zone=Habilitando zona +error.something.went.wrong.please.correct.the.following=Algo deu errado; por favor corrija abaixo +error.could.not.enable.zone=No foi possvel habilitar a zona +message.zone.creation.complete.would.you.like.to.enable.this.zone=Criao de zona completa. Voc gostaria de habilitar esta zona? +message.please.add.at.lease.one.traffic.range=Por favor adicione pelo menos um range de trfego. +message.you.must.have.at.least.one.physical.network=Voc deve ter pelo menos uma rede fsica +message.please.select.a.different.public.and.management.network.before.removing=Por favor selecione uma rede pblica e de gerenciamento diferente antes de remover + +label.zone.type=Tipo de Zona +label.setup.zone=Configurar Zona +label.setup.network=Configurar Rede +label.add.resources=Adicionar Recursos +label.launch=Executar +label.set.up.zone.type=Configurar tipo de zona +message.please.select.a.configuration.for.your.zone=Por favor selecione uma configuracao para sua zona. +# message.desc.basic.zone=Provide a single network where each VM instance is assigned an IP directly from the network. Guest isolation can be provided through layer-3 means such as security groups (IP address source filtering). +label.basic=Bsico +# message.desc.advanced.zone=For more sophisticated network topologies. This network model provides the most flexibility in defining guest networks and providing custom network offerings such as firewall, VPN, or load balancer support. +label.advanced=Avançado +# message.desc.zone=A zone is the largest organizational unit in CloudStack, and it typically corresponds to a single datacenter. Zones provide physical isolation and redundancy. A zone consists of one or more pods (each of which contains hosts and primary storage servers) and a secondary storage server which is shared by all pods in the zone. +label.physical.network=Rede Fsica +label.public.traffic=Trfego Pblico +label.guest.traffic=Trfego do guest +label.storage.traffic=Trfego do Storage +# message.setup.physical.network.during.zone.creation=When adding an advanced zone, you need to set up one or more physical networks. Each network corresponds to a NIC on the hypervisor. Each physical network can carry one or more types of traffic, with certain restrictions on how they may be combined.

Drag and drop one or more traffic types onto each physical network. +label.add.physical.network=Adicionar rede fsica +label.traffic.types=Tipos de Trfego +label.management=Gerenciamento +label.guest=Guest +label.please.specify.netscaler.info=Por favor especifique as informaes do Netscaler +# message.public.traffic.in.advanced.zone=Public traffic is generated when VMs in the cloud access the internet. Publicly-accessible IPs must be allocated for this purpose. End users can use the CloudStack UI to acquire these IPs to implement NAT between their guest network and their public network.

Provide at least one range of IP addresses for internet traffic. +# message.public.traffic.in.basic.zone=Public traffic is generated when VMs in the cloud access the Internet or provide services to clients over the Internet. Publicly accessible IPs must be allocated for this purpose. When a instance is created, an IP from this set of Public IPs will be allocated to the instance in addition to the guest IP address. Static 1-1 NAT will be set up automatically between the public IP and the guest IP. End users can also use the CloudStack UI to acquire additional IPs to implement static NAT between their instances and the public IP. +# message.add.pod.during.zone.creation=Each zone must contain in one or more pods, and we will add the first pod now. A pod contains hosts and primary storage servers, which you will add in a later step. First, configure a range of reserved IP addresses for CloudStack's internal management traffic. The reserved IP range must be unique for each zone in the cloud. +# message.guest.traffic.in.advanced.zone=Guest network traffic is communication between end-user virtual machines. Specify a range of VLAN IDs to carry guest traffic for each physical network. +# message.guest.traffic.in.basic.zone=Guest network traffic is communication between end-user virtual machines. Specify a range of IP addresses that CloudStack can assign to guest VMs. Make sure this range does not overlap the reserved system IP range. +# message.storage.traffic=Traffic between CloudStack's internal resources, including any components that communicate with the Management Server, such as hosts and CloudStack system VMs. Please configure storage traffic here. +# message.desc.cluster=Each pod must contain one or more clusters, and we will add the first cluster now. A cluster provides a way to group hosts. The hosts in a cluster all have identical hardware, run the same hypervisor, are on the same subnet, and access the same shared storage. Each cluster consists of one or more hosts and one or more primary storage servers. +# message.desc.host=Each cluster must contain at least one host (computer) for guest VMs to run on, and we will add the first host now. For a host to function in CloudStack, you must install hypervisor software on the host, assign an IP address to the host, and ensure the host is connected to the CloudStack management server.

Give the host's DNS or IP address, the user name (usually root) and password, and any labels you use to categorize hosts. +# message.desc.primary.storage=Each cluster must contain one or more primary storage servers, and we will add the first one now. Primary storage contains the disk volumes for all the VMs running on hosts in the cluster. Use any standards-compliant protocol that is supported by the underlying hypervisor. +# message.desc.secondary.storage=Each zone must have at least one NFS or secondary storage server, and we will add the first one now. Secondary storage stores VM templates, ISO images, and VM disk volume snapshots. This server must be available to all hosts in the zone.

Provide the IP address and exported path. +label.launch.zone=Executar zona. +message.please.wait.while.zone.is.being.created=Por favor, espere enquanto sua zona est sendo criada; isto pode demorar um pouco... + +label.load.balancing=Balanceamento de Carga +label.static.nat.enabled=NAT esttico Habilitado +label.zones=Zonas +label.view.more=Ver mais +label.number.of.zones=Nmero de Zonas +label.number.of.pods=Nmero de Pods +label.number.of.clusters=Nmero de Clusters +label.number.of.hosts=Nmero de Hosts +label.total.hosts=Total de Hosts +label.total.CPU=CPU TOTAL +label.total.memory=Total de Memria +label.total.storage=Totam de Storage +label.purpose=Propsito + + + + +label.action.migrate.router=Migrar Roteador +label.action.migrate.router.processing=Migrando Roteador... +message.migrate.router.confirm=Por favor confirme o host que voc deseja migrar o roteador para\: +label.migrate.router.to=Migrar Roteador para + +label.action.migrate.systemvm=Migrar VM de Sistema +label.action.migrate.systemvm.processing=Migrando VM de Sistema... +message.migrate.systemvm.confirm=Por favor confirme o host para o qual voc deseja migrar a VM de sistema\: +label.migrate.systemvm.to=Migrar VM de sistema para + + +mode=Modo +side.by.side=Lado a Lado +# inline=Inline + +# extractable=Extractable + +label.ocfs2=OCFS2 + +label.action.edit.host=Editar Host + +network.rate=Taxa de Transferência + +ICMP.type=Tipo ICMP +ICMP.code=Código ICMP + +image.directory=Diretório da Imagem + +label.action.create.template.from.vm=Criar Template a partir da VM +label.action.create.template.from.volume=Criar Template a partir do Disco + +message.vm.create.template.confirm=Criar Template reiniciará a VM automaticamente. + +label.action.manage.cluster=Vincular Cluster +message.action.manage.cluster=Confirma a vinculação do cluster. +label.action.manage.cluster.processing=Vinculando o Cluster.... + +label.action.unmanage.cluster=Desvincular Cluster +message.action.unmanage.cluster=Confirma a desvinculação do cluster. +label.action.unmanage.cluster.processing=Desvinculando Cluster.... + +label.allocation.state=Status da Alocação +managed.state=Status do Gerenciamento + +label.default.use=Uso padro +# label.host.tags=Host Tags + +label.cidr=CIDR +label.cidr.list=CIDR de Origem + +label.storage.tags=Tags de Storage + +label.redundant.router=Roteador Redundantee +label.is.redundant.router=Redundante + +force.delete=Forçar Exclusão +force.delete.domain.warning=Atenção\: Esta opção removerá todos os domínios, contas e recursos associados. + +force.remove=Forçar Remoção +force.remove.host.warning=Atenção\: O CloudStack desligará de maneira forçada todas as VMs antes de remover o host do cluster. + +force.stop=Forçar Parada +force.stop.instance.warning=Aviso\: Forar o desligamento desta instncia deve ser sua ltima opo. Isto pode levar a perda de dados, bem como comportamento inconsistnte do estado da mquina virtual. + +label.PreSetup=PreSetup +label.SR.name = SR Name-Label +label.SharedMountPoint=SharedMountPoint +label.clvm=CLVM +label.volgroup=Grupo de Volume +label.VMFS.datastore=VMFS datastore + +label.network.device=Dispositivo de Rede +label.add.network.device=Adicionar Dispositivo de Rede +label.network.device.type=Tipo de Dispositivo de Rede +label.DHCP.server.type=Tipo de Servidor DHCP +label.Pxe.server.type=Tipo de Servidor PXE +label.PING.storage.IP=Disparar PING para IP do Storage +label.PING.dir=PING Directory +label.TFTP.dir=TFTP Directory +label.PING.CIFS.username=PING CIFS username +label.PING.CIFS.password=PING CIFS password +label.CPU.cap=CPU Cap + + +label.action.enable.zone=Ativar Zona +label.action.enable.zone.processing=Ativando Zona.... +message.action.enable.zone=Confirma a ativação da zona. +label.action.disable.zone=Desativar Zona +label.action.disable.zone.processing=Desativando Zona.... +message.action.disable.zone=Confirma a desativação da zona. + +label.action.enable.pod=Ativar POD +label.action.enable.pod.processing=Ativando POD.... +message.action.enable.pod=Confirma a ativação do POD. +label.action.disable.pod=Desativar POD +label.action.disable.pod.processing=Desativando POD.... +message.action.disable.pod=Confirma a desativação do POD. + +label.action.enable.cluster=Ativar Cluster +label.action.enable.cluster.processing=Ativando Cluster.... +message.action.enable.cluster=Confirma a ativação do cluster. +label.action.disable.cluster=Desativar Cluster +label.action.disable.cluster.processing=Desativando Cluster.... +message.action.disable.cluster=Confirma a desativação do cluster. + +label.account.id=ID da Conta +label.account.name=Nome da Conta +# label.account.specific=Account-Specific +label.account=Conta +label.accounts=Contas +label.acquire.new.ip=Adquirir novo IP +label.show.ingress.rule=Mostrar Regra de Entrada +label.hide.ingress.rule=Ocultar Regra de Entrada +label.action.attach.disk.processing=Anexando Disco.... +label.action.attach.disk=Anexar Disco +label.action.attach.iso.processing=Anexando ISO.... +label.action.attach.iso=Anexar ISO +label.action.cancel.maintenance.mode.processing=Cancelando Modo de Manutenção.... +label.action.cancel.maintenance.mode=Cancelar Modo de Manutenção +label.action.change.password=Troca de Senha +label.action.change.service.processing=Trocando de Plano.... +label.action.change.service=Trocar Plano +label.action.copy.ISO.processing=Copiando ISO.... +label.action.copy.ISO=Copiar ISO +label.action.copy.template.processing=Copiando Template.... +label.action.copy.template=Copiar Template +label.action.create.template.processing=Criando Template.... +label.action.create.template=Criar Template +label.action.create.vm.processing=Criando VM.... +label.action.create.vm=Criar VM +label.action.create.volume.processing=Criando Disco.... +label.action.create.volume=Criar Disco +label.action.delete.IP.range.processing=Removendo Range de IP.... +label.action.delete.IP.range=Remover Range IP +label.action.delete.ISO.processing=Removendo ISO.... +label.action.delete.ISO=Removendo ISO +label.action.delete.account.processing=Removendo conta.... +label.action.delete.account=Remover conta +label.action.delete.cluster.processing=Removendo Cluster.... +label.action.delete.cluster=Remover Cluster +label.action.delete.disk.offering.processing=Removendo Oferta de Disco.... +label.action.delete.disk.offering=Remover Oferta de Disco + +label.action.update.resource.count=Atualiza Contador de Recursos +label.action.update.resource.count.processing=Atualizando Contador de Recursos.... + +label.action.delete.domain=Remover Domínio +label.action.delete.domain.processing=Removendo Domínio.... + +label.action.delete.firewall.processing=Removendo Firewall.... +label.action.delete.firewall=Remover regra de firewall +label.action.delete.ingress.rule.processing=Removendo Regra de Entrada.... +label.action.delete.ingress.rule=Remover Regra de Entrada +label.action.delete.load.balancer.processing=Removendo Load Balancer.... +label.action.delete.load.balancer=Remover regra de balanceador de carga +label.action.edit.network.processing=Editarando Rede.... +label.action.edit.network=Editar Rede +label.action.delete.network.processing=Removendo Rede.... +label.action.delete.network=Remover Rede +label.action.delete.pod.processing=Removendo POD.... +label.action.delete.pod=Remover POD +label.action.delete.primary.storage.processing=Removendo Storage Primário.... +label.action.delete.primary.storage=Remover Storage Primário +label.action.delete.secondary.storage.processing=Removendo Storage Secundário.... +label.action.delete.secondary.storage=Remover Storage Secundário +label.action.delete.security.group.processing=Removendo Security Group.... +label.action.delete.security.group=Remover Security Group +label.action.delete.service.offering.processing=Removendo Plano.... +label.action.delete.service.offering=Remover Plano +label.action.delete.snapshot.processing=Removendo Snapshot.... +label.action.delete.snapshot=Remover Snapshot +label.action.delete.template.processing=Removendo Template.... +label.action.delete.template=Remover Template +label.action.delete.user.processing=Removendo Usuário.... +label.action.delete.user=Remover Usurio +label.action.delete.volume.processing=Removendo Disco.... +label.action.delete.volume=Remover Disco +label.action.delete.zone.processing=Removendo Zona.... +label.action.delete.zone=Remover Zona +label.action.destroy.instance.processing=Apagando Cloud Server.... +label.action.destroy.instance=Apagar Cloud Server +label.action.destroy.systemvm.processing=Apagando VM de Sistema.... +label.action.destroy.systemvm=Apagar VM de Sistema +label.action.detach.disk.processing=Desplugando Disco.... +label.action.detach.disk=Desplugar Disco +label.action.detach.iso.processing=Desplugando ISO.... +label.action.detach.iso=Desplugar ISO +label.action.disable.account.processing=Desativando conta.... +label.action.disable.account=Desativar conta +label.action.disable.static.NAT.processing=Desativando NAT Estático.... +label.action.disable.static.NAT=Desativar NAT Estático +label.action.disable.user.processing=Desativando Usuário.... +label.action.disable.user=Desativar Usuário +label.action.download.ISO=Baixar ISO +label.action.download.template=Baixar Template +label.action.download.volume.processing=Baixando Disco.... +label.action.download.volume=Baixar Disco +label.action.edit.ISO=Editar ISO +label.action.edit.account=Editar conta +label.action.edit.disk.offering=Editar Oferta de Disco +label.action.edit.domain=Editar Domínio +label.action.edit.global.setting=Editar Configurações Globais +label.action.edit.instance=Editar Cloud Server +label.action.edit.network.offering=Editar Oferta de Rede +label.action.edit.pod=Editar Pod +label.action.edit.primary.storage=Editar Storage Primário +label.action.edit.resource.limits=Editar Limite de Recursos +label.action.edit.service.offering=Editar Plano +label.action.edit.template=Editar Template +label.action.edit.user=Editar Usurio +label.action.edit.zone=Editar Zona +label.action.enable.account.processing=Ativando conta.... +label.action.enable.account=Ativar conta +label.action.enable.maintenance.mode.processing=Ativando Modo de Manutenção.... +label.action.enable.maintenance.mode=Ativar Modo de Manutenção +label.action.enable.static.NAT.processing=Ativando NAT Estático.... +label.action.enable.static.NAT=Ativar NAT Estático +label.action.enable.user.processing=Habilitando Usurio... +label.action.enable.user=Habilitar usurio +label.action.force.reconnect.processing=Reconectando.... +label.action.force.reconnect=Force Reconnect +label.action.generate.keys.processing=Gerando Chaves.... +label.action.generate.keys=Gerar Chaves +label.action.lock.account.processing=Bloqueando conta.... +label.action.lock.account=Bloquear conta +label.action.migrate.instance=Migrar Cloud Server +label.action.migrate.instance.processing=Migrando Cloud Server... +label.action.reboot.instance.processing=Reiniciando Cloud Server... +label.action.reboot.instance=Reiniciar Cloud Server +label.action.reboot.router.processing=Reiniciando Roteador.... +label.action.reboot.router=Reiniciar Roteador +label.action.reboot.systemvm.processing=Reiniciando VM de Sistema.... +label.action.reboot.systemvm=Reiniciar VM de Sistema +# label.action.recurring.snapshot=Recurring Snapshots +label.action.release.ip.processing=Liberando IP.... +label.action.release.ip=Liberar IP +label.action.remove.host.processing=Removendo Host.... +label.action.remove.host=Remover Host +label.action.reset.password.processing=Recuperando a Senha.... +label.action.reset.password=Recuperar Senha +label.action.resource.limits=Limite de Recursos +label.action.restore.instance.processing=Restaurando Cloud Server... +label.action.restore.instance=Restaurar Cloud Server +label.action.start.instance.processing=Iniciando Cloud Server... +label.action.start.instance=Iniciar Cloud Server +label.action.start.router.processing=Iniciando Roteador.... +label.action.start.router=Iniciar Roteador +label.action.start.systemvm.processing=Iniciando VM de Sistema.... +label.action.start.systemvm=Iniciar VM de Sistema +label.action.stop.instance.processing=Parando Cloud Server... +label.action.stop.instance=Parar Cloud Server +label.action.stop.router.processing=Parando Roteador.... +label.action.stop.router=Parar Roteador +label.action.stop.systemvm.processing=Parando VM de Sistema.... +label.action.stop.systemvm=Parar VM de Sistema +label.action.take.snapshot.processing=Tirando Snapshot.... +label.action.take.snapshot=Tirar Snapshot +label.action.update.OS.preference.processing=Atualizando Preferência de SO.... +label.action.update.OS.preference=Atualizar Preferência de SO +label.actions=Ações +label.active.sessions=Sessões Ativas +label.add.account=Adicionar Conta +label.add.by.cidr=Adicionar por CIDR +label.add.by.group=Adicionar por Grupo +label.add.cluster=Adicionar Cluster +label.add.direct.iprange=Add Direct Ip Range +label.add.disk.offering=Adicionar Oferta de Disco +label.add.domain=Adicionar Domínio +label.add.firewall=Adicionar regra de Firewall +label.add.host=Adicionar Host +label.add.ingress.rule=Adicionar Regra de Entrada +label.add.ip.range=Adicionar Range de IP +label.add.load.balancer=Adicionar Load Balance +label.add.more=Adicionar Mais +label.add.network=Adicionar Rede +label.add.pod=Adicionar POD +label.add.primary.storage=Adicionar Storage Primário +label.add.secondary.storage=Adicionar Storage Secundário +label.add.security.group=Adicionar Security Group +label.add.service.offering=Adicionar Plano +label.add.template=Adicionar Template +label.add.user=Adicionar Usurio +label.add.vlan=Adicionar VLAN +label.add.volume=Adicionar Disco +label.add.zone=Adicionar Zona +label.add=Adicionar +label.adding.cluster=Adicionando Cluster +label.adding.failed=Falha ao Adicionar +label.adding.pod=Adicionando POD +label.adding.processing=Adicionando.... +label.adding.succeeded=Adicionado com Sucesso +label.adding.user=Adicionando Usuário +label.adding.zone=Adicionando Zona +label.adding=Adicionando +label.additional.networks=Redes Adicionais +label.admin.accounts=Contas Administrativas +label.admin=Administrador +label.advanced.mode=Modo Avançado +label.advanced.search=Busca Avançada +label.advanced=Avançado +label.alert=Alerta +label.algorithm=Algoritmo +label.allocated=Alocado +label.api.key=API Key +label.assign.to.load.balancer=Atribuindo o Cloud Server ao Load Balancer +label.assign=Atribuir +label.associated.network.id=ID de Rede Associado +label.attached.iso=Imagem ISO Plugada +label.availability.zone=Datacenter +label.availability=Availability +label.available.public.ips=IP Público Disponível +label.available=Disponível +label.back=Voltar +label.basic.mode=Modo Básico +label.bootable=Inicializável +label.broadcast.domain.type=Tipo de Domínio Broadcast +label.by.account=por Conta +label.by.availability=By Availability +label.by.domain=por Domínio +label.by.end.date=por Data Final +label.by.level=por Nível +label.by.pod=por Pod +label.by.role=por Função +label.by.start.date=por Data Inicial +label.by.state=por estado +label.by.traffic.type=por Tipo de Tráfego +label.by.type.id=por Tipo de ID +label.by.type=Por Tipo +label.by.zone=por Zona +label.bytes.received=Bytes Recebidos +label.bytes.sent=Bytes Enviados +label.cancel=Cancelar +label.certificate=Certificado +label.privatekey=PKCS\#8 Private Key +label.domain.suffix=Sufixo de Domínio DNS (ex. xyz.com) +label.character=Caracter +label.cidr.account=CIDR ou Conta/Security Group +label.close=Fechar +label.cloud.console=Console de Gerenciamento da Nuvem +label.cloud.managed=Cloud.com Managed +label.cluster.type=Tipo de Cluster +label.cluster=Cluster +label.code=Código +label.confirmation=Confirmação +label.cpu.allocated.for.VMs=CPU Alocada por VMs +label.cpu.allocated=CPU Alocada +label.cpu.utilized=CPU Utilizada +label.cpu=CPU +label.created=Criado +label.cross.zones=Inter Zonas +label.custom.disk.size=Tamanho Customizado +label.daily=Diário +label.data.disk.offering=Oferta de Disco Adicional +label.date=Data +label.day.of.month=Dia do Mês +label.day.of.week=Dia da Semana +label.delete=Remover +label.deleting.failed=Falha ao remover +label.deleting.processing=Removendo.... +label.description=Descrição +label.detaching.disk=Desplugando Disco +label.details=Detalhes +label.device.id=ID do Dispositivo +label.disabled=Desativado +label.disabling.vpn.access=Desativando Acesso VPN +label.disk.allocated=Disco Alocado +label.disk.offering=Oferta de Disco +label.disk.size.gb=Tamanho (em GB) +label.disk.size=Tamanho do Disco +label.disk.total=Disco Total +label.disk.volume=Disco +label.display.text=Descrição +label.dns.1=DNS 1 +label.dns.2=DNS 2 +label.domain.admin=Administrador de Domínio +label.domain.id=ID do Domínio +label.domain.name=Nome do Domínio +label.domain=Domínio +label.double.quotes.are.not.allowed=Aspas duplas não são permitidas +label.download.progress=Status do Download +label.edit=Editar +label.email=Email +label.enabling.vpn.access=Ativando Acesso VPN +label.enabling.vpn=Ativando VPN +label.end.port=Porta Final +label.endpoint.or.operation=Endpoint or Operation +label.error.code=Código de Erro +label.error=Erro +label.esx.host=ESX/ESXi Host +label.example=Examplo +label.failed=Falhou +label.featured=Featured +label.firewall=Firewall +label.first.name=Primeiro Nome +label.format=Formato +label.friday=Sexta-feira +label.full=Full +label.gateway=Gateway +label.general.alerts=Alertas Gerais +label.generating.url=Criando URL +label.go.step.2=Vá para passo 2 +label.go.step.3=Vá para passo 3 +label.go.step.4=Vá para passo 4 +label.go.step.5=Vá para passo 5 +label.group.optional=Grupo (Opcional) +label.group=Grupo +label.guest.cidr=CIDR de rede Convidado +label.guest.gateway=Gateway de rede Convidado +label.guest.ip.range=Intervalo de rede convidado +label.guest.ip=Endereço IP Convidado +label.guest.netmask=Máscara de rede Convidado +label.ha.enabled=HA Ativado +label.help=Ajuda +label.host.alerts=Alertas de Host +label.host.name=Host Name +label.host=Host +label.hosts=Hosts +label.hourly=A cada hora +label.hypervisor.type=Tipo do Hypervisor +label.hypervisor=Hypervisor +label.id=ID +label.info=Info +label.ingress.rule=Regra de Entrada +label.initiated.by=Iniciado por +label.instance.limits=Limites do Cloud Server +label.instance.name=Nome do Cloud Server +label.instance=Cloud Server +label.instances=Cloud Servers +label.internal.dns.1=DNS 1 Interno +label.internal.dns.2=DNS 2 Interno +label.interval.type=Tipo de Intervalo +label.invalid.integer=Invalid Integer +label.invalid.number=Número Inválido +label.ip.address=Endereço IP +label.ip.allocations=Alocações de IP +label.ip.limits=Limites de IP Público +label.ip.or.fqdn=IP ou FQDN +label.ip.range=Range de IP +label.ip=IP +label.ips=IPs +label.is.default=\u0089 Padrão +label.is.shared=\u0089 Compartilhado +label.is.system= um sistema +label.iscsi=iSCSI +label.iso.boot=ISO de Boot +label.iso=ISO +label.isolation.mode=Modo Isolado +label.keep=Manter +label.lang.chinese=Chinese (Simplified) +label.lang.english=English +label.lang.japanese=Japanese +label.lang.spanish=Spanish +label.last.disconnected=Last Disconnected +label.last.name=\u009altimo Nome +label.level=Nível +label.linklocal.ip=Endereço IP Link Local +label.load.balancer=Load Balancer +label.loading=Carregando +label.local=Local +# label.local.storage.enabled=Local storage enabled +label.login=Entrar +label.logout=Sair +label.lun=LUN +label.manage=Gerenciar +label.maximum=Máximo +label.memory.allocated=Memória Alocada +label.memory.total=Memória Total +label.memory.used=Memória Usada +label.memory=Memória (em MB) +label.menu.accounts=Contas +label.menu.alerts=Alertas +label.menu.all.accounts=Todas as Contas +label.menu.all.instances=Todos Cloud Servers +label.menu.community.isos=ISOs Públicas +label.menu.community.templates=Templates Públicos +label.menu.configuration=Configurao +label.menu.dashboard=Dashboard +label.menu.destroyed.instances=Cloud Servers Apagados +label.menu.disk.offerings=Oferta de Discos +label.menu.domains=Domínios +label.menu.events=Eventos +label.menu.featured.isos=ISOs Customizada +label.menu.featured.templates=Templates Customizados +label.menu.global.settings=Configurações Globais +label.menu.instances=Cloud Servers +label.menu.ipaddresses=Endereos IP +label.menu.isos=ISOs +label.menu.my.accounts=Minhas Contas +label.menu.my.instances=Meus Cloud Servers +label.menu.my.isos=Minhas ISOs +label.menu.my.templates=Meus Templates +label.menu.network.offerings=Oferta de Rede +label.menu.network=Rede +label.menu.physical.resources=Recursos Físicos +label.menu.running.instances=Cloud Servers Rodando +label.menu.security.groups=Security Groups +label.menu.service.offerings=Planos +label.menu.snapshots=Snapshots +label.menu.stopped.instances=Cloud Servers Parados +label.menu.storage=Storage +label.menu.system.vms=VM de Sistemas +label.menu.system=Sistema +label.menu.templates=Templates +label.menu.virtual.appliances=Appliances Virtuais +label.menu.virtual.resources=Recursos Virtuais +label.menu.volumes=Discos +label.migrate.instance.to=Migrar Cloud Server para +label.minimum=Mínimo +label.minute.past.hour=minuto(s) ltima hora +label.monday=Segunda +label.monthly=Mensal +label.more.templates=Mais Templates +label.my.account=Minha Conta +label.name.optional=Nome (Opcional) +label.name=Nome +label.netmask=Másrca de Rede +label.network.desc=Descrição de Rede +label.network.domain=Domínio de Rede +label.network.id=ID de Rede +label.network.name=Nome da Rede +label.network.offering.display.text=Network Offering Display Text +label.network.offering.id=Network Offering ID +label.network.offering.name=Network Offering Name +label.network.offering=Network Offering +label.network.rate=Taxa de Transferência +label.network.read=Network Read +label.network.type=Tipo de Rede +label.network.write=Network Write +label.network=Rede +label.new.password=Nova Senha +label.next=Próximo +label.nfs.server=Servidor NFS +label.nfs.storage=Storage NFS +label.nfs=NFS +label.nics=REDE +label.no.actions=Sem Ações Disponíveis +label.no.alerts=Sem Alertas Recentes +label.no.errors=Sem Erros Recentes +label.no.isos=Sem ISO Disponível +label.no.items=Sem \u008dtens Disponíveis +label.no.security.groups=Sem Security Groups Disponíveis +label.no.thanks=No obrigado +label.no=No +label.none=Nenhum +label.not.found=Não Encontrado +label.num.cpu.cores=\# de Core CPU +label.numretries=Número de Tentativas +label.offer.ha=Offer HA +label.optional=Opcional +label.os.preference=Preferência de SO +label.os.type=Tipo de SO +label.owned.public.ips=IP Público Utilizado +label.owner.account=Dono da Conta +label.owner.domain=Dono do Domnio +label.parent.domain=Domínio Principal +label.password.enabled=Senha Ativada +label.password=Senha +label.path=Caminho (Path) +label.please.wait=Por Favor Aguarde +label.pod=POD +label.port.forwarding=Encaminhamento de Porta +label.port.range=Range de Porta +label.prev=Prev +label.primary.allocated=Alocação do Storage Primário +label.primary.network=Rede Primária +label.primary.storage=Storage Primário +label.primary.used=Uso do Storage Primário +label.private.interface=Interface Privada +label.private.ip.range=Range de IP Privado +label.private.ip=Endereço IP Privado +label.private.ips=IPs Privados +label.private.port=Porta Privada +label.private.zone=Zona Privada +label.protocol=Protocolo +label.public.interface=Interface Pública +label.public.ip=Endereço IP Público +label.public.ips=IPs Públicos +label.public.port=Porta Pública +label.public.zone=Zona Pública +label.public=Público +label.recent.errors=Erros Recentes +label.refresh=Atualizar +label.related=Relacionado +label.remove.from.load.balancer=Removendo Cloud Server do Load Balancer +label.removing.user=Removendo Usuário +label.required=Obrigatrio +label.reserved.system.ip=IP de Sistema Reservado +label.resource.limits=Limite de Recursos +label.resource=Recurso +label.resources=Recursos +label.role=Função +label.root.disk.offering=Oferta de Disco ROOT +label.running.vms=VMs Rodando +label.saturday=Sábado +label.save=Salvar +label.saving.processing=Salvando.... +label.scope=Escopo +label.search=Pesquisar +label.secondary.storage=Storage Secundário +label.secondary.used=Uso do Storage Secundário +label.secret.key=Chave Secreta +label.security.group.name=Nome do Security Group +label.security.group=Security Group +label.security.groups.enabled=Security Groups Ativado +label.security.groups=Security Groups +label.sent=Enviado +label.server=Servidor +label.service.offering=Plano +label.system.service.offering=System Service Offering +label.session.expired=Sessão Expirada +label.shared=Compatilhado +label.size=Tamanho +label.snapshot.limits=Limites de Snapshot +label.snapshot.name=Nome do Snapshot +label.snapshot.s=Snapshot (s) +# label.snapshot.schedule=Setup Recurring Snapshot +label.snapshot=Snapshot +label.snapshots=Snapshots +label.source.nat=Source NAT +label.specify.vlan=Especificar VLAN +label.start.port=Porta de Início +label.state=Estado +label.static.nat.to=NAT Estático para +label.static.nat=NAT Estático +label.statistics=Estatísticas +label.status=Estado +label.step.1.title=Passo 1\: Selecione o Template +label.step.1=Passo 1 +label.step.2.title=Passo 2\: Plano +label.step.2=Passo 2 +label.step.3.title=Passo 3\: Selecione o Disco Adicional +label.step.3=Passo 3 +label.step.4.title=Passo 4\: Rede +label.step.4=Passo 4 +label.step.5.title=Passo 5\: Revisar +label.step.5=Passo 5 +label.stopped.vms=VMs Paradas +label.storage.type=Tipo de Storage +label.storage=Storage +label.submit=Enviar +label.submitted.by=[Enviado por\: ] +label.succeeded=Sucedido +label.sunday=Domingo +label.system.capacity=Capacidade do Sistema +label.system.vm.type=Tipo de VM de Sistema +label.system.vm=VM de Sistema +label.system.vms=VM de Sistema +label.tagged=Tagged +label.tags=Tags +label.target.iqn=Target IQN +label.template.limits=Limites do Template +label.template=Template +label.theme.default=Tema Padrão +label.theme.grey=Custom - Grey +label.theme.lightblue=Custom - Light Blue +label.thursday=Quinta +label.time.zone=Fuso Horário +label.time=Time +label.timeout.in.second = Timeout(segundos) +label.timezone=Fuso Horário +label.total.cpu=CPU TOTAL +label.total.vms=Total VMs +label.traffic.type=Tipo de Tráfego +label.tuesday=Terça +label.type.id=Tipo do ID +label.type=Tipo +label.unavailable=Indisponível +label.unlimited=Ilimitado +label.untagged=Não Marcado +label.update.ssl.cert=Atualizar Certificado SSL +label.update.ssl=Atualizar Certificado SSL +label.updating=Atualizando +label.url=URL +label.usage.interface=Usage Interface +label.used=Usado +label.user=Usuário +label.username=Nome de Usuário +label.users=Usurios +label.value=Valor +label.vcenter.cluster=vCenter Cluster +label.vcenter.datacenter=vCenter Datacenter +label.vcenter.datastore=vCenter Datastore +label.vcenter.host=vCenter Host +label.vcenter.password=vCenter Password +label.vcenter.username=vCenter Username +label.version=Versão +label.virtual.appliance=Appliance Virtual +label.virtual.appliances=Appliance Virtual +label.virtual.network=Rede Virtual +label.vlan.id=VLAN ID +label.vlan.range=Intervalo de VLAN +label.vm.add=Adicionar Cloud Server +label.vm.destroy=Apagar +label.vm.reboot=Reiniciar +label.vm.start=Incio +label.vm.stop=Parar +label.vmfs=VMFS +label.vms=VMs +label.volume.limits=Limites de Disco +label.volume.name=Nome do Disco +label.volume=Disco +label.volumes=Discos +label.vsphere.managed=vSphere Managed +label.waiting=Aguardando +label.warn=Avisar +label.wednesday=Quarta-Feira +label.weekly=Semanal +label.welcome.cloud.console=Painel de Controle +label.welcome=Bem-Vindo +label.yes=Sim +label.zone.id=ID da Zona +label.zone.step.1.title=Passo 1\: Selecionar a Rede +label.zone.step.2.title=Passo 2\: Adicionar a Zona +label.zone.step.3.title=Passo 3\: Adicionar o POD +label.zone.step.4.title=Passo 4\: Adicionar um Intervalo de IP +# label.zone.wide=Zone-Wide +label.zone=Zona + +#Messages +message.acquire.public.ip=Selecione a zona de onde você deseja adquirir o novo IP +message.action.cancel.maintenance.mode=Confirme que você deseja cancelar esta manutenção +message.action.cancel.maintenance=A manutenção do seu HOST foi cancelada com sucesso +message.action.delete.ISO.for.all.zones=Esta ISO é usada por todas as Zonas. Confirme se você deseja excluir a ISO de todas as Zonas +message.action.delete.ISO=Confirme que você deseja excluir esta ISO +message.action.delete.cluster=Confirme que você deseja excluir este HOST +message.action.delete.disk.offering=Confirme que você deseja excluir esta oferta de disco +message.action.delete.domain=Confirme que você deseja excluir este domínio +message.action.delete.external.firewall=Confirme que você gostaria de remover este Firewall externo. Aviso\: Se você está planejando adicionar novamente este mesmo Firewall, é necessário apagar os contadores do dispositivo. +message.action.delete.external.load.balancer=Confirme que você gostaria de remover este Load Balancer Externo. Aviso\: Se você está planejando adicionar novamente este mesmo Load Balancer, é necessário apagar os contadores do dispositivo. +message.action.delete.ingress.rule=Confirme que você deseja excluir esta regra de entrada. +message.action.delete.network=Confirme que você deseja remover esta rede. +message.action.delete.pod=Confirme que você deseja remover este POD. +message.action.delete.primary.storage=Confirme que você deseja remover este Storage Primário. +message.action.delete.secondary.storage=Confirme que você deseja remover este Storage Secundário. +message.action.delete.security.group=Confirme que você deseja remover este Security Group. +message.action.delete.service.offering=Confirme que você deseja remover este Plano. +message.action.delete.snapshot=Confirme que você deseja remover este Snapshot. +message.action.delete.template.for.all.zones=Este Template é usado por todas as zonas. Confirme que você deseja remover o Template de todas as zonas. +message.action.delete.template=Confirme que você deseja remover este Template. +message.action.delete.volume=Confirme que você deseja remover este Disco. +message.action.delete.zone=Confirme que você deseja remover esta Zona. +message.action.destroy.instance=Confirme que você deseja excluir este Cloud Server. +message.action.destroy.systemvm=Confirme que você deseja excluir esta VM de Sistema. +message.action.disable.static.NAT=Confirme que você deseja desativar o NAT estático. +message.action.enable.maintenance=O Host foi preparado com sucesso para manutenção. Este processo poderá levar alguns minutos ou mais dependendo do número de VMs hospedadas neste Host. +message.action.force.reconnect=O procedimento de reconexão forçada foi preparado com sucesso. Este processo poderá levar alguns minutos. +message.action.host.enable.maintenance.mode=Ativar o modo de manutenção irá causar o live migration de todos Cloud Server hospedados neste Host para o próximo disponível. +message.action.instance.reset.password=Por favor confirme que voc deseja alterar a senha de ROOT para est mquina virtual. +message.action.primarystorage.enable.maintenance.mode=Aviso\: Colocar o Storage primário em modo de manutenção irá causar a parada de todas as VMs hospedadas nesta unidade. Deseja continuar? +message.action.reboot.instance=Confirme que você deseja reiniciar este Cloud Server. +message.action.reboot.systemvm=Confirme que você deseja reiniciar esta VM de sistema. +message.action.release.ip=Confirme que você deseja liberar este IP. +message.action.remove.host=Remover o único/último host do cluster e reinstalar o host irá provocar a perda do ambiente/banco do host tornando os Cloud Servers inutilizáveis. +message.action.restore.instance=Confirme que você deseja restaurar este Cloud Server. +message.action.start.instance=Confirme que você deseja iniciar este Cloud Server. +message.action.start.router=Confirme que você deseja inciar este roteador. +message.action.start.systemvm=Confirme que você deseja iniciar esta VM de sistema. +message.action.stop.instance=Confirme que você deseja parar este Cloud Server. +message.action.stop.systemvm=Confirme que você deseja parar esta VM de Sistema. +message.action.take.snapshot=Por favor confirme que voc deseja criar um snapshot deste volume. +message.add.cluster.zone=Add a hypervisor managed cluster for zone +message.add.cluster=Add a hypervisor managed cluster for zone , pod +message.add.disk.offering=Especifique o seguintes parâmetros para adicionar uma nova oferta de disco. +message.add.firewall=Adicionar Firewall à zona. +message.add.host=Especifique os seguintes parâmetros para adicionar um novo host. +message.add.ip.range.direct.network=Add an IP range to direct network in zone +message.add.ip.range.to.pod=

Add an IP range to pod\:

+message.add.ip.range=Add an IP range to public network in zone +message.add.load.balancer=Add a load balancer to zone +message.add.network=Add a new network for zone\: +message.add.pod=Add a new pod for zone +message.add.primary.storage=Adicionar novo Storage primário à zona , pod +message.add.primary=Especifique os seguintes parâmetros para adicionar um novo Storage primário. +message.add.secondary.storage=Add a new storage for zone +message.add.service.offering=Por favor preencha os dados abaixo para adicionar uma nova oferta de computao. +message.add.template=Entre com os dados para criar um novo template. +message.add.volume=Entre com os dados para criar um novo disco. +message.additional.networks.desc=Selecione a(s) rede(s) adicionais que seu Cloud Server terá acesso. +message.advanced.mode.desc=Escolhe este modelo de rede se deseja ter habilitar o suporte a VLAN. Este modelo permite maior flexibilidade ao administrador ao permitir ofertas de rede customizada, firewall, vpn ou load balancer bem como acesso via rede virtual ou acesso direto. +message.advanced.security.group=Escolha esta opção se desejar utilizar Security Groups para isolamento das VMs guest. +message.advanced.virtual=Escolha esta opção se desejar utilizar VLANs para isolamento das VMs guest. +message.allow.vpn.access=Entre com nome de usuário e senha do usuário que terá acesso VPN. +message.attach.iso.confirm=Confirme que você deseja conectar a ISO ao Cloud Server. +message.attach.volume=Preencha os seguintes dados para conectar o novo disco. Se você está conectando um disco a um Cloud Server Windows, será necessário reiniciar o Cloud Server para visualizar o novo disco. +message.basic.mode.desc=Escolha este modelo de rede se você *não* quer suporte a VLAN. Todo Cloud Server criado neste modelo de rede estará ligado diretamente a um IP da rede e será usado Security Groups para prover segurança e separação. +message.change.offering.confirm=Confirme que você deseja mudar o plano deste Cloud Server. +message.copy.iso.confirm=Confirme se você deseja copiar a ISO para +message.copy.template=Copiar template XXX da zona para +message.create.template.vm=Criar VM do template +message.create.template.volume=Especifique as seguintes informações antes de criar o template a partir do disco\: . A criação de um template a partir de um disco pode levar alguns minutos ou mais dependendo do tamnho do disco. +message.delete.account=Confirme se você deseja excluir esta conta. +message.detach.iso.confirm=Confirme se você deseja desconectar a ISO do Cloud Server. +message.disable.account=Por favor confirme que voc deseja desabilitar esta conta. Aps desabilitar uma conta, todos os usurios desta conta no iro possuir mais acesso aos seus recursos da cloud. Todas as mquinas virtuais sero automaticamente desligadas. +message.disable.vpn.access=Confirme se você deseja desativar o acesso VPN. +message.download.ISO=Por favor clique 00000 para baixar o ISO +message.download.template=Por favor clique 00000 para baixar o template +message.download.volume=Clique 00000 para baixar o disco +message.edit.confirm=Por favor confirme suas alteraes antes de clicar em "Salvar". +message.edit.limits=Especifique os limites para os seguintes recursos. "-1" indica sem limite para o total de recursos criados. +message.enable.account=Confirme se você deseja ativar a conta. +message.enable.vpn.access=VPN está desativada para este endereço IP. Gostaria de ativar o acesso VPN? +message.enabled.vpn.ip.sec=Sua chave IPSec (pre-shared) é +message.enabled.vpn=Seu acesso VPN está ativado e pode ser acessado através do IP +message.launch.vm.on.private.network=Voc deseja executar sua instncia na sua prpria rede privada dedicada ? +message.lock.account=Confirme se você deseja bloquear esta conta. Bloqueando a conta, todos os usuários desta conta não estarão mais habilitados a gerenciar os recursos na nuvem. Os recursos existentes (Cloud Server) ainda poderão ser acessados. +message.migrate.instance.confirm=Confirme o host que você deseja migrar o Cloud Server. +message.new.user=Especifique abaixo para adicionar novos usurios para a conta +message.no.network.support.configuration.not.true=Voc no possui nenhuma zona com grupos de segurana habilitado. Assim sendo, no possui recursos adicionais de rede. Por favor continue para o passo 5. +message.no.network.support=O hypervisor escolhido, vSphere, não possui nenhum recurso de rede adicional. Por favor, vá para o passo 5. +message.number.clusters=

Clusters

+message.number.hosts=

Hosts

+message.number.pods=

PODs

+message.number.storage=

Volumes do Storage Primário

+message.number.zones=

Zonas

+message.remove.vpn.access=Confirme se você deseja remover acesso VPN do seguinte usuário. +message.restart.mgmt.server=Reinicie o(s) servidor(es) de gerenciamento para que a nova configuração tenha efeito. +message.restart.mgmt.usage.server=Por favor reinicie seu servidor(es) de gerenciamento e seu servidor(es) de utilizao para as mudanas entrarem em efeito. +message.security.group.usage=(Use Ctrl-clique para selecionar todos os Security Groups) +message.snapshot.schedule=Você pode configurar Snapshots recorrentes agendados selecionando as opções disponíveis abaixo +message.step.1.continue=Selecione o template ou ISO para continuar +message.step.1.desc=Selecione o template para o novo Cloud Server. +message.step.2.continue=Selecione o plano +message.step.2.desc= +message.step.3.continue=Seleciona a oferta de disco +message.step.3.desc= +message.step.4.continue=Selecione pelo menos uma rede para continuar +message.step.4.desc=Selecione a rede principal que seu Cloud Server será conectado. +message.update.os.preference=Escolha o SO de preferencia para este host. Todos Cloud Server com preferencias similares serão alocados neste host antes de tentar em outro. +message.update.ssl=Envie o novo certificado SSL X.509 para ser atualizado em cada console proxy\: +message.virtual.network.desc=Rede virtual dedicado para sua conta. O domínio de broadcast está na VLAN e todo acesso a internet é roteado através do virtual router. +message.volume.create.template.confirm=Confirme se você deseja criar um template a partir deste disco. A criação do template pode levar alguns minutos ou mais dependendo do tamanho do disco. +message.zone.step.1.desc=Seleciona o modelo de rede para a zona. +message.zone.step.2.desc=Entre a informao a seguir para adicionar uma nova zona +message.zone.step.3.desc=Entre a informao a seguir para adicionar um novo pod +message.apply.snapshot.policy=Você atualizou com sucesso sua política de Snapshot. +message.disable.snapshot.policy=Você desativou com sucesso sua política de Snapshot. +message.action.change.service.warning.for.instance=Para troca de plano é necessário parar o Cloud Server. +message.action.change.service.warning.for.router=O roteador precisa ser desligado antes de trocar o plano/tamanho. +message.action.reset.password.warning=Para recuperar a senha é necessário parar o Cloud Server. +message.action.reset.password.off=Seu Cloud Server não suporta esta funcionalidade. + +#Errors +error.login=Usuário ou senha inválido. +error.menu.select=No foi possvel realizar a ao pois nenhum item foi selecionado. +error.mgmt.server.inaccessible=O servidor de gerenciamento está inacessível. Tente novamente mais tarde. +error.session.expired=Sua sessão expirou. +error.unresolved.internet.name=Impossível resolver DNS diff --git a/client/WEB-INF/classes/resources/messages_ru_RU.properties b/client/WEB-INF/classes/resources/messages_ru_RU.properties new file mode 100644 index 00000000000..0c6b962d1cf --- /dev/null +++ b/client/WEB-INF/classes/resources/messages_ru_RU.properties @@ -0,0 +1,1514 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + + +#new labels (begin) ********************************************************************************************** +# label.isolation.uri=Isolation URI +# label.broadcast.uri=Broadcast URI +#new labels (end) ************************************************************************************************ + + +#modified labels (begin) ***************************************************************************************** +# message.zoneWizard.enable.local.storage=WARNING\: If you enable local storage for this zone, you must do the following, depending on where you would like your system VMs to launch\:

1. If system VMs need to be launched in primary storage, primary storage needs to be added to the zone after creation. You must also start the zone in a disabled state.

2. If system VMs need to be launched in local storage, system.vm.use.local.storage needs to be set to true before you enable the zone.


Would you like to continue? +#modified labels (end) ******************************************************************************************* + +# label.configure.network.ACLs=Configure Network ACLs +# label.network.ACLs=Network ACLs +# label.add.network.ACL=Add network ACL +# label.private.Gateway=Private Gateway +# label.VPC.router.details=VPC router details +# label.VMs.in.tier=VMs in tier +# label.local.storage.enabled=Local storage enabled +# label.tier.details=Tier details +# label.edit.tags=Edit tags +label.action.enable.physical.network=Включить физическую сеть +label.action.disable.physical.network=Отключить физическую сеть +message.action.enable.physical.network=Подтвердите, что вы действительно хотите включить эту физическую сеть. +message.action.disable.physical.network=Подтвердите, что вы действительно хотите выключить эту физическую сеть. + +# label.select.tier=Select Tier +# label.add.ACL=Add ACL +# label.remove.ACL=Remove ACL +# label.tier=Tier +# label.network.ACL=Network ACL +# label.network.ACL.total=Network ACL Total +# label.add.new.gateway=Add new gateway +# message.add.new.gateway.to.vpc=Please specify the information to add a new gateway to this VPC. +# label.delete.gateway=delete gateway +# message.delete.gateway=Please confirm you want to delete the gateway +# label.CIDR.of.destination.network=CIDR of destination network +# label.add.route=Add route +# label.add.static.route=Add static route +# label.remove.static.route=Remove static route +# label.site.to.site.VPN=site-to-site VPN +# label.add.VPN.gateway=Add VPN Gateway +# message.add.VPN.gateway=Please confirm that you want to add a VPN Gateway +# label.VPN.gateway=VPN Gateway +# label.delete.VPN.gateway=delete VPN Gateway +# message.delete.VPN.gateway=Please confirm that you want to delete this VPN Gateway +# label.VPN.connection=VPN Connection +# label.IPsec.preshared.key=IPsec Preshared-Key +# label.IKE.policy=IKE policy +# label.ESP.policy=ESP policy +# label.create.VPN.connection=Create VPN Connection +# label.VPN.customer.gateway=VPN Customer Gateway +# label.CIDR.list=CIDR list +# label.IKE.lifetime=IKE Lifetime (second) +# label.ESP.lifetime=ESP Lifetime(second) +# label.dead.peer.detection=Dead Peer Detection +# label.reset.VPN.connection=Reset VPN connection +# message.reset.VPN.connection=Please confirm that you want to reset VPN connection +# label.delete.VPN.connection=delete VPN connection +# message.delete.VPN.connection=Please confirm that you want to delete VPN connection +# label.add.new.tier=Add new tier +# label.add.VM.to.tier=Add VM to tier +# label.remove.tier=Remove tier + +# label.local.storage.enabled=Local storage enabled +# label.associated.network=Associated Network +# label.add.port.forwarding.rule=Add port forwarding rule +# label.dns=DNS + +# label.vpc=VPC +# label.vpc.id=VPC ID +# label.tier=Tier +# label.add.vpc=Add VPC +# label.super.cidr.for.guest.networks=Super CIDR for Guest Networks +# label.DNS.domain.for.guest.networks=DNS domain for Guest Networks +# label.configure.vpc=Configure VPC +# label.edit.vpc=Edit VPC +# label.restart.vpc=restart VPC +# message.restart.vpc=Please confirm that you want to restart the VPC +# label.remove.vpc=remove VPC +# message.remove.vpc=Please confirm that you want to remove the VPC +# label.vpn.customer.gateway=VPN Customer Gateway +# label.add.vpn.customer.gateway=Add VPN Customer Gateway +# label.IKE.encryption=IKE Encryption +# label.IKE.hash=IKE Hash +# label.IKE.DH=IKE DH +# label.ESP.encryption=ESP Encryption +# label.ESP.hash=ESP Hash +# label.perfect.forward.secrecy=Perfect Forward Secrecy +# label.IKE.lifetime=IKE Lifetime (second) +# label.ESP.lifetime=ESP Lifetime(second) +# label.dead.peer.detection=Dead Peer Detection +# label.delete.VPN.customer.gateway=delete VPN Customer Gateway +# message.delete.VPN.customer.gateway=Please confirm that you want to delete this VPN Customer Gateway + +label.network.domain.text=Текст домена сети +label.memory.mb=Память (в МБ) +label.cpu.mhz=CPU (в Мгц) + +message.action.remove.host=Удаление последнего/единственного сервера в кластере и повторная его установка приведет уничтожению рабочего окружения/базы данных на сервере и сделае гостевые машины непригодными к использованию. + +message.action.reboot.router=Подтвердите, что вы действительно хотите перезагрузить этот роутер. +message.action.stop.router=Подтвердите, что вы действительно хотите остановить этот роутер. +message.restart.network=Подтвердите, что вы действительно хотите перезапустить сеть. + + +label.ipaddress=IP адресса +label.vcdcname=Имя vCenter DC +label.vcipaddress=vCenter IP Адресс +label.vsmctrlvlanid=Управление VLAN ID +label.vsmpktvlanid=Пакет VLAN ID +label.vsmstoragevlanid=Хранение VLAN ID +label.nexusVswitch=Nexus Vswitch +label.action.delete.nexusVswitch=Удалить NexusVswitch +label.action.enable.nexusVswitch=Включить NexusVswitch +label.action.disable.nexusVswitch=Отключить NexusVswitch +label.action.list.nexusVswitch=Лист NexusVswitch +message.action.delete.nexusVswitch=Пожалуйста, подтвердите, что вы хотите удалить это nexusVswitch. +message.action.enable.nexusVswitch=Пожалуйста, подтвердите, что вы хотите включить это nexusVswitch. +message.action.disable.nexusVswitch=Пожалуйста, подтвердите, что вы хотите отключить эту nexusVswitch. +message.specify.url=Пожалуйста, укажите URL +label.select.instance.to.attach.volume.to=Выбирите сервер для добавления обьема +label.upload=Загрузить +label.upload.volume=Добавить объем +label.virtual.routers=Виртуальный роутер +label.primary.storage.count=Первичный архив для хранения +label.secondary.storage.count=Вторичный архив для хранения +label.number.of.system.vms=Количество системы виртуальных машин +label.number.of.virtual.routers=Количество виртуальных маршрутизаторов +label.action.register.iso=Регистрация ISO +label.isolation.method=Метод изоляции +label.action.register.template=Регистрация шаблона +label.checksum=Проверить MD5 сумму +label.vpn=VPN +label.vlan=VLAN + + +label.management.ips=Панель управления IP адрессами +label.devices=Устройство +label.rules=Правила +label.traffic.label=Трафик +label.vm.state=Статус сервера +message.setup.physical.network.during.zone.creation.basic=При добавления в основную зону, вы можите создать одну физическую сеть, которая соотвествует NIC на гипервизор. Сеть осуществляет несколько видов трафика.

Вы можете также перетаскивать drag and drop другие типы трафика на физические сети. +label.domain.router=Машрутизатор +label.console.proxy=Прокси +label.secondary.storage.vm=Вторичный файловый сервер +label.add.netScaler.device=Добавить Netscaler устройство +label.add.F5.device=Добавить F5 устройво +label.add.SRX.device=Добавить SRX устройство +label.account.and.security.group=Аккаунт, группы безопасности +label.fetch.latest=Выборка последних +label.system.offering=Система размещения +message.validate.instance.name=Имя сервера не может быть длинее 63 символа. Только ASCII, буквы a~z, A~Z, цыфры 0~9, дефис не допускается. Должна начинаться с буквы и заканчиваться буквой или цифрой. + + +label.isolated.networks=Изолированные сети +label.latest.events=Последнии события +state.Enabled=Включено +label.system.wide.capacity=Общесистемного потенциала +label.network.service.providers=Поставщики сетевых служб +message.launch.zone=Зона готова к запуску, пожалуйста, перейдите к следующему шагу. +error.unable.to.reach.management.server=Не удается подключиться к серверу управления +label.internal.name=Внутреннее имя +message.configure.all.traffic.types=У вас есть несколько физических сетей, пожалуйста, настроить метки для каждого типа трафика, нажав на кнопку Изменить. +message.edit.traffic.type=Пожалуйста, укажите трафик метки вы хотите, связанных с этим типом трафика. +label.edit.traffic.type=Изменить тип трафика +label.label=Метка +label.max.networks=Максимум сетей +error.invalid.username.password=Неправильній логин или пароль +message.enabling.security.group.provider=Включение поставщика засищеной сети +message.adding.Netscaler.provider=Добавить Netscaler +message.creating.guest.network=Создать гостевую сеть +label.action.delete.physical.network=Удаление физической сети +message.action.delete.physical.network=Пожалуйста, подтвердите, что вы хотите удалить этот физическую сеть +message.installWizard.copy.whatIsAHost=Узел - это отдельный компьютер. Узлы предоставляют вычислительные ресурсы для запуска гостевых виртуальных машин. Каждый узел содержит гипервизор для управления ВМ (кроме узлов BareMetal, они являются исключением из правил и рассматривается в расширенном руководстве по установке). Например, это Linux-сервер с KVM, сервер Citrix XenServer или сервер ESXI. При простой установке вы можете использовать один узел с XenServer.

Узел - это наименьшая единица в платформе CloudStack&\#8482;, далее узлы распологаются в кластерах, кластеры - в стендах, стенды - в зонах. + + +label.add.compute.offering=Добавить вычисления предложение +label.compute.offering=Вычислить предложение +label.compute.offerings=Вычислить предложений +label.select.offering=Выберите предложение +label.menu.infrastructure=Инфорструктура +label.sticky.tablesize=Размер таблицы +label.sticky.expire=Истекает +label.sticky.cookie-name=Cookie имя +label.sticky.mode=Режим +label.sticky.length=Длина +label.sticky.holdtime=время удержания +label.sticky.request-learn=Требуется изучение. +label.sticky.prefix=Префикс +label.sticky.nocache=Нет кэша +label.sticky.indirect=Косвенный +label.sticky.postonly=Сообщение только +label.sticky.domain=Домен +state.Allocating=Выделение +state.Migrating=Мигрирующий +error.please.specify.physical.network.tags=Сеть предложений не доступна, пока вы указать теги для этого физической сети. + + +state.Stopping=Остановить +message.add.load.balancer.under.ip=Правило балансировки нагрузки был добавлен в IP\: +message.select.instance=Пожалуйста, выберите сервер. +label.select=Выбрать +label.select.vm.for.static.nat=Выбор VM для NAT +label.select.instance=Выбирите сервер +label.nat.port.range=NAT диапазон портов +label.static.nat.vm.details=Статистика NAT виртуальных машин +label.edit.lb.rule=Редактировать LB правила +message.migrate.instance.to.host=Подтвердите, что вы действительно хотите перенести машину на другой узел. +label.migrate.instance.to.host=Перенос машины на другой узел +message.migrate.instance.to.ps=Подтвердите, что вы действительно хотите перенести машину на другое основное хранилище. +label.migrate.instance.to.ps=Перенос машины на другое основное хранилище +label.corrections.saved=Изменения сохранены +message.installWizard.copy.whatIsSecondaryStorage=Дополнительное хранилище привязано к зоне и содержит следующее\:
  • Шаблоны - образы ОС, которые можно использовать для загрузки ВМ и содержащие дополнительную информацию, такую как установленные приложения.
  • Образы ISO - это загрузочные или незагрузочные образы ОС
  • Снимки дисковых томов - сохраненные копии данных ВМ, которых можно использовать для восстановления данных или для создания нового шаблона
+message.installWizard.copy.whatIsPrimaryStorage=CloudStack&\#8482; - это облачная платформа, использующая два типа хранилища\: основное и дополнительное. В качестве хранилищ можно использовать iSCSI или NFS-сервер, а также локальный диск.

Основное хранилище привязано к кластеру и содержит дисковые тома каждой ВМ, запущенной в узлах этого кластера. Как правило, основное хранилище размещается в самих узлах. +message.installWizard.copy.whatIsACluster=Кластер предоставляет группы узлов. Узлы в кластере имеют одинаковое оборудование, запущены в одинаковом гипервизере, находятся в одной подсети и имеют доступ к одному и тому же общему хранилищу. Виртуальные машины могут быть перенесены "вживую" с одного узла на другой в пределах кластера, без остановки служб пользователем. Кластер - третья по размерности единица в платформе CloudStack&\#8482;. Кластеры распоогаются в стендах, а стенды - в зонах.

CloudStack&\#8482; разрешает использовать несколько кластеров, но при простой установке эта возможность отсутствует. +message.installWizard.copy.whatIsAPod=Стенд, как правило, предоставляет одну стойку с машинами. Узлы в одном стенде расположены в одной подсети.

Стенд - вторая по размерности единица в платформе CloudStack&\#8482;. Стенды распологаются в зонах. Каждая зона может содержать несколько стендов, но при простой установке в зоне можно создать лишь один стенд. +message.installWizard.copy.whatIsAZone=Зона - это наиболее крупная организационная единица в платформе CloudStack&\#8482;. Зона обычно соответствует единичному ЦОД, хотя имеется возможность использовать несколько зон в пределах одного ЦОД. Основным преимуществом построения инфраструктуры с использование зон является обеспечение изолирования и избыточности. Например, каждая зона может иметь свой блок питания и сеть, а сами зоны могут широко расположены географически. +message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482 - это программная плафторма для создания публичных, частных и гибридных облаков по схеме «Инфраструктура как сервис» (IaaS). CloudStack&\#8482 управляет сетью, хранилищем и вычислительными узлами, входящие в облачную инфраструктуру. Главным образом, CloudStack&\#8482 используется для развертывания, управления и настройкой сложных облачных решений.

CloudStack&\#8482 реализует предоставление как услуги целого центра обработки данных с необходимыми компонентами для создания сложных инфраструктур на основе облака. Мы можете выбрать между свободной и Безнес-версиями, которые почти ничем не отличаются. +message.installWizard.tooltip.addSecondaryStorage.path=Путь экспорта, расположенный на вышеуказанном сервере. +message.installWizard.tooltip.addSecondaryStorage.nfsServer=IP-адрес сервера NFS, где находится дополнительное хранилище +message.installWizard.tooltip.addPrimaryStorage.path=(для NFS) В NFS это путь экпорта сервера. Путь (для ОткрытойТочкиДоступа). В KVM это путь для каждого узла, который указывает расположение основного хранилища. Например, "/mnt/primary". +message.installWizard.tooltip.addPrimaryStorage.server=(для NFS, iSCSI или PreSetup) IP-адрес или имя DNS устройства хранилища. +message.installWizard.tooltip.addPrimaryStorage.name=Имя устройства хранилища. +message.installWizard.tooltip.addHost.password=Этот пароль для вышеуказанного пользователя (с вашего XenServer) +message.installWizard.tooltip.addHost.username=Обычно root. +message.installWizard.tooltip.addHost.hostname=Имя DNS или IP-адрес узла. +message.installWizard.tooltip.addCluster.name=Имя кластера. Вы можете сами выбрать имя, не используемый Cloudstack. +message.installWizard.tooltip.addPod.reservedSystemEndIp=Это диапазон IP частной сети, который используется CloudStack для ВМ дополнительного хранилища и консольного прокси. Эти адреса получаются из сети вычислительных серверов. +message.installWizard.tooltip.addPod.reservedSystemStartIp=Это диапазон IP частной сети, который используется CloudStack для ВМ дополнительного хранилища и консольного прокси. Эти адреса получаются из сети вычислительных серверов. +message.installWizard.tooltip.addPod.reservedSystemNetmask=Сетевая маска подсети для гостей. +message.installWizard.tooltip.addPod.reservedSystemGateway=Шлюз для узлов этого стенда. +message.installWizard.tooltip.addPod.name=Имя стенда +message.installWizard.tooltip.configureGuestTraffic.guestEndIp=Диапазон IP-адресов, которые будут доступны для гостей этой зоны. При использовании одного сетевого устройства (NIC) эти адреса должны быть в подсети (CIDR) стенда. +message.installWizard.tooltip.configureGuestTraffic.guestStartIp=Диапазон IP-адресов, которые будут доступны для гостей этой зоны. При использовании одного сетевого устройства (NIC) эти адреса должны быть в подсети (CIDR) стенда. +message.installWizard.tooltip.configureGuestTraffic.guestNetmask=Сетевая маска подсети для гостей. +message.installWizard.tooltip.configureGuestTraffic.guestGateway=Шлюз для гостями +message.installWizard.tooltip.configureGuestTraffic.description=Описание этой сети +message.installWizard.tooltip.configureGuestTraffic.name=Имя этой сети +message.installWizard.tooltip.addZone.internaldns2=Это cерверы DNS для системных ВМ этой зоны. Эти серверы будут доступны через частный интерфейс системной ВМ. Частный IP-адрес, предоставленный в стенде, должен иметь маршрут к этим серверам DNS. +message.installWizard.tooltip.addZone.internaldns1=Это cерверы DNS для системных ВМ этой зоны. Эти серверы будут доступны через частный интерфейс системной ВМ. Частный IP-адрес, предоставленный в стенде, должен иметь маршрут к этим серверам DNS. +message.installWizard.tooltip.addZone.dns2=Это cерверы DNS для гостевых ВМ этой зоны. Эти серверы будут доступны через публичный интерфейс, который вы добавите позже. Публичные IP-адреса, предоставленные в зоне, должны иметь маршрут к этим серверам DNS. +message.installWizard.tooltip.addZone.name=Имя зоны +message.installWizard.tooltip.addZone.dns1=Это cерверы DNS для гостевых ВМ этой зоны. Эти серверы будут доступны через публичный интерфейс, который вы добавите позже. Публичные IP-адреса, предоставленные в зоне, должны иметь маршрут к этим серверам DNS. +message.setup.successful=Настройка облака завершена\! +label.may.continue=Вы можете продолжить. +error.installWizard.message=Что-то не так. Вернитесь назад и исправьте ошибки. +message.installWizard.now.building=Ваше облако создаётся... +message.installWizard.click.retry=Кликните, чтобы повторить запуск. +label.launch=Запуск +label.installWizard.click.launch=Кликните на кнопку запуска +label.congratulations=Поздравляем\! +label.installWizard.addSecondaryStorageIntro.subtitle=Что такое "Дополнительное хранилище"? +label.installWizard.addSecondaryStorageIntro.title=Давайте добавим допольнительное хранилище. +label.installWizard.addPrimaryStorageIntro.subtitle=Что такое "Основное хранилище"? +label.installWizard.addPrimaryStorageIntro.title=Давайте добавим основное хранилище +label.installWizard.addHostIntro.subtitle=Что такое "Узел"? +label.installWizard.addHostIntro.title=Давайте добавим узел +label.installWizard.addClusterIntro.subtitle=Что такое "Кластер"? +label.installWizard.addClusterIntro.title=Давайте добавим кластер +label.installWizard.addPodIntro.subtitle=Что такое "Стенд"? +label.installWizard.addPodIntro.title=Давайте добавим стенд +label.installWizard.addZone.title=Добавить зону +label.installWizard.addZoneIntro.subtitle=Что такое "Зона"? +label.installWizard.addZoneIntro.title=Давайте добавим зону +error.password.not.match=Пароли не совпадают +label.confirm.password=Подтвердите пароль +message.change.password=Измените ваш пароль. +label.save.and.continue=Сохранить и продолжить +label.skip.guide=Я уже великий мастер CloudStack, пропустить это руководство +label.continue.basic.install=Продолжить простую установку +label.introduction.to.cloudstack=Введение в CloudStack +label.what.is.cloudstack=Что такое CloudStack? +label.hints=Подсказки +label.installWizard.subtitle=Это руководство настроит ваш CloudStack. +label.continue=Продолжить +label.installWizard.title=Здравствуйте и добро пожаловать в CloudStack\! +label.agree=Согласен +label.license.agreement=Лицензионное соглашение +label.license.agreement.subtitle=Для продолжения установки согласитесь с лицензионным соглашением. +label.manage.resources=Управление ресурсами +label.port.forwarding.policies=Политики проброса портов +label.load.balancing.policies=Политики балансировки нагрузки +label.networking.and.security=Сеть и безопасность +label.bandwidth=Пропускная способность +label.virtual.machines=Виртуальные машины +label.compute.and.storage=Вычисления и хранилище +label.task.completed=Задача выполнена +label.update.project.resources=Обновить ресурсы проекта +label.remove.project.account=Удалить учетную запись проекта +label.item.listing=Список элементов +message.select.item=Выберите элемент +label.removing=Удаление +label.invite=Пригласить +label.add.by=Добавить +label.max.vms=Макс. количество пользовательских ВМ +label.max.public.ips=Макс. публичных IP +label.max.volumes=Макс. томов +label.max.snapshots=Макс. снимков +label.max.templates=Макс. шаблонов +# label.max.vpcs=Max. VPCs +label.project.dashboard=Панель проекта +label.remind.later=Предупредить позже +label.invited.accounts=Приглашённые учетные записи +label.invite.to=Пригласить +label.add.accounts.to=Добавить учётные записи +label.add.accounts=Добавить аккаунты +label.project.name=Имя проекта +label.create.project=Создать проект +label.networks=Сети +label.launch.vm=Запуск ВМ +label.new.vm=Новая ВМ +label.previous=Предыдущий +label.add.to.group=Добавить в группу +message.vm.review.launch=Проверьте следующую информацию и удостоверьтесь в том, что ваша машина настроена правильно. +message.select.security.groups=Выберите группу/группы безопасности для новой ВМ +label.new=Создать +message.please.select.networks=Выберите сети для виртуальной машины +message.please.proceed=Перейдите к следующему шагу +message.zone.no.network.selection=Выбранная зона не имеет вариантов для выбора сети. +label.no.thanks=Нет, спасибо +label.my.templates=Мои шаблоны +message.select.template=Выберите шаблон для новой ВМ +message.select.iso=Выберите образ ISO для новой ВМ +message.template.desc=Образ ОС, который можно использовать в качестве загрузочной в ВМ +message.iso.desc=Образ диска содержит загрузочные или незагрузочные данные для ОС. +label.select.iso.or.template=Выберите ISO или шаблон +message.select.a.zone=Зона обычно соответствует единичному центру обработки данных. Несколько зоныпомогают создавать более надежные облака, обеспечивая физическую изоляцию и избыточность. +label.select.a.zone=Выберите зону +label.review=Обзор +label.select.a.template=Выберите шаблон +label.setup=Настройка +state.Allocated=Распределено +changed.item.properties=Параметры элемента изменены +label.apply=Применить +label.default=По умолчанию +label.viewing=Просмотр +label.move.to.top=Переместить на самый верх +label.move.up.row=Переместить на одну строку выше +label.move.down.row=Переместить на одну строку ниже +# label.move.to.bottom=Move to bottom +label.drag.new.position=Переместить на новую позицию +label.order=Очередь +label.no.data=Нет информации для показа +label.change.value=Изменить значение +label.clear.list=Очистить список +label.full.path=Полный путь +message.add.domain=Укажите поддомен, где вы хотите создать ваш домен +message.delete.user=Подтвердите, что вы действительно хотите удалить этого пользователя. +message.enable.user=Подтвердите, что вы действительно хотите включить этого пользователя. +message.disable.user=Подтвердите, что вы действительно хотите выключить этого пользователя. +message.generate.keys=Подтвердите, что вы действительно хотите создать новые ключи для этого пользователя. +message.update.resource.count=Подтвердите, что вы действительно хотите обновить счетчик ресурсов для этого аккаунта. +message.edit.account=Редактировать (значение "-1" показывает отсутствие пределов для ресурса) +label.total.of.vm=Всего ВМ +label.total.of.ip=Всего IP-адресов +state.enabled=Включено +message.action.download.iso=Подтвердите, что вы действительно хотите загрузить этот ISO. +message.action.download.template=Подтвердите, что вы действительно хотите загрузить этот шаблон. +label.destination.zone=Целевая зона +label.keyboard.type=Тип клавиатуры +label.nic.adapter.type=Тип сетевой карты (NIC) +label.root.disk.controller=Контроллер корневого диска +label.community=Сообщество +label.remove.egress.rule=Удалить выходное правило +label.add.egress.rule=Добавить выходное правило +label.egress.rule=Выходное правило +label.remove.ingress.rule=Удалить входное правило +label.delete.vpn.user=Удалить пользователя VPN +label.add.vpn.user=Добавить пользователя VPN +label.remove.pf=Удалить правило проброса порта +label.remove.vm.from.lb=Удалить ВМ с правила балансировки нагрузки +label.add.vms.to.lb=Добавить ВМ в правило балансировки нагрузки +label.add.vm=Добавить ВМ +label.remove.static.nat.rule=Удалить правило статичного NAT +label.remove.rule=Удалить правило +label.add.static.nat.rule=Добавить правило статичного NAT +label.add.rule=Добавить правило +label.configuration=Конфигурация +message.disable.vpn=Вы действительно хотите выключить VPN? +label.disable.vpn=Выключить VPN +message.enable.vpn=Подтвердите, что вы действительно хотите открыть доступ к VPN для этого IP-адреса. +label.enable.vpn=Включить VPN +message.acquire.new.ip=Подтвердите, что вы действительно хотите получить "белый" IP для этой сети. +label.elastic=Гибкий +label.my.network=Моя сеть +label.add.vms=Добавить ВМ +label.configure=Настроить +label.stickiness=Липкий +label.source=Источник +label.least.connections=Least connections +label.round.robin=Round-robin +label.restart.required=Требуется перезапуск +label.clean.up=Очистить +label.restart.network=Перезапустить сеть +label.edit.network.details=Редактировать детали сети +label.add.guest.network=Добавить гостевую сеть +label.guest.networks=Гостевые сети +message.ip.address.changed=Ваши IP-адреса могли быть изменены, хотите обновить список адресов? Помните, что в этом случае область деталей будет закрыта. +state.BackingUp=Резервное копирование +state.BackedUp=Зарезервировано +label.done=Готово +label.vm.name=Имя VM +message.migrate.volume=Подтвердите, что вы действительно хотите перенести том в другое основное хранилище. +label.migrate.volume=Перенести том в другое основное хранилище +message.create.template=Вы действительно хотите создать шаблонн? +label.create.template=Создать шаблон +message.download.volume.confirm=Подтвердите, что вы действительно загрузить этот том +message.detach.disk=Вы действительно хотите присоединить этот диск? +state.ready=Готов +state.Ready=Готов +label.vm.display.name=Отображаемое имя ВМ +label.select-view=Выберите вид +label.local.storage=Локальное хранилище +label.direct.ips=Прямые IP-адреса +label.view.all=Просмотреть всё +label.zone.details=Подробности зоны +message.alert.state.detected=Обнаружен сигнал тревоги +state.Starting=Запускается +state.Expunging=Удалён +state.Creating=Создается +message.decline.invitation=Подтвердите, что вы хотите отменить приглашение на проект. +label.decline.invitation=Отменить приглашение +message.confirm.join.project=Подтвердите присоединение к проекту. +message.join.project=Теперь вы присоединены к проекту. Выберите "Проектный вид" для просмотра проекта. +label.accept.project.invitation=Принять приглашение на проект +label.token=Талон +label.project.id=ID проекта +message.enter.token=Введите ключ, который вы получили в пригласительном письме +label.enter.token=Введите талон +state.Accepted=Принято +state.Pending=Ожидается +state.Completed=Завершено +state.Declined=Отклонено +label.project=Проект +label.invitations=Приглашения +label.delete.project=Удалить проект +message.delete.project=Вы действительно хотите удалить этот проект? +message.activate.project=Вы действительно хотите запустить этот проект? +label.activate.project=Запустить проект +label.suspend.project=Приостановить проект +message.suspend.project=Вы действительно хотите приостановить проект? +state.Suspended=Приостановлено +label.edit.project.details=Редактировать детали проекта +label.new.project=Новый проект +state.Active=Включен +state.Disabled=Выключен +label.projects=Проекты +label.make.project.owner=Сделать аккаунт владельцем проекта +label.remove.project.account=Удалить учетную запись проекта +message.project.invite.sent=Приглашение было отправлено пользователю; он будет добавлен в проект после подтверждения приглашения. +label.add.account.to.project=Добавить аккаунт в проект +label.revoke.project.invite=Отозвать приглашение +label.project.invite=Пригласить в проект +label.select.project=Выберите проект +message.no.projects=У вас нет проектов.
Создайте новый проект в секции "Проекты" +message.no.projects.adminOnly=У вас нет проектовю
Обратитесь к вашему администратору для создания нового проекта. +message.pending.projects.1=В ожидании следующие приглашения\: +message.pending.projects.2=Для просмотра перейдите к раздел проектов, далее выберите приглашения из выпадающего меню. +message.instanceWizard.noTemplates=Вы не имеете доступных шаблонов; для перезапуска машины добавьте совместивый шаблон. +label.view=Вид +instances.actions.reboot.label=Перезагрузить машину +label.filterBy=Фильтровать +label.ok=OK +notification.reboot.instance=Перезагрузить машину +notification.start.instance=Запустить машину +notification.stop.instance=Остановить машину +label.display.name=Отображаемое имя +label.zone.name=Имя зоны +ui.listView.filters.all=Все +ui.listView.filters.mine=Mine +state.Running=Запущено +state.Stopped=Остановлено +state.Destroyed=Уничтожено +state.Error=Ошибка +message.reset.password.warning.notPasswordEnabled=Шаблон для этой машины создан без использования пароля +message.reset.password.warning.notStopped=Для изменения пароля необходимо остановить машину +label.notifications=Оповещения +label.default.view=Стандартный вид +label.project.view=Проектный вид + +message.add.system.service.offering=Дополните следующую информацию для добавления нового ресурса для системных служб. +message.action.delete.system.service.offering=Подтвердите, что вы действительно хотите удалить этот ресурс для системных служб. +label.action.delete.system.service.offering=Удалить системный ресурс +label.hypervisor.capabilities=Возможности гипервизора +label.hypervisor.version=Версия гипервизора +label.max.guest.limit=Предел количества гостей +label.add.network.offering=Добавить сетевой ресурс +label.supported.services=Поддерживаемые службы +label.service.capabilities=Возможности службы +label.guest.type=Тип гостя +label.specify.IP.ranges=Укажите диапазон IP-адресов +label.conserve.mode=Экономичный режим +label.created.by.system=Создано системой +label.menu.system.service.offerings=Системные ресурсы +label.add.system.service.offering=Добавить системный ресурс +label.redundant.router.capability=Возможности резервного роутера +label.supported.source.NAT.type=Поддерживаемые типы NAT-источника +label.elastic.LB=Гибкий LB +label.LB.isolation=Изоляция LB +label.elastic.IP=Гибкий IP +label.network.label.display.for.blank.value=Исп. основной шлюз +label.xen.traffic.label=Метка трафика XenServer +label.kvm.traffic.label=Метка трафика KVM +label.vmware.traffic.label=Метка трафика VMware +label.start.IP=Начальный IP +label.end.IP=Конечный IP +label.remove.ip.range=Удалить диапазон IP +label.ip.ranges=Диапазоны IP +label.start.vlan=Начальный VLAN +label.end.vlan=Конечный VLAN +label.broadcast.domain.range=Диапазон широковещательного домена +label.compute=Вычисление +message.add.guest.network=Подтвердите, что вы действительно хотите добавить гостевую сеть +label.subdomain.access=Доступ к поддомену +label.guest.start.ip=Начальный гостевой IP +label.guest.end.ip=Конечный гостевой IP. +label.virtual.router=Виртуальный роутер +label.physical.network.ID=ID физической сети +label.destination.physical.network.id=ID целевой физической сети +label.dhcp=DHCP +label.destroy.router=Удалить роутер +message.confirm.destroy.router=Подтвердите, что вы действительно хотите удалить роутер +label.change.service.offering=Изменить служебный ресурс +label.view.console=Показать консоль +label.redundant.state=Состояние резерва +label.enable.provider=Включить поставщика +message.confirm.enable.provider=Подтвердите, что вы действительно хотите включить поставщика +label.disable.provider=Выключить поставщика +message.confirm.disable.provider=Подтвердите, что вы действительно хотите выключить поставщика +label.shutdown.provider=Отключить поставщика +message.confirm.shutdown.provider=Подтвердите, что вы действительно хотите отключить этого поставщика +label.netScaler=NetScaler +label.add.new.NetScaler=Добавить новый NetScaler +label.capacity=Мощность +label.dedicated=Выделенный +label.f5=F5 +label.add.new.F5=Добавить новый F5 +label.srx=SRX +label.providers=Поставщики +label.add.new.SRX=Добавить новый SRX +label.timeout=Время ожидания +label.public.network=Публичная сеть +label.private.network=Частная сеть +label.enable.swift=Включить Swift +confirm.enable.swift=Заполните нижеследующую информацию для включения поддержи Swift +message.after.enable.swift=Swift настроен. Примечание\: Если вы покинете эту страницу, вам не придется настраивать Swift снова +label.key=Ключ +label.delete.NetScaler=Удалить NetScaler +message.confirm.delete.NetScaler=Подтвердите, что вы действительно хотите удалить NetScaler +label.delete.F5=Удалить F5 +message.confirm.delete.F5=Подтвердите, что вы действительно хотите удалить F5 +label.delete.SRX=Удалить SRX +message.confirm.delete.SRX=Подтвердите, что вы действительно хотите удалить SRX +label.pods=Стенды +label.pod.name=Имя стенда +label.reserved.system.gateway=Зарезервированный системный шлюз +label.reserved.system.netmask=Зарезервированная системная маска +label.start.reserved.system.IP=Начальный зарезервированный системный IP-адрес +label.end.reserved.system.IP=Конечный зарезервированный системный IP-адрес +label.clusters=Кластеры +label.cluster.name=Имя кластера +label.host.MAC=MAC узла +label.agent.username=Имя агента +label.agent.password=Пароль агента +message.confirm.action.force.reconnect=Подтвердите, что вы действительно хотите переподключиться к узлу +label.resource.state=Состояние ресурсов +label.LUN.number=LUN \# +message.confirm.remove.IP.range=Подтвердите, что вы действительно хотите удалить этот диапазон IP. +message.tooltip.zone.name=Имя для зоны +message.tooltip.dns.1=Имя сервера DNS для ВМ этой зоны. Публичные IP-адреса этой зоны должны иметь маршрут до этого сервера. +message.tooltip.dns.2=Имя второго сервера DNS для ВМ этой зоны. Публичные IP-адреса этой зоны должны иметь маршрут до этого сервера. +message.tooltip.internal.dns.1=Имя сервера DNS для внутренних ВМ CloudStack этой зоны. Частные IP-адреса стендов должны иметь маршрут до этого сервера. +message.tooltip.internal.dns.2=Имя сервера DNS для внутренних ВМ CloudStack этой зоны. Частные IP-адреса стендов должны иметь маршрут до этого сервера. +message.tooltip.network.domain=Суффикс DNS для создания собственного доменного имени сети, доступный гостевыми ВМ. +message.tooltip.pod.name=Имя для стенда +message.tooltip.reserved.system.gateway=Шлюз для узлов этого стенда +message.tooltip.reserved.system.netmask=Префикс сети, определяющий подсеть стенда. Используется обозначение CIDR. +message.creating.zone=Создание зоны +message.creating.physical.networks=Создание физических сетей +message.configuring.physical.networks=Настройка физических сетей +message.adding.Netscaler.device=Добавление устройства NetScaler +message.creating.pod=Создание стенда +message.configuring.public.traffic=Настройка публичного трафика +message.configuring.storage.traffic=Настройка трафика хранилища +message.configuring.guest.traffic=Настройка гостевого трафика +message.creating.cluster=Создание кластера +message.adding.host=Добавление узла +message.creating.primary.storage=Создание основного хранилища +message.creating.secondary.storage=Создание дополнительного хранилища +message.Zone.creation.complete=Создание зоны завершено +message.enabling.zone=Включить зону +error.something.went.wrong.please.correct.the.following=Что-то не так, исправьте ошибки +error.could.not.enable.zone=Не удалось включить зону +message.zone.creation.complete.would.you.like.to.enable.this.zone=Создание зоны завершено. Хотите включить эту зону? +message.please.add.at.lease.one.traffic.range=Добавьте как минимум один диапазон для трафика +message.you.must.have.at.least.one.physical.network=Добавьте как минимум одну физическую сеть +message.please.select.a.different.public.and.management.network.before.removing=Выберите другую публичную и обслуживающую сеть перед удалением + +label.zone.type=Тип зоны +label.setup.zone=Настройка зоны +label.setup.network=Настройка сети +label.add.resources=Добавить ресурсов +label.launch=Запуск +label.set.up.zone.type=Настроить тип зоны +message.please.select.a.configuration.for.your.zone=Выберите конфигурацию вашей зоны +message.desc.basic.zone=Предоставляет едиственную сеть, где каждая ВМ имеет «белый» IP-адрес сети. Изоляции гостей можно добиться использованием сети 3-го уровня, например, группы безопасности (фильтрация IP-вдресов) +label.basic=Простой +message.desc.advanced.zone=Для более сложных сетевых топологий. Эта сетевая модель обеспечивает максимальную гибкость в определении гостевой сети и предоставление услуг, таких как межсетевой экран, VPN, или поддержка балансировки нагрузки. +label.advanced=Продвинутый +message.desc.zone=layer 3 +label.physical.network=Физические сети +label.public.traffic=Публичный трафик +label.guest.traffic=Гостевой трафик +label.storage.traffic=Трафик хранилища +message.setup.physical.network.during.zone.creation=Во время расширенной настройки зоны, вам необходимо указать один или несколько физических сетей. Каждая сеть соответствует сетевому интерфейсу гипервизора. Какждая физическая сеть может использоваться для одного или нескольких видов трафика с некоторыми ограничениями при объединении видов трафика.

Перетащите один или несколько видов трафика к каждой физической сети. +label.add.physical.network=Добавить физическую сеть +label.traffic.types=Типы трафика +label.management=Управление +label.guest=Гость +label.please.specify.netscaler.info=Укажите данные NetScaler +message.public.traffic.in.advanced.zone=Публичный трафик генерируется при получения ВМ доступа к Интернету. Публично доступные IP должны быть обязательно выделены. Пользователь может ииспользовать CloudStack UI для получения IP и создания NAT, используемый для общения между гостевой и публичной сетью.

Укажите как минимум один диапазон адресов для интернет-трафика. +message.public.traffic.in.basic.zone=Публичный трафик генерируется при получения ВМ доступа к Интернету или при предоставлении клиентам служб через Интернет. Публично доступные IP должны быть обязательно выделены. При создании ВМ, адрес из диапазона публичных Ip привяжется к машине в дополнение гостевого адреса IP. Статический 1-1 NAT должен автоматически настроиться на работу между публичной и гостевой сетью. Пользователь также имеет возможность использовать CloudStack UI для получения дополнительных адресов для реализации статического NAT между машинами и публичной сетью. +message.add.pod.during.zone.creation=Каждая зона содержит один или более стендов, который вы сейчас добавите первым. Стенд содержит узлы и серверы основного хранилища, которые будут добавлены в последнем шаге. Для начала необходимо настроить диапазон резервных адресов IP для внутренней сети управления. Диапазон резервных IP должен быть уникальным для каждой зоны облака. +message.guest.traffic.in.advanced.zone=Гостевой трафик сети связи между конечными пользователями виртуальных машин. Укажите диапазон идентификаторов VLAN проводить гостя трафик для каждой физической сети. +message.guest.traffic.in.basic.zone=Гостевой трафик генерируется при общении между виртуальными машинами. Укажите диапазон адресов IP, который CloudStack сможет выделить для ВМ. Убедитесь, что этот диапазон не перекрещивается с диапазоном резервных адресов. +message.storage.traffic=Трафик между внутренними ресурсами CloudStack, включая все компоненты, которые взаимодействуют с сервером управления, такие как виртуальные хосты и CloudStack системы. Настройте трафик хранения здесь. +message.desc.cluster=Каждый стенд должен иметь один или более кластеров, первый из которых вы сейчас добавите. Кластер предоставляет группу узлов. Узлы в кластере имеют одинаковое оборудование, запускается через один гипервизор, находятся в одной сети и имеют доступ к одному и тому же открытому хранилищу. Каждый кластер содержит один или более узлов, а также иеть один или несколько основных хранилищ. +message.desc.host=Каждый кластер должен содержать как минимум один узел (компьютер) для запуска ВМ, первый из кластер вы добавите сейчас. Для работы узла в CloudStack важна установка гипервизора на узел, привязка IP к узлу и соединение узла с сервером управления CloudStack.

Укажите имя DNS или адрес IP, имя пользователя и пароль к ОС (обычно root), а также метки для группирования узлов. +message.desc.primary.storage=Каждая группа должна содержать один или несколько первичных серверов хранения данных, и мы добавим первый сейчас. Первичная хранения содержит логические разделы жесткого диска для всех виртуальных машин, работающих на узлах кластера. Используйте любой совместимый протокол, который поддерживает основные гипервизора. +message.desc.secondary.storage=Каждая зона должна обладать хотя бы одним сервером NFS или дополнительным хранилищем и их надо добавить в первую очередь. Дополнительное хранилище предназначено для хранения шаблонов ВМ, образов ISO и снимков ВМ. Этот сервер должен быть доступен для всех узлов зоны.

Предоставить IP-адрес и путь. +label.launch.zone=Запустить зону +message.please.wait.while.zone.is.being.created=Подождите, создается зона. Это может занять некоторое время... + +label.load.balancing=Балансировка нагрузки +label.static.nat.enabled=Статический NAT включен +label.zones=Зоны +label.view.more=Просмотреть больше +label.number.of.zones=Количество зон +label.number.of.pods=Количество стендов +label.number.of.clusters=Количество кластеров +label.number.of.hosts=Количество узлов +label.total.hosts=Всего узлов +label.total.CPU=Всего процессоров +label.total.memory=Всего памяти +label.total.storage=Всего хранилищ +label.purpose=Назначение + + + + +label.action.migrate.router=Перенести роутер +label.action.migrate.router.processing=Перенос роутера... +message.migrate.router.confirm=Подтвердите, что вы действительно хотите перенести роутер в узел +label.migrate.router.to=Перенести роутер в + +label.action.migrate.systemvm=Перенести системную ВМ +label.action.migrate.systemvm.processing=Перенос системной ВМ... +message.migrate.systemvm.confirm=Подтвердите, что вы действительно хотите перенести роутер в узел +label.migrate.systemvm.to=Перенести системную ВМ в + + +mode=Режим +side.by.side=Бок-о-Бок +inline=Встроенный + +extractable=Извлекаемый + +label.ocfs2=OCFS2 + +label.action.edit.host=Редактировать узел + +network.rate=Скорость сети + +ICMP.type=Тип ICMP +ICMP.code=Код ICMP + +image.directory=Каталог с образами + +label.action.create.template.from.vm=Создать шаблон из ВМ +label.action.create.template.from.volume=Создать шаблон из тома + +message.vm.create.template.confirm=Создание шаблона автоматически перезагрузит ВМ + +label.action.manage.cluster=Управление кластером +message.action.manage.cluster=Подтвердите, что вы действительно хотите перевести кластер в режим обслуживания. +label.action.manage.cluster.processing=Переход кластера в режим обслуживания... + +label.action.unmanage.cluster=Перевести кластер в обычный режим +message.action.unmanage.cluster=Подтвердите, что вы действительно хотите перевести кластер в обычный режим. +label.action.unmanage.cluster.processing=Переход кластера в обычный режим... + +label.allocation.state=Состояние распределения +managed.state=Состояние обслуживания + +label.default.use=По умолчанию +label.host.tags=Метки узла + +label.cidr=CIDR +label.cidr.list=CIDR источника + +label.storage.tags=Метки хранилища + +label.redundant.router=Резервной роутер +label.is.redundant.router=Резервной + +force.delete=Принудительно удалить +force.delete.domain.warning=Внимание\: При выборе этого варианта приведет к удалению всех дочерних доменов и все связанные с ними аккаунтов и их ресурсов. + +force.remove=Принудительно удалить +force.remove.host.warning=Внимание\: При выборе этой опции будет вызыван CloudStack для принудительной остановики всех виртуальных машин, прежде чем снимать этот узел из кластера.. + +force.stop=Принудительно остановить +force.stop.instance.warning=Внимание\: Принудительная остановка должна применяться в самуюпоследнюю очередь. Вы можете потерять данные или получить неожиданное поведение/состояние виртуальной машины. + +label.PreSetup=Предварительная настройка +label.SR.name = SR Name-Label +label.SharedMountPoint=ОткрытаяТочкаДоступа +label.clvm=CLVM +label.volgroup=Группа тома +label.VMFS.datastore=Хранилище VMFS + +label.network.device=Сетевое устройство +label.add.network.device=Добавить сетевое устройство +label.network.device.type=Тип сетевого устройства +label.DHCP.server.type=Тип сервера DHCP +label.Pxe.server.type=Тип сервера PXE +label.PING.storage.IP=IP адрес PING-хранилища +label.PING.dir=Каталог PING +label.TFTP.dir=Каталог TFTP +label.PING.CIFS.username=Имя пользователя PING CIFS +label.PING.CIFS.password=Пароль PING CIFS +label.CPU.cap=CPU Cap + + +label.action.enable.zone=Включить зону +label.action.enable.zone.processing=Включение зоны... +message.action.enable.zone=Потдтвердите, что вы действительно хотите включить эту зону +label.action.disable.zone=Выключить зону +label.action.disable.zone.processing=Выключение зоны... +message.action.disable.zone=Подтвердите, что вы действительно хотите выключить эту зону + +label.action.enable.pod=Включить стенд +label.action.enable.pod.processing=Включение стенда.. +message.action.enable.pod=Подтвердите, что вы действительно хотите включить этот стенд. +label.action.disable.pod=Выключить стенд +label.action.disable.pod.processing=Выключение стенда. +message.action.disable.pod=Подтвердите, что вы действительно хотите выключить эту зону. + +label.action.enable.cluster=Включить кластер +label.action.enable.cluster.processing=Включение кластера... +message.action.enable.cluster=Подтвердите, что вы действительно хотите включить этот кластер. +label.action.disable.cluster=Выключить кластер +label.action.disable.cluster.processing=Выключение кластера... +message.action.disable.cluster=Подтвердите, что вы действительно хотите выключить этот кластер. + +label.account.id=ID учётной записи +label.account.name=Имя учётной записи +label.account.specific=Специфика аккауннта +label.account=Учётная запись +label.accounts=Учётные записи +label.acquire.new.ip=Получить новый IP +label.show.ingress.rule=Показать входное правило +label.hide.ingress.rule=Скрыть входное правило +label.action.attach.disk.processing=Прикрепление диска... +label.action.attach.disk=Прикрепить диск +label.action.attach.iso.processing=Прикрепление ISO... +label.action.attach.iso=Прикрепить ISO +label.action.cancel.maintenance.mode.processing=Отмена режима обслуживания... +label.action.cancel.maintenance.mode=Отменить режим обслуживания +label.action.change.password=Изменить пароль +label.action.change.service.processing=Изменение службы... +label.action.change.service=Изменить службу +label.action.copy.ISO.processing=Копирование ISO... +label.action.copy.ISO=Копировать ISO +label.action.copy.template.processing=Копирование шаблона... +label.action.copy.template=Копировать шаблон +label.action.create.template.processing=Создание шаблона... +label.action.create.template=Создать шаблон +label.action.create.vm.processing=Создание ВМ... +label.action.create.vm=Создать ВМ +label.action.create.volume.processing=Создание тома... +label.action.create.volume=Создать том +label.action.delete.IP.range.processing=Удаление диапазона IP... +label.action.delete.IP.range=Удалить диапазон IP +label.action.delete.ISO.processing=Удаление ISO... +label.action.delete.ISO=Удалить ISO +label.action.delete.account.processing=Удаление учётной записи... +label.action.delete.account=Удалить учётную запись +label.action.delete.cluster.processing=Удаление кластера... +label.action.delete.cluster=Удалить кластер +label.action.delete.disk.offering.processing=Удаление дискового ресурса... +label.action.delete.disk.offering=Удалить дисковый ресурс + +label.action.update.resource.count=Обновить счётчик ресурсов +label.action.update.resource.count.processing=Обновление счетчика ресурсов... + +label.action.delete.domain=Удалить домен +label.action.delete.domain.processing=Удаление домена... + +label.action.delete.firewall.processing=Удаление фаервола... +label.action.delete.firewall=Удалить правило фаервола +label.action.delete.ingress.rule.processing=Удаление входного правила... +label.action.delete.ingress.rule=Удалить входное правило +label.action.delete.load.balancer.processing=Удаление балансировки нагрузки... +label.action.delete.load.balancer=Удалить правило балансировки нагрузки +label.action.edit.network.processing=Редактирование сети... +label.action.edit.network=Редактировать сеть +label.action.delete.network.processing=Удаление сети... +label.action.delete.network=Удалить сеть +label.action.delete.pod.processing=Удаление стенда... +label.action.delete.pod=Удалить стенд +label.action.delete.primary.storage.processing=Удаление основного хранилища... +label.action.delete.primary.storage=Удалить основное хранилище +label.action.delete.secondary.storage.processing=Удаление дополнительного хранилища... +label.action.delete.secondary.storage=Удалить дополнительное хранилище +label.action.delete.security.group.processing=Удаление группы безопасности... +label.action.delete.security.group=Удалить группу безопасности +label.action.delete.service.offering.processing=Удаление служебного ресурса... +label.action.delete.service.offering=Удалить служебный ресурс +label.action.delete.snapshot.processing=Удаление снимка... +label.action.delete.snapshot=Удалить снимок +label.action.delete.template.processing=Удаление шаблона... +label.action.delete.template=Удалить шаблон +label.action.delete.user.processing=Удаление пользователя... +label.action.delete.user=Удалить пользователя +label.action.delete.volume.processing=Удаление тома... +label.action.delete.volume=Удалить том +label.action.delete.zone.processing=Удаление зоны... +label.action.delete.zone=Удалить зону +label.action.destroy.instance.processing=Уничтожение машины... +label.action.destroy.instance=Уничтожить машину +label.action.destroy.systemvm.processing=Уничтожение системного ВМ... +label.action.destroy.systemvm=Уничтожить системный ВМ +label.action.detach.disk.processing=Открепление диска... +label.action.detach.disk=Открепить диск +label.action.detach.iso.processing=Открепление ISO +label.action.detach.iso=Открепить ISO +label.action.disable.account.processing=Выключение учётной записи +label.action.disable.account=Выключить учётную запись +label.action.disable.static.NAT.processing=Выключение статичного NAT... +label.action.disable.static.NAT=Выключить статичный NAT +label.action.disable.user.processing=Выключение пользователя +label.action.disable.user=Выключить пользователя +label.action.download.ISO=Загрузить ISO +label.action.download.template=Загрузить шаблон +label.action.download.volume.processing=Загрузка тома... +label.action.download.volume=Загрузить том +label.action.edit.ISO=Редактировать ISO +label.action.edit.account=Редактировать учётную запись +label.action.edit.disk.offering=Редактировать дисковый ресурс +label.action.edit.domain=Редактировать домен +label.action.edit.global.setting=Редактировать глобальные настройки +label.action.edit.instance=Редактировать машину +label.action.edit.network.offering=Редактировать сетевой ресурс +label.action.edit.pod=Редактировать стенд +label.action.edit.primary.storage=Редактировать основное хранилище +label.action.edit.resource.limits=Редактировать пределы ресурсов +label.action.edit.service.offering=Редактировать служебный ресурс +label.action.edit.template=Редактировать шаблон +label.action.edit.user=Редактировать пользователя +label.action.edit.zone=Редактировать зону +label.action.enable.account.processing=Включение аккаунта... +label.action.enable.account=Включить учётную запись +label.action.enable.maintenance.mode.processing=Включение режима обслуживания... +label.action.enable.maintenance.mode=Включить режим обслуживания +label.action.enable.static.NAT.processing=Включение статичного NAT.. +label.action.enable.static.NAT=Включить статичный NAT +label.action.enable.user.processing=Включение пользователя... +label.action.enable.user=Включить пользователя +label.action.force.reconnect.processing=Переподключение... +label.action.force.reconnect=Принудительно переподключить +label.action.generate.keys.processing=Создание ключей... +label.action.generate.keys=Создать ключи +label.action.lock.account.processing=Блокирования учётной записи +label.action.lock.account=Заблокировать учётную запись +label.action.migrate.instance=Перенести машину +label.action.migrate.instance.processing=Перенос машины...... +label.action.reboot.instance.processing=Перезагрузка машины... +label.action.reboot.instance=Перезагрузить машину +label.action.reboot.router.processing=Перезагрузка роутера... +label.action.reboot.router=Перезагрузить роутер +label.action.reboot.systemvm.processing=Перезагрузка системной ВМ +label.action.reboot.systemvm=Перезапустить системную ВМ +label.action.recurring.snapshot=Повторяемые снимки +label.action.release.ip.processing=Освобождение IP... +label.action.release.ip=Освободить IP +label.action.remove.host.processing=Удаление узла... +label.action.remove.host=Удалить узел +label.action.reset.password.processing=Сброс пароля... +label.action.reset.password=Сбросить пароль +label.action.resource.limits=Пределы ресурсов +label.action.restore.instance.processing=Восстановление машины... +label.action.restore.instance=Восстановить машину +label.action.start.instance.processing=Запуск машины... +label.action.start.instance=Запустить машину +label.action.start.router.processing=Запуск роутера +label.action.start.router=Запустить роутер +label.action.start.systemvm.processing=Запуск системной ВМ... +label.action.start.systemvm=Запустить системную ВМ +label.action.stop.instance.processing=Остановка машины... +label.action.stop.instance=Остановить машину +label.action.stop.router.processing=Остановка роутера... +label.action.stop.router=Остановить роутер +label.action.stop.systemvm.processing=Остановка системной ВМ... +label.action.stop.systemvm=Остановить системной ВМ +label.action.take.snapshot.processing=Получение снимка... +label.action.take.snapshot=Получить снимок... +label.action.update.OS.preference.processing=Обновление параметров ОС... +label.action.update.OS.preference=Обновить параметры ОС +label.actions=Действия +label.active.sessions=Активные сессии +label.add.account=Добавить аккаунт +label.add.by.cidr=Добавить к CIDR +label.add.by.group=Добавить к группе +label.add.cluster=Добавить кластер +label.add.direct.iprange=Добавить диапазон прямых IP +label.add.disk.offering=Новый дисковый ресурс +label.add.domain=Добавить домен +label.add.firewall=Добавить правило фаервола. +label.add.host=Добавить узел +label.add.ingress.rule=Новое входное правило +label.add.ip.range=Добавить диапазон IP +label.add.load.balancer=Добавить балансировку нагрузки +label.add.more=Добавить что-то еще +label.add.network=Добавить сеть +label.add.pod=Добавить стенд +label.add.primary.storage=Добавить основное хранилище +label.add.secondary.storage=Добавить дополнительное хранилище +label.add.security.group=Добавить группу безопасности +label.add.service.offering=Новый системный ресурс +label.add.template=Добавить шаблон +label.add.user=Добавить пользователя +label.add.vlan=Добавить VLAN +label.add.volume=Добавить том +label.add.zone=Добавить зону +label.add=Добавить +label.adding.cluster=Добавление кластера +label.adding.failed=Не удалось добавить +label.adding.pod=Добавление стенда +label.adding.processing=Добавление... +label.adding.succeeded=Добавление завершено успешно +label.adding.user=Добавление пользователя +label.adding.zone=Добавление зоны +label.adding=Добавление зоны +label.additional.networks=Дополнительные сети +label.admin.accounts=Администраторские учётные записи +label.admin=Администратор +label.advanced.mode=Продвинутый режим +label.advanced.search=Расширенный поиск +label.advanced=Продвинутый +label.alert=Тревога +label.algorithm=Алгоритм +label.allocated=Распределено +label.api.key=Ключ API +label.assign.to.load.balancer=Включение машины в систему балансировки нагрузки +label.assign=Присвоить +label.associated.network.id=Связанный ID сети +label.attached.iso=Прикрепленный ISO +label.availability.zone=Доступность зоны +label.availability=Доступность +label.available.public.ips=Доступные публичные IP-адреса +label.available=Доступно +label.back=Назад +label.basic.mode=Просто режим +label.bootable=Загружаемый +label.broadcast.domain.type=Тип широковещательного домена +label.by.account=По учётной записи +label.by.availability=По доступности +label.by.domain=До домену +label.by.end.date=По завершению +label.by.level=По уровню +label.by.pod=По стенду +label.by.role=По роли +label.by.start.date=По началу +label.by.state=По состоянию +label.by.traffic.type=По типу трафика +label.by.type.id=По типу ID +label.by.type=По типу +label.by.zone=По зоне +label.bytes.received=Байт получен +label.bytes.sent=Байт отправлено +label.cancel=Отмена +label.certificate=Сертификат +label.privatekey=Частный ключ PKCS\#8 +label.domain.suffix=Суффикс домена DNS (нпр. xyz.com) +label.character=Символов +label.cidr.account=CIDR или учётная запись/группа безопасности +label.close=Закрыть +label.cloud.console=Консоль управления облаком +label.cloud.managed=Панель управления +label.cluster.type=Тип кластера +label.cluster=Кластер +label.code=Код +label.confirmation=Подтверждение +label.cpu.allocated.for.VMs=Распределено ЦПУ для ВМ +label.cpu.allocated=Распределено ЦПУ +label.cpu.utilized=Использование CPU +label.cpu=CPU +label.created=Создано +label.cross.zones=Общие для зон +label.custom.disk.size=Свой размер диска +label.daily=Ежедневно +label.data.disk.offering=Данные диска +label.date=Дата +label.day.of.month=День месяца +label.day.of.week=День недели +label.delete=Удалить +label.deleting.failed=Не удалось удалить +label.deleting.processing=Удаление... +label.description=Описание +label.detaching.disk=Открепление диска +label.details=Детали +label.device.id=ID устройства +label.disabled=Выключено +label.disabling.vpn.access=Выключение доступа к VPN +label.disk.allocated=Распределено дискового пространства +label.disk.offering=Дисковый ресурс +label.disk.size.gb=Размер диска (в ГБ) +label.disk.size=Размер диска +label.disk.total=Всего в дисках +label.disk.volume=Том диска +label.display.text=Отображаемый текст +label.dns.1=DNS 1 +label.dns.2=DNS 2 +label.domain.admin=Администратор домена +label.domain.id=ID домена +label.domain.name=Имя домена +label.domain=Домен +label.double.quotes.are.not.allowed=Двойные кавычки запрещены +label.download.progress=Статус загрузки +label.edit=Редактировать +label.email=E-mail +label.enabling.vpn.access=Включение доступа к VPN +label.enabling.vpn=Включение VPN +label.end.port=Конечный порт +label.endpoint.or.operation=Конечная точка или операция +label.error.code=Код ошибки +label.error=Ошибка +label.esx.host=Узел ESX/ESXi +label.example=Пример +label.failed=Неудачно +label.featured=Представленный +label.firewall=Фаервол +label.first.name=Имя +label.format=Формат +label.friday=Пятница +label.full=Полный +label.gateway=Шлюз +label.general.alerts=Общие тревоги +label.generating.url=Создание URL +label.go.step.2=Перейти к шагу 2 +label.go.step.3=Перейти к шагу 3 +label.go.step.4=Перейти к шагу 4 +label.go.step.5=Перейти к шагу 5 +label.group.optional=Группа (опционально) +label.group=Группа +label.guest.cidr=Гостевой CIDR +label.guest.gateway=Шлюз +label.guest.ip.range=Диапазон IP-адресов +label.guest.ip=Гостевые IP-адреса +label.guest.netmask=Гостевая сетевая маска +label.ha.enabled=HA включен +label.help=Помощь +label.host.alerts=Тревоги узла +label.host.name=Имя узла +label.host=Узел +label.hosts=Узлы +label.hourly=Часовая +label.hypervisor.type=Тип гипервизора +label.hypervisor=Гипервизор +label.id=ID +label.info=Информация +label.ingress.rule=Внутринее правило +label.initiated.by=Пользователь +label.instance.limits=Пределы машины +label.instance.name=Имя машины +label.instance=Машина +label.instances=Машины +label.internal.dns.1=Внутренний DNS 1 +label.internal.dns.2=Внутренний DNS 2 +label.interval.type=Тип диапазона +label.invalid.integer=Неправильное целое число +label.invalid.number=Неправильное число +label.ip.address=IP-адрес +label.ip.allocations=Распределения IP +label.ip.limits=Пределы публичных IP +label.ip.or.fqdn=IP или FQDN +label.ip.range=Диапазон IP +label.ip=IP +label.ips=IP +label.is.default=По умолчанию +label.is.shared=общие +label.is.system=Есть система +label.iscsi=iSCSI +label.iso.boot=Загрузка ISO +label.iso=ISO +label.isolation.mode=Режим изоляции +label.keep=Хранить +label.lang.chinese=Китайский (упрощённый) +label.lang.english=Английский +label.lang.japanese=Японский +label.lang.spanish=Испанский +label.last.disconnected=Последнее соединение +label.last.name=Последнее имя +label.level=Уровень +label.linklocal.ip=Локальный IP адрес +label.load.balancer=Балансировка нагрузки +label.loading=Загрузка +label.local=Локальный +# label.local.storage.enabled=Local storage enabled +label.login=Вход +label.logout=Выход +label.lun=LUN +label.manage=Управление +label.maximum=Максимум +label.memory.allocated=Распределено памяти +label.memory.total=Всего памяти +label.memory.used=Использованной памяти +label.memory=Память +label.menu.accounts=Учётные записи +label.menu.alerts=Тревоги +label.menu.all.accounts=Все учётные записи +label.menu.all.instances=Все машины +label.menu.community.isos=ISO-сообщества +label.menu.community.templates=Шаблоны сообщества +label.menu.configuration=Конфигурация +label.menu.dashboard=Главная +label.menu.destroyed.instances=Уничтоженные машины +label.menu.disk.offerings=Предложения дисков +label.menu.domains=Домены +label.menu.events=События +label.menu.featured.isos=Рекомендуемые ISO +label.menu.featured.templates=Рекомендуемые шаблоны +label.menu.global.settings=Глобальные настройки +label.menu.instances=Машины +label.menu.ipaddresses=IP-адреса +label.menu.isos=ISO +label.menu.my.accounts=Мои учётные записи +label.menu.my.instances=Мои машины +label.menu.my.isos=Мои ISO +label.menu.my.templates=Мои шаблоны +label.menu.network.offerings=Предложения сети +label.menu.network=Сеть +label.menu.physical.resources=Физические ресурсы +label.menu.running.instances=Запущенные машины +label.menu.security.groups=Группы безопасности +label.menu.service.offerings=Услуги +label.menu.snapshots=Снимки +label.menu.stopped.instances=Остановленные машины +label.menu.storage=Хранилище +label.menu.system.vms=Системные ВМ +label.menu.system=Система +label.menu.templates=Шаблоны +label.menu.virtual.appliances=Виртуальные устройства +label.menu.virtual.resources=Виртуальные ресурсы +label.menu.volumes=Тома +label.migrate.instance.to=Перенести машину в +label.minimum=Минимум +label.minute.past.hour=Минута +label.monday=Понедельник +label.monthly=Каждый месяц +label.more.templates=Больше шаблонов +label.my.account=Моя учётная запись +label.name.optional=Имя (необязательно) +label.name=Имя +label.netmask=Сетевая маска +label.network.desc=Описание сети +label.network.domain=Домен сети +label.network.id=ID сети +label.network.name=Имя сети +label.network.offering.display.text=сеть, обеспечивающую Отображение текста +label.network.offering.id=сеть, обеспечивающую ID +label.network.offering.name=сеть, обеспечивающую Имя +label.network.offering=Сетевой ресурс +label.network.rate=Скорость сети +label.network.read=Прочитано через сеть +label.network.type=Тип сети +label.network.write=Записано через сеть +label.network=Сеть +label.new.password=Новый пароль +label.next=Следующий +label.nfs.server=Сервер NFS +label.nfs.storage=Хранилище NFS +label.nfs=NFS +label.nics=Сетевые устройства (NIC) +label.no.actions=Нет доступных операций +label.no.alerts=Тревог не получено +label.no.errors=Ошибок не получено +label.no.isos=Нет доступных ISO +label.no.items=Нет доступных элементов +label.no.security.groups=Нет доступных групп безопасность +label.no.thanks=Нет, спасибо +label.no=Нет +label.none=Нет +label.not.found=Не найдено +label.num.cpu.cores=Кол. CPU +label.numretries=Количество попыток +label.offer.ha=Предост. HA +label.optional=Необязательно +label.os.preference=Предпочтительная ОС +label.os.type=Тип ОС +label.owned.public.ips=Собственные публичные IP-адреса +label.owner.account=Учётная запись владельца +label.owner.domain=Домен владельца +label.parent.domain=Родительский домен +label.password.enabled=Пароль включен +label.password=Пароль +label.path=Путь +label.please.wait=Подождите +label.pod=Стенд +label.port.forwarding=Проброс портов +label.port.range=Диапазон портов +label.prev=Предыдуший +label.primary.allocated=Распределение основного хранилища +label.primary.network=Основная сеть +label.primary.storage=Основное хранилище +label.primary.used=Использование основного хранилища +label.private.interface=Частный интерфейс +label.private.ip.range=Диапазон частных IP +label.private.ip=Частный IP-адрес +label.private.ips=Частные IP-адреса +label.private.port=Частный порт +label.private.zone=Частная зона +label.protocol=Протокол +label.public.interface=Публичный интерфейс +label.public.ip=Публичный IP-адрес +label.public.ips=Публичные IP-адреса +label.public.port=Публичный порт +label.public.zone=Публичная зона +label.public=Публичный +label.recent.errors=Полученные ошибки +label.refresh=Обновить +label.related=Связанный +label.remove.from.load.balancer=Удалить машину с балансировки нагрузки +label.removing.user=Удаление пользователя +label.required=Требуется +label.reserved.system.ip=Зарезервированный системный IP +label.resource.limits=Пределы ресурсов +label.resource=Ресурс +label.resources=Ресурсы +label.role=Роль +label.root.disk.offering=Ресурс корневого диска +label.running.vms=Запущенные ВМ +label.saturday=Суббота +label.save=Сохранить +label.saving.processing=Сохранение... +label.scope=Сфера +label.search=Поиск +label.secondary.storage=Дополнительное хранилище +label.secondary.used=Использование дополнительного хранилища +label.secret.key=Секретный ключ +label.security.group.name=Имя группы безопасности +label.security.group=Группа безопасности +label.security.groups.enabled=Группы безопасности включены +label.security.groups=Группы безопасности +label.sent=Отправлено +label.server=Сервер +label.service.offering=Служебный ресурс +label.system.service.offering=Системный ресурс +label.session.expired=Время сессии вышло +label.shared=Общедоступный +label.size=Размер +label.snapshot.limits=Пределы снимков +label.snapshot.name=Имя снимка +label.snapshot.s=Снимок/снимки +label.snapshot.schedule=Настройка повторяемых снимков +label.snapshot=Снимок +label.snapshots=Снимки +label.source.nat=NAT-источник +label.specify.vlan=Укажите VLAN +label.start.port=Начальный порт +label.state=Состояние +label.static.nat.to=Статичный NAT к +label.static.nat=Статичный NAT +label.statistics=Статистика +label.status=Статус +label.step.1.title=Шаг 1\: Выберите шаблон +label.step.1=Шаг 1 +label.step.2.title=Шаг 2\: Системный ресурс +label.step.2=Шаг 2 +label.step.3.title=Шаг 3\: Выберите дисковый ресурс +label.step.3=Шаг 3 +label.step.4.title=Step 4\: Сеть +label.step.4=Шаг 4 +label.step.5.title=Step 5\: Обзор +label.step.5=Шаг 5 +label.stopped.vms=Остановленные ВМ +label.storage.type=Тип хранилища +label.storage=Хранилище +label.submit=Опубликовать +label.submitted.by=[Опубликовано\: ] +label.succeeded=Успешно +label.sunday=Воскресенье +label.system.capacity=Мощность системы +label.system.vm.type=Тип системной ВМ +label.system.vm=Системная ВМ +label.system.vms=Системные ВМ +label.tagged=С меткой +label.tags=Метки +label.target.iqn=Целевой IQN +label.template.limits=Пределы шаблона +label.template=Шаблон +label.theme.default=Стандартная тема +label.theme.grey=Серая тема +label.theme.lightblue=Голубая тема +label.thursday=Четверг +label.time.zone=Часовой пояс +label.time=Время +label.timeout.in.second = Время ожидание (сек.) +label.timezone=Часовой пояс +label.total.cpu=Всего CPU +label.total.vms=Всего ВМ +label.traffic.type=Тип трафика +label.tuesday=Вторник +label.type.id=ID типа +label.type=Тип +label.unavailable=Не доступно +label.unlimited=Бесконечно +label.untagged=Без метки +label.update.ssl.cert=Обновить сертификаты SSL +label.update.ssl=Обновить сертификаты SSL +label.updating=Обновление +label.url=URL +label.usage.interface=Интерфейс использования +label.used=Использовано +label.user=Пользователь +label.username=Имя пользователя +label.users=Пользователи +label.value=Значение +label.vcenter.cluster=Кластер vCenter +label.vcenter.datacenter=ЦОД vCenter +label.vcenter.datastore=Хранилище vCenter +label.vcenter.host=Узел vCenter +label.vcenter.password=Пароль vCenter +label.vcenter.username=Имя пользователя vCenter +label.version=Версия +label.virtual.appliance=Виртуальное устройство +label.virtual.appliances=Виртуальное устройства +label.virtual.network=Виртуальная сеть +label.vlan.id=ID VLAN +label.vlan.range=Диапазон VLAN +label.vm.add=Добавить машины +label.vm.destroy=Уничтожить +label.vm.reboot=Перезагрузить +label.vm.start=Запустить +label.vm.stop=Остановить +label.vmfs=VMFS +label.vms=ВМ +label.volume.limits=Пределы томов +label.volume.name=Имя тома +label.volume=Том +label.volumes=Томы +label.vsphere.managed=Обслуживание vSphere +label.waiting=Ожидание +label.warn=Внимание +label.wednesday=Среда +label.weekly=Еженедельно +label.welcome.cloud.console=Добро пожаловать на панель управления +label.welcome=Добро пожаловать +label.yes=Да +label.zone.id=ID зоны +label.zone.step.1.title=Шаг 1\: Выберите сеть +label.zone.step.2.title=Step 2\: Добавьте зону +label.zone.step.3.title=Step 3\: Добавьте стенд +label.zone.step.4.title=Step 4\: Добавьте диапазон IP-адресов +label.zone.wide=Всей зоны +label.zone=Зона + +#Messages +message.acquire.public.ip=Пожалуйста, выберите зону, из которой вы хотите приобрести новый IP. +message.action.cancel.maintenance.mode=Подтвердите, что вы действительно хотите отменить режим обслуживания. +message.action.cancel.maintenance=Узел успешно вышел из режима обслуживания. Этль процесс может длиться несколько минут. +message.action.delete.ISO.for.all.zones=Это ISO, используемый всеми зонами. Подтвердите, что вы действительно хотите удалить его со всех зон. +message.action.delete.ISO=Подтвердите, что вы действительно хотите удалить этот ISO. +message.action.delete.cluster=Подтвердите, что вы действительно хотите удалить этот кластер. +message.action.delete.disk.offering=Подтвердите, что вы действительно хотите удалить этот дисковый ресурс. +message.action.delete.domain=Подтвердите, что вы действительно хотите удалить этот домен. +message.action.delete.external.firewall=Подтвердите, что вы действительно хотите удалить внешний фаервол. Внимание\: если вы планируете вернуться к этому внешнему фаерволу обратно, вам придется сбросить информацию об использовании в устройстве. +message.action.delete.external.load.balancer=Подтвердите, что вы действительно хотите удалить внешнюю балансировку нагрузки. Внимание\: если вы планируете вернуться к этой внешней балансировке, вам придется сбросить информацию об использовании в устройстве. +message.action.delete.ingress.rule=Подтвердите, что вы действительно хотите удалить это входное правило. +message.action.delete.network=Подтвердите, что вы действительно хотите удалить эту сеть. +message.action.delete.pod=Подтвердите, что вы действительно хотите удалить этот стенд. +message.action.delete.primary.storage=Подтвердите, что вы действительно хотите удалить это основное хранилище. +message.action.delete.secondary.storage=Подтвердите, что вы действительно хотите удалить это дополнительное хранилище. +message.action.delete.security.group=Подтвердите, что вы действительно хотите удалить эту группу безопасности. +message.action.delete.service.offering=Подтвердите, что вы действительно хотите удалить этот служебный ресурс. +message.action.delete.snapshot=Подтвердите, что вы действительно хотите удалить этот снимок. +message.action.delete.template.for.all.zones=Шаблон используется во всех зонах. Подтвердите, что вы хотите удалить его со всех зон. +message.action.delete.template=Подтвердите, что вы действительно хотите удалить этот шаблон. +message.action.delete.volume=Подтвердите, что вы действительно хотите удалить этот том. +message.action.delete.zone=Подтвердите, что вы действительно хотите удалить эту зону. +message.action.destroy.instance=Подтвердите, что вы действительно хотите уничтожить эту машину. +message.action.destroy.systemvm=Подтвердите, что вы действительно хотите удалить это основное хранилище. +message.action.disable.static.NAT=Подтвердите, что вы действительно хотите отключить статичный NAT. +message.action.enable.maintenance=Узел успешно вошел в режим обслуживания. Длительность этого процесса зависит от количества запущенных ВМ в этом узле и обычно равна нескольким минутам. +message.action.force.reconnect=Узел успешно переподключился. Этот процесс может длиться несколько минут. +message.action.host.enable.maintenance.mode=Включение режима обслуживания на узле приведет к переносу запущенных виртуальных машин на другие доступные узлы. +message.action.instance.reset.password=Подтвердите, что вы действительно хотите изменить пароль root этой ВМ. +message.action.primarystorage.enable.maintenance.mode=Внимание\: при переходе основного хранилища в режим обслуживания, все ВМ будут остановлены. Хотите продолжить? +message.action.reboot.instance=Подтвердите, что вы действительно хотите перезагрузить эту машину. +message.action.reboot.systemvm=Подтвердите, что вы действительно хотите перезагрузить этот системный ВМ. +message.action.release.ip=Подтвердите, что вы действительно хотите освободить этот IP-адрес. +message.action.remove.host=Удаление последнего/единственного сервера в кластере и повторная его установка приведет уничтожению рабочего окружения/базы данных на сервере и сделае гостевые машины непригодными к использованию. +message.action.restore.instance=Подтвердите, что вы действительно хотите восстановить эту машину. +message.action.start.instance=Подтвердите, что вы действительно хотите запустить эту машину. +message.action.start.router=Подтвердите, что вы действительно хотите запустить этот роутер. +message.action.start.systemvm=Подтвердите, что вы действительно хотите запустить эту системную ВМ. +message.action.stop.instance=Подтвердите, что вы действительно хотите остановить эту машину. +message.action.stop.systemvm=Подтвердите, что вы действительно хотите остановить эту системную ВМ. +message.action.take.snapshot=Подтвердите, что вы действительно хотите получить снимок этого тома. +message.add.cluster.zone=Добавить гипервизора управления кластером для зоны +message.add.cluster=Добавить гипервизор управления кластером для зоны , модуль +message.add.disk.offering=Пожалуйста, укажите следующие параметры, чтобы добавить новое предложение диска +message.add.firewall=Добавить фаервол в зону +message.add.host=Укажите следующие параметры для добавления нового узла. +message.add.ip.range.direct.network=Добавить IP-диапазона сети в зоне +message.add.ip.range.to.pod=

Добавить диапазон IP-адресов в стенд\:

+message.add.ip.range=Добавить диапазон IP-адресов в публичную сеть зоны +message.add.load.balancer=Добавить балансировку нагрузки в зону +message.add.network=Добавить новую сеть для зоны\: +message.add.pod=Добавить новый стенд для зоны +message.add.primary.storage=Добавить основное хранилище для зоны , стенда +message.add.primary=Укажите следующие параметры для добавления нового основного хранилища +message.add.secondary.storage=Добавить хранилище в зону +message.add.service.offering=Укажите следующие параметры для добавления нового системного ресурса. +message.add.template=Укажите следующие параметры для добавления нового шаблона +message.add.volume=Укажите следующие параметры для добавления нового тома +message.additional.networks.desc=Пожалуйста, выберите дополнительные сети, куда вашы сервера будут подключены. +message.advanced.mode.desc=Выберите эту модель сети, если вы хотите включить поддержку VLAN. Эта сетевая модель обеспечивает максимальную гибкость в предоставлении администраторам для предоставления пользовательских предложений сети, такие как межсетевой экран, VPN, или поддержка балансировки нагрузки, а также позволяет прямое против виртуальных сетей. +message.advanced.security.group=Выберите этот параметр, если вы хотите использовать группы безопасности, обеспечить изоляцию сервера. +message.advanced.virtual=Выберите этот параметр, если вы хотите использовать всей зоны сети VLAN, чтобы обеспечить изоляцию сервера. +message.allow.vpn.access=Пожалуйста, введите имя пользователя и пароль пользователя, который вы хотите добавить для VPN-доступа. +message.attach.iso.confirm=Пожалуйста, подтвердите, что вы хотите прикрепить ISO в этот сервер. +message.attach.volume=Пожалуйста, укажите следующие данные, что бы увеличить место. Для Windows, нужно перезагружать сервер +message.basic.mode.desc=Выберите эту модель сети, если вы *not* хотите, чтобы была любая поддержка VLAN. Всем виртуальным машинам, созданные по этой модели сети будет назначен IP напрямую из сети и группы безопасности, которые используются для обеспечения безопасности и сегрегации. +message.change.offering.confirm=Пожалуйста, подтвердите, что вы хотите изменить службу размещения этого VM. +message.copy.iso.confirm=Пожалуйста, подтвердите, что вы хотите скопировать ISO до +message.copy.template=Копировать шаблон XXX из зоны в +message.create.template.vm=Создать шаблон виртуальной машины +message.create.template.volume=Пожалуйста, укажите следующую информацию, прежде чем создавать шаблон диска объемом\: . Создание шаблона может варьироваться от нескольких минут до дольше в зависимости от размера тома. +message.delete.account=Пожалуйста, подтвердите, что вы хотите удалить этот аккаунт. +message.detach.iso.confirm=Пожалуйста, подтвердите, что вы хотите отделить ISO от этого виртуального сервера. +message.disable.account=Пожалуйста, подтвердите, что вы хотите отключить эту учетную запись. При отключении аккаунта, все пользователи для этой учетной записи не будут иметь доступ к своим ресурсам облака. Все виртуальные машины будут немедленно закрыты. +message.disable.vpn.access=Пожалуйста, подтвердите, что вы хотите отключить VPN доступ +message.download.ISO=Пожалуйста, нажмите 00000 скачать образ +message.download.template=Нажмите 00000для загрузки +message.download.volume=Нажмите 00000 для загрузки тома +message.edit.confirm=Пожалуйста, подтвердите, прежде чем нажать "Сохранить". +message.edit.limits=Укажите пределы для ресурсов. Значение "-1" означает отсутствие предела потребления данного ресурса. +message.enable.account=Подтвердите, что вы действительно хотите включить эту учётную запись. +message.enable.vpn.access=Сейчас VPN для этого IP-aдреса выключен. Желаете включить VPN-доступ? +message.enabled.vpn.ip.sec=Ваш IPSec pre-shared ключ +message.enabled.vpn=Ваш VPN доступ в настоящее время включен и могут быть доступны через IP +message.launch.vm.on.private.network=Хотите запустить ВМ в вашей частной выделенной сети? +message.lock.account=Подтвердите, что вы действительно хотите заблокировать эту учётную запись. Все пользователи в таких учётных записях потеряют возможность управлять своими облачными ресурсами. Эти ресурсы останутся доступны для других учётных записей. +message.migrate.instance.confirm=Подтвердите, что вы действительно хотите перенести виртуальную машину. +message.new.user=Введите информацию для добавления нового пользователя в учётную запись. +message.no.network.support.configuration.not.true=Ни в одной зоне нет групп безопасности. Поэтому дополнительные сетевые возможности недоступны. Перейдите к шагу 5. +message.no.network.support=Выбранный гипервизор (vSphere) не обладает дополнительными сетевыми возмодностями. Перейдите к шагу 5. +message.number.clusters=

\# of Кластеры

+message.number.hosts=

\# of Узлы

+message.number.pods=

\# of Стенды

+message.number.storage=

\# of Тома основного хранилища

+message.number.zones=

\# of Зоны

+message.remove.vpn.access=Подтвердите, что вы действительно хотите удалить доступ к VPN для этого пользователя. +message.restart.mgmt.server=Пожалуйста, перезагрузите сервер(ы) управления для принятия новых настроек. +message.restart.mgmt.usage.server=Пожалуйста, перезагрузите сервер для вступления новых параметров в силу. +message.security.group.usage=(используйте Ctrl-клик, чтобы выбрать все соответствующие группы безопасности) +message.snapshot.schedule=Вы можете настроить повторяющиеся снимоки, выбирая из доступных вариантов ниже и применив политику предпочтения +message.step.1.continue=Выберите шаблон или ISO для продолжения. +message.step.1.desc=Пожалуйста, выберите шаблон для нового сервера. Вы можете также выбрать пустой шаблон, из которого образ ISO может быть установлен на. +message.step.2.continue=Выберите служебный ресурс для продолжения. +message.step.2.desc= +message.step.3.continue=Выберите дисковый ресурс для продолжения. +message.step.3.desc= +message.step.4.continue=Выберите хотя бы одну сеть для продолжения. +message.step.4.desc=Выберите основную сеть, к которой будет подключена машина. +message.update.os.preference=Пожалуйста, выберите ОС для этого хоста. Все виртуальные экземпляры с аналогичными предпочтениями впервые будет выделено на этот узел, прежде чем выбрать другую. +message.update.ssl=Пожалуйста, отправьте новый совместимый X.509 SSL сертификат для обновления для каждой консоли виртуальных прокси, например\: +message.virtual.network.desc=выделенной виртуальной сети для вашей учетной записи. Широковещательный домен находится внутри VLAN и весь внешний доступ к сети направляется путем виртуального маршрутизатора. +message.volume.create.template.confirm=Подтвердите, что вы действительно хотите создать шаблон этого тома. Это процесс может продлиться несколько минут в зависимости от размера тома. +message.zone.step.1.desc=Выберите тип сети этой зоны. +message.zone.step.2.desc=Введите необходимую информацию для добавления новой зоны +message.zone.step.3.desc=Введите необходимую информацию для добавления нового стенда +message.apply.snapshot.policy=Политики этого снимка были успешно обновлены. +message.disable.snapshot.policy=Политики этого снимка были успешно отключены. +message.action.change.service.warning.for.instance=Для изменения текущего служебного ресурса ваша машина должна быть остановлена. +message.action.change.service.warning.for.router=\n +message.action.reset.password.warning=Машина должна быть остановлена для изменения пароля +message.action.reset.password.off=На данный момент машина не поддерживает данную функцию + +#Errors +error.login=Ваше имя/пароль не совпадает с вашими записями. +error.menu.select=Не удается выполнить действие из-за отсутствия выбраных пунктов. +error.mgmt.server.inaccessible=Сервер управления недоступна. Попробуйте обратиться к нему позже. +error.session.expired=Ваша сессия была завершена +error.unresolved.internet.name=Ваше интернет-имя определить не удалось diff --git a/client/pom.xml b/client/pom.xml index 50b85e956f8..c3a048604b1 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -1,21 +1,13 @@ - + 4.0.0 @@ -25,7 +17,7 @@ org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT @@ -77,6 +69,12 @@ org.apache.cloudstack cloud-plugin-hypervisor-kvm ${project.version} + + + org.mortbay.jetty + servlet-api + + org.apache.cloudstack @@ -111,7 +109,7 @@ org.apache.maven.plugins maven-war-plugin - 2.2 + 2.3 ./WEB-INF/web.xml ./target/generated-webapp @@ -130,15 +128,16 @@ /client ${basedir}/WEB-INF/web.xml - ${basedir}/target/generated-webapp + ${project.build.directory}/${project.build.finalName} org.apache.tomcat.maven tomcat7-maven-plugin + /client ${basedir}/WEB-INF/web.xml - ./target/generated-webapp + ${project.build.directory}/generated-webapp/ @@ -146,43 +145,74 @@ 1.7 + generate-resource generate-resources run - - + + - + - + + + + + + + - + - - + + + + + process-nonoss + process-resources + + run + + + + test + + + + - + org.eclipse.m2e lifecycle-mapping @@ -204,7 +234,7 @@ - + @@ -214,4 +244,86 @@ + + + netapp + + + nonoss + + + + + org.apache.cloudstack + cloud-plugin-netapp + ${project.version} + + + + + f5 + + + nonoss + + + + + org.apache.cloudstack + cloud-plugin-network-f5 + ${project.version} + + + + + netscaler + + + nonoss + + + + + org.apache.cloudstack + cloud-plugin-network-netscaler + ${project.version} + + + + + srx + + + nonoss + + + + + org.apache.cloudstack + cloud-plugin-network-srx + ${project.version} + + + + + vmware + + + nonoss + + + + + org.apache.cloudstack + cloud-plugin-hypervisor-vmware + ${project.version} + + + org.apache.cloudstack + cloud-vmware-base + ${project.version} + + + + diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index e2336946e27..d9243d553fb 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -160,6 +160,8 @@ stopRouter=com.cloud.api.commands.StopRouterCmd;7 destroyRouter=com.cloud.api.commands.DestroyRouterCmd;7 changeServiceForRouter=com.cloud.api.commands.UpgradeRouterCmd;7 listRouters=com.cloud.api.commands.ListRoutersCmd;7 +listVirtualRouterElements=com.cloud.api.commands.ListVirtualRouterElementsCmd;7 +configureVirtualRouterElement=com.cloud.api.commands.ConfigureVirtualRouterElementCmd;7 #### system vm commands startSystemVm=com.cloud.api.commands.StartSystemVMCmd;1 diff --git a/client/tomcatconf/components-nonoss.xml.in b/client/tomcatconf/components-nonoss.xml.in new file mode 100755 index 00000000000..fbfc5cc2726 --- /dev/null +++ b/client/tomcatconf/components-nonoss.xml.in @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + true + + + + + + diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 5730b832075..2953eb781a6 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -179,6 +179,7 @@ under the License. + diff --git a/client/tomcatconf/db.properties.in b/client/tomcatconf/db.properties.in index ba51b7282c8..f39d8fe4097 100644 --- a/client/tomcatconf/db.properties.in +++ b/client/tomcatconf/db.properties.in @@ -69,3 +69,15 @@ db.usage.autoReconnect=true # awsapi database settings db.awsapi.name=cloudbridge + +# Simulator database settings +db.simulator.username=@DBUSER@ +db.simulator.password=@DBPW@ +db.simulator.host=@DBHOST@ +db.simulator.port=3306 +db.simulator.name=simulator +db.simulator.maxActive=250 +db.simulator.maxIdle=30 +db.simulator.maxWait=10000 +db.simulator.autoReconnect=true + diff --git a/cloud-cli/cloudapis/cloud.py b/cloud-cli/cloudapis/cloud.py index 1ee9806c978..a0e88805c82 100644 --- a/cloud-cli/cloudapis/cloud.py +++ b/cloud-cli/cloudapis/cloud.py @@ -71,10 +71,10 @@ class CloudAPI: requests = zip(requests.keys(), requests.values()) requests.sort(key=lambda x: str.lower(x[0])) - requestUrl = "&".join(["=".join([request[0], urllib.quote_plus(str(request[1]))]) for request in requests]) - hashStr = "&".join(["=".join([str.lower(request[0]), urllib.quote_plus(str.lower(str(request[1])))]) for request in requests]) + requestUrl = "&".join(["=".join([request[0], urllib.quote(str(request[1],""))]) for request in requests]) + hashStr = "&".join(["=".join([str.lower(request[0]), urllib.quote(str.lower(str(request[1])),"")]) for request in requests]) - sig = urllib.quote_plus(base64.encodestring(hmac.new(self.securityKey, hashStr, hashlib.sha1).digest()).strip()) + sig = urllib.quote_plus(base64.encodestring(hmac.new(self.securityKey, str.lower(hashStr), hashlib.sha1).digest()).strip()) requestUrl += "&signature=%s"%sig diff --git a/cloud.spec b/cloud.spec index 724f8577a2e..29c10936a9f 100644 --- a/cloud.spec +++ b/cloud.spec @@ -38,7 +38,11 @@ Group: System Environment/Libraries Source0: %{name}-%{_ver}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{_ver}-%{release}-build +%if 0%{?fedora} >= 17 +BuildRequires: java-1.7.0-openjdk-devel +%else BuildRequires: java-1.6.0-openjdk-devel +%endif BuildRequires: tomcat6 BuildRequires: ws-commons-util BuildRequires: jpackage-utils @@ -76,7 +80,7 @@ CloudStack management server. Summary: CloudStack server library Requires: java >= 1.6.0 Obsoletes: vmops-server < %{version}-%{release} -Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, tomcat6-servlet-2.5-api +Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-scripts = %{version}, tomcat6-servlet-2.5-api Group: System Environment/Libraries %description server The CloudStack server libraries provide a set of Java classes for CloudStack. @@ -95,6 +99,7 @@ Requires: nfs-utils Requires: wget # there is a fsimage.so in the source code, which adds xen-libs as a dependence, needs to supress it, as rhel doesn't have this pacakge AutoReqProv: no +Provides: cloud-agent-scripts = %{version}-%{release} Obsoletes: cloud-agent-scripts < %{version}-%{release} Group: System Environment/Libraries %description scripts @@ -274,7 +279,7 @@ Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = Requires: %{name}-setup = %{version} Requires: %{name}-client = %{version} Requires: jsvc -License: GPLv3+ +License: Apache License 2.0 Group: System Environment/Libraries %description usage The CloudStack usage monitor provides usage accounting across the entire cloud for @@ -285,6 +290,7 @@ Summary: CloudStack CloudBridge Group: System Environment/Libraries Requires: java >= 1.6.0 Requires: tomcat6 +Requires: %{name}-deps = %{version} %if 0%{?fedora} > 15 Requires: apache-commons-lang %endif @@ -330,15 +336,10 @@ if [ "$1" == "0" ] ; then /sbin/service %{name}-management stop > /dev/null 2>&1 || true fi -%pre client +%pre aws-api id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "CloudStack unprivileged user" \ -r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true -# set max file descriptors for cloud user to 4096 -sed -i /"cloud hard nofile"/d /etc/security/limits.conf -sed -i /"cloud soft nofile"/d /etc/security/limits.conf -echo "cloud hard nofile 4096" >> /etc/security/limits.conf -echo "cloud soft nofile 4096" >> /etc/security/limits.conf rm -rf %{_localstatedir}/cache/%{name} # user harcoded here, also hardcoded on wscript @@ -387,32 +388,33 @@ else /sbin/service %{name}-agent condrestart >/dev/null 2>&1 || true fi -%post client -if [ "$1" == "1" ] ; then - /sbin/chkconfig --add %{name}-management > /dev/null 2>&1 || true - /sbin/chkconfig --level 345 %{name}-management on > /dev/null 2>&1 || true +if [ -x /etc/sysconfig/modules/kvm.modules ] ; then + /bin/sh /etc/sysconfig/modules/kvm.modules fi -if [ "$1" == "1" ] ; then - root=/usr/share/cloud/bridge - target=/usr/share/cloud/management/ +%post client + /sbin/chkconfig --add %{name}-management > /dev/null 2>&1 || true + /sbin/chkconfig --level 345 %{name}-management on > /dev/null 2>&1 || true - if [ ! -e $target/webapps/awsapi ]; then - ln -s $root/webapps/awsapi $target/webapps/awsapi + root=/usr/share/cloud/bridge + target=/usr/share/cloud/management + + mkdir -p $target/webapps7080 + if [ ! -h $target/webapps7080/awsapi ]; then + ln -sf $root/webapps7080/awsapi $target/webapps7080/awsapi fi - jars=`ls $root/lib` - for j in $jars - do - cp -f $root/lib/$j $root/webapps/awsapi/WEB-INF/lib/ - done +# jars=`ls $root/lib` +# for j in $jars +# do +# cp -f $root/lib/$j $root/webapps/awsapi/WEB-INF/lib/ +# done confs="cloud-bridge.properties ec2-service.properties" for c in $confs do cp -f $root/conf/$c $target/conf done -fi %files utils %defattr(0644,root,root,0755) @@ -421,14 +423,14 @@ fi %attr(0755,root,root) %{_bindir}/cloud-sccs %attr(0755,root,root) %{_bindir}/cloud-gitrevs %doc %{_docdir}/%{name}-%{version}/version-info -%doc %{_docdir}/%{name}-%{version}/sccs-info -%doc %{_docdir}/%{name}-%{version}/configure-info -%doc README.html -%doc debian/copyright +%doc LICENSE +%doc NOTICE %files client-ui %defattr(0644,root,root,0755) %{_datadir}/%{name}/management/webapps/client/* +%doc LICENSE +%doc NOTICE %files server %defattr(0644,root,root,0755) @@ -446,6 +448,8 @@ fi %{_javadir}/%{name}-plugin-elb.jar %{_javadir}/%{name}-plugin-nicira-nvp.jar %config(noreplace) %{_sysconfdir}/%{name}/server/* +%doc LICENSE +%doc NOTICE %files scripts %defattr(-,root,root,-) @@ -453,10 +457,23 @@ fi # maintain the following list in sync with files scripts %{_libdir}/%{name}/common/vms/systemvm.zip %{_libdir}/%{name}/common/vms/systemvm.iso - +%doc LICENSE +%doc NOTICE %files deps %defattr(0644,root,root,0755) +%{_javadir}/axiom-*.jar +%{_javadir}/axis2-*.jar +%{_javadir}/antlr*.jar +%{_javadir}/XmlSchema-*.jar +%{_javadir}/json-simple*.jar +%{_javadir}/neethi*.jar +%{_javadir}/woden*.jar +%{_javadir}/xercesImpl*.jar +%{_javadir}/xml-apis*.jar +%{_javadir}/dom4j*.jar +%{_javadir}/javassist*.jar +%{_javadir}/commons-fileupload*.jar %{_javadir}/commons-codec-1.6.jar %{_javadir}/commons-dbcp-1.4.jar %{_javadir}/commons-pool-1.6.jar @@ -484,9 +501,14 @@ fi %{_javadir}/jstl-1.2.jar %{_javadir}/javax.persistence-2.0.0.jar %{_javadir}/bcprov-jdk16-1.45.jar +%doc LICENSE +%doc NOTICE + %files core %defattr(0644,root,root,0755) %{_javadir}/%{name}-core.jar +%doc LICENSE +%doc NOTICE %files python %defattr(0644,root,root,0755) @@ -494,6 +516,8 @@ fi %attr(0755,root,root) %{_bindir}/cloud-external-ipallocator.py %attr(0755,root,root) %{_initrddir}/cloud-ipallocator %dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/ipallocator +%doc LICENSE +%doc NOTICE %files setup %attr(0755,root,root) %{_bindir}/%{name}-setup-databases @@ -507,6 +531,8 @@ fi %{_datadir}/%{name}/setup/db/*.sql %{_datadir}/%{name}/setup/*.sh %{_datadir}/%{name}/setup/server-setup.xml +%doc LICENSE +%doc NOTICE %files client %defattr(0644,root,root,0775) @@ -530,12 +556,16 @@ fi %dir %attr(0770,root,%{name}) %{_localstatedir}/cache/%{name}/management/temp %dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/management %dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/agent +%doc LICENSE +%doc NOTICE %files agent-libs %defattr(0644,root,root,0755) %{_javadir}/%{name}-agent.jar %{_javadir}/%{name}-plugin-hypervisor-kvm.jar %{_javadir}/libvirt-0.4.9.jar +%doc LICENSE +%doc NOTICE %files agent %defattr(0644,root,root,0755) @@ -546,6 +576,8 @@ fi %attr(0755,root,root) %{_initrddir}/%{name}-agent %attr(0755,root,root) %{_bindir}/%{name}-setup-agent %dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/agent +%doc LICENSE +%doc NOTICE %files cli %{_bindir}/%{name}-tool @@ -555,9 +587,13 @@ fi %dir %{_prefix}/lib*/python*/site-packages/%{name}tool %{_prefix}/lib*/python*/site-packages/%{name}tool/* %{_prefix}/lib*/python*/site-packages/%{name}apis.py +%doc LICENSE +%doc NOTICE %files baremetal-agent %attr(0755,root,root) %{_bindir}/cloud-setup-baremetal +%doc LICENSE +%doc NOTICE %files usage %defattr(0644,root,root,0775) @@ -567,6 +603,8 @@ fi %config(noreplace) %{_sysconfdir}/%{name}/usage/usage-components.xml %config(noreplace) %{_sysconfdir}/%{name}/usage/log4j-%{name}_usage.xml %config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/usage/db.properties +%doc LICENSE +%doc NOTICE %files aws-api %defattr(0644,cloud,cloud,0755) @@ -575,6 +613,8 @@ fi %attr(0644,root,root) %{_datadir}/cloud/setup/bridge/db/* %attr(0755,root,root) %{_bindir}/cloudstack-aws-api-register %attr(0755,root,root) %{_bindir}/cloud-setup-bridge +%doc LICENSE +%doc NOTICE %changelog * Fri Sep 14 2012 Marcus Sorensen 4.0.1 diff --git a/console-proxy/certs/realhostip.csr b/console-proxy/certs/realhostip.csr index 0684141d237..61395c9f8d9 100644 --- a/console-proxy/certs/realhostip.csr +++ b/console-proxy/certs/realhostip.csr @@ -1,15 +1,15 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIICsDCCAZgCAQAwazELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlDdXBlcnRp -bm8xDjAMBgNVBAoTBVZNT3BzMRAwDgYDVQQLEwdVbmtub3duMRkwFwYDVQQDDBAqLnJlYWxob3N0 -aXAuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg0/QLRH7PrPyPEF6eq6wsNIj -SdPhoLMmzR4XlPiaS9/SzE2cpAq2YWZ8g78HcQqDnxN/Emt9m2hyjXbPstkh5zDbDpMPDnDbnBxA -V9RSKTgRqYfQ+sQvrpsfaHesTFhE1L+4+odrvlgtzoQTPHxwgaiIgKJd9fyJHKg8cbB5UPEv6An0 -5VyVGOmJ+tvDgNV4oynUZ2nVdIWfNvXL/z2SpY48EFE8q3dCh0HpLAR/mAGEqNiVJfHpDS7DovP3 -D7X6I55bc0SNRl4tGTjbPFZw8ydGtoKmWPrsZc/ghmy5xp5TeI/XAaRPjH1BPt+Q6tdtbE6bEoBf -OTM/qVYZ9kut9wIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAF5lhhni9dW9MqSL2ixNbViPWpFS -ecOggshYChJfZKrhsuZaDpumJ/+ebICS4zv/oxDwNLSmeAmydiaUQC9LFQEEwvPBYDTtTzwCrtwH -yyFJQSm6pyeIBP/Bih/5hLW8JPm0bDbp5ldrHCDEgKQeeyQhyYOKFODkTuMLw+FLD+V86IVHxElL -/urCRWyZEPwyMsgfsU6ywNX9XNShyk1uDHjFDE67sPhfw52ooxXrYQnBdTk+g0UXPbULzrCK/1kU -fjRq347V9Fwi5NFyGADOaA+q6mtnlb1i3uH1n1YVUzevvpnIr3/RxPSYHB47Kj9iYKeDlYdTRHJy -NpuvTfmQO2Y= ------END NEW CERTIFICATE REQUEST----- +-----BEGIN NEW CERTIFICATE REQUEST----- +MIICsDCCAZgCAQAwazELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlDdXBlcnRp +bm8xDjAMBgNVBAoTBVZNT3BzMRAwDgYDVQQLEwdVbmtub3duMRkwFwYDVQQDDBAqLnJlYWxob3N0 +aXAuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg0/QLRH7PrPyPEF6eq6wsNIj +SdPhoLMmzR4XlPiaS9/SzE2cpAq2YWZ8g78HcQqDnxN/Emt9m2hyjXbPstkh5zDbDpMPDnDbnBxA +V9RSKTgRqYfQ+sQvrpsfaHesTFhE1L+4+odrvlgtzoQTPHxwgaiIgKJd9fyJHKg8cbB5UPEv6An0 +5VyVGOmJ+tvDgNV4oynUZ2nVdIWfNvXL/z2SpY48EFE8q3dCh0HpLAR/mAGEqNiVJfHpDS7DovP3 +D7X6I55bc0SNRl4tGTjbPFZw8ydGtoKmWPrsZc/ghmy5xp5TeI/XAaRPjH1BPt+Q6tdtbE6bEoBf +OTM/qVYZ9kut9wIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBAF5lhhni9dW9MqSL2ixNbViPWpFS +ecOggshYChJfZKrhsuZaDpumJ/+ebICS4zv/oxDwNLSmeAmydiaUQC9LFQEEwvPBYDTtTzwCrtwH +yyFJQSm6pyeIBP/Bih/5hLW8JPm0bDbp5ldrHCDEgKQeeyQhyYOKFODkTuMLw+FLD+V86IVHxElL +/urCRWyZEPwyMsgfsU6ywNX9XNShyk1uDHjFDE67sPhfw52ooxXrYQnBdTk+g0UXPbULzrCK/1kU +fjRq347V9Fwi5NFyGADOaA+q6mtnlb1i3uH1n1YVUzevvpnIr3/RxPSYHB47Kj9iYKeDlYdTRHJy +NpuvTfmQO2Y= +-----END NEW CERTIFICATE REQUEST----- diff --git a/console-proxy/js/ajaxviewer.js b/console-proxy/js/ajaxviewer.js index 355cc827ba2..6ac56be6641 100644 --- a/console-proxy/js/ajaxviewer.js +++ b/console-proxy/js/ajaxviewer.js @@ -63,11 +63,296 @@ function getCurrentLanguage() { // function KeyboardMapper() { this.mappedInput = []; + this.jsX11KeysymMap = []; + this.jsKeyPressX11KeysymMap = []; } +// +// RAW keyboard +// Primarily translates KeyDown/KeyUp event, either as is (if there is no mapping entry) +// or through mapped result. +// +// For KeyPress event, it translates it only if there exist a mapping entry +// in jsX11KeysymMap map and the entry meets the condition +// +// COOKED keyboard +// Primarily translates KeyPress event, either as is or through mapped result +// It translates KeyDown/KeyUp only there exists a mapping entry, or if there +// is no mapping entry, translate when certain modifier key is pressed (i.e., +// CTRL or ALT key +// +// Mapping entry types +// direct : will be directly mapped into the entry value with the same event type +// boolean : only valid for jsX11KeysymMap, existence of this type, no matter true or false +// in value, corresponding KeyDown/KeyUp event will be masked +// array : contains a set of conditional mapping entry +// +// Conditional mapping entry +// +// { +// type: , code: , modifiers: , +// shift : , -- match on shift state +// guestos : , -- match on guestos type +// browser: , -- match on browser +// browserVersion: -- match on browser version +// } +// +KeyboardMapper.KEYBOARD_TYPE_RAW = 0; +KeyboardMapper.KEYBOARD_TYPE_COOKED = 1; + KeyboardMapper.prototype = { - inputFeed : function(eventType, code, modifiers) { - this.mappedInput.push({type: eventType, code: code, modifiers: modifiers}); + + setKeyboardType : function(keyboardType) { + this.keyboardType = keyboardType; + + if(keyboardType == KeyboardMapper.KEYBOARD_TYPE_RAW) { + // intialize keyboard mapping for RAW keyboard + this.jsX11KeysymMap[AjaxViewer.JS_KEY_CAPSLOCK] = AjaxViewer.X11_KEY_CAPSLOCK; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACKSPACE] = AjaxViewer.X11_KEY_BACKSPACE; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_TAB] = AjaxViewer.X11_KEY_TAB; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ENTER] = AjaxViewer.X11_KEY_ENTER; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ESCAPE] = AjaxViewer.X11_KEY_ESCAPE; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_INSERT] = AjaxViewer.X11_KEY_INSERT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_DELETE] = AjaxViewer.X11_KEY_DELETE; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_HOME] = AjaxViewer.X11_KEY_HOME; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_END] = AjaxViewer.X11_KEY_END; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEUP] = AjaxViewer.X11_KEY_PAGEUP; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEDOWN] = AjaxViewer.X11_KEY_PAGEDOWN; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_LEFT] = AjaxViewer.X11_KEY_LEFT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_UP] = AjaxViewer.X11_KEY_UP; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_RIGHT] = AjaxViewer.X11_KEY_RIGHT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_DOWN] = AjaxViewer.X11_KEY_DOWN; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F1] = AjaxViewer.X11_KEY_F1; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F2] = AjaxViewer.X11_KEY_F2; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F3] = AjaxViewer.X11_KEY_F3; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F4] = AjaxViewer.X11_KEY_F4; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F5] = AjaxViewer.X11_KEY_F5; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F6] = AjaxViewer.X11_KEY_F6; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F7] = AjaxViewer.X11_KEY_F7; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F8] = AjaxViewer.X11_KEY_F8; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F9] = AjaxViewer.X11_KEY_F9; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F10] = AjaxViewer.X11_KEY_F10; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F11] = AjaxViewer.X11_KEY_F11; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F12] = AjaxViewer.X11_KEY_F12; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_SHIFT] = AjaxViewer.X11_KEY_SHIFT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_CTRL] = AjaxViewer.X11_KEY_CTRL; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ALT] = AjaxViewer.X11_KEY_ALT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_GRAVE_ACCENT] = AjaxViewer.X11_KEY_GRAVE_ACCENT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_SUBSTRACT] = AjaxViewer.X11_KEY_SUBSTRACT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ADD] = AjaxViewer.X11_KEY_ADD; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_OPEN_BRACKET] = AjaxViewer.X11_KEY_OPEN_BRACKET; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_CLOSE_BRACKET] = AjaxViewer.X11_KEY_CLOSE_BRACKET; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACK_SLASH] = AjaxViewer.X11_KEY_BACK_SLASH; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_SINGLE_QUOTE] = AjaxViewer.X11_KEY_SINGLE_QUOTE; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_COMMA] = AjaxViewer.X11_KEY_COMMA; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_PERIOD] = AjaxViewer.X11_KEY_PERIOD; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_FORWARD_SLASH] = AjaxViewer.X11_KEY_FORWARD_SLASH; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_DASH] = AjaxViewer.X11_KEY_DASH; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_SEMI_COLON] = AjaxViewer.X11_KEY_SEMI_COLON; + + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD0] = AjaxViewer.X11_KEY_NUMPAD0; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD1] = AjaxViewer.X11_KEY_NUMPAD1; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD2] = AjaxViewer.X11_KEY_NUMPAD2; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD3] = AjaxViewer.X11_KEY_NUMPAD3; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD4] = AjaxViewer.X11_KEY_NUMPAD4; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD5] = AjaxViewer.X11_KEY_NUMPAD5; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD6] = AjaxViewer.X11_KEY_NUMPAD6; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD7] = AjaxViewer.X11_KEY_NUMPAD7; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD8] = AjaxViewer.X11_KEY_NUMPAD8; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD9] = AjaxViewer.X11_KEY_NUMPAD9; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_DECIMAL_POINT] = AjaxViewer.X11_KEY_DECIMAL_POINT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_DIVIDE] = AjaxViewer.X11_KEY_DIVIDE; + + this.jsX11KeysymMap[AjaxViewer.JS_KEY_MULTIPLY] = [ + {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0 }, + {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ASTERISK, modifiers: 0 }, + {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ASTERISK, modifiers: 0 }, + {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0 } + ]; + + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ADD] = false; + this.jsKeyPressX11KeysymMap = []; + this.jsKeyPressX11KeysymMap[61] = [ + {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, + {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false } + ]; + this.jsKeyPressX11KeysymMap[43] = [ + {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false }, + {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, + {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, + {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false }, + {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true }, + {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true } + ]; + } else { + // initialize mapping for COOKED keyboard + this.jsX11KeysymMap[AjaxViewer.JS_KEY_CAPSLOCK] = AjaxViewer.X11_KEY_CAPSLOCK; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACKSPACE] = AjaxViewer.X11_KEY_BACKSPACE; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_TAB] = AjaxViewer.X11_KEY_TAB; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ENTER] = AjaxViewer.X11_KEY_ENTER; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ESCAPE] = AjaxViewer.X11_KEY_ESCAPE; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_INSERT] = AjaxViewer.X11_KEY_INSERT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_DELETE] = AjaxViewer.X11_KEY_DELETE; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_HOME] = AjaxViewer.X11_KEY_HOME; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_END] = AjaxViewer.X11_KEY_END; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEUP] = AjaxViewer.X11_KEY_PAGEUP; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEDOWN] = AjaxViewer.X11_KEY_PAGEDOWN; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_LEFT] = AjaxViewer.X11_KEY_LEFT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_UP] = AjaxViewer.X11_KEY_UP; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_RIGHT] = AjaxViewer.X11_KEY_RIGHT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_DOWN] = AjaxViewer.X11_KEY_DOWN; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F1] = AjaxViewer.X11_KEY_F1; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F2] = AjaxViewer.X11_KEY_F2; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F3] = AjaxViewer.X11_KEY_F3; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F4] = AjaxViewer.X11_KEY_F4; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F5] = AjaxViewer.X11_KEY_F5; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F6] = AjaxViewer.X11_KEY_F6; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F7] = AjaxViewer.X11_KEY_F7; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F8] = AjaxViewer.X11_KEY_F8; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F9] = AjaxViewer.X11_KEY_F9; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F10] = AjaxViewer.X11_KEY_F10; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F11] = AjaxViewer.X11_KEY_F11; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_F12] = AjaxViewer.X11_KEY_F12; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_SHIFT] = AjaxViewer.X11_KEY_SHIFT; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_CTRL] = AjaxViewer.X11_KEY_CTRL; + this.jsX11KeysymMap[AjaxViewer.JS_KEY_ALT] = AjaxViewer.X11_KEY_ALT; + } + }, + + RawkeyboardInputHandler : function(eventType, code, modifiers, guestos, browser, browserVersion) { + if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) { + + // special handling for Alt + Ctrl + Ins, convert it into Alt-Ctrl-Del + if(code == AjaxViewer.JS_KEY_INSERT) { + if((modifiers & AjaxViewer.ALT_KEY_MASK) != 0 && (modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) { + this.mappedInput.push({type : eventType, code: 0xffff, modifiers: modifiers}); + return; + } + } + + var X11Keysym = code; + if(this.jsX11KeysymMap[code] != undefined) { + X11Keysym = this.jsX11KeysymMap[code]; + if(typeof this.jsX11KeysymMap[code] == "boolean") { + return; + } else if($.isArray(X11Keysym)) { + for(var i = 0; i < X11Keysym.length; i++) { + if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser, browserVersion)) { + this.mappedInput.push(X11Keysym[i]); + } + } + } else { + this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); + } + } else { + this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); + } + + // special handling for ALT/CTRL key + if(eventType == AjaxViewer.KEY_UP && (code == AjaxViewer.JS_KEY_ALT || code == code == AjaxViewer.JS_KEY_CTRL)) + this.mappedInput.push({type : eventType, code: this.jsX11KeysymMap[code], modifiers: modifiers}); + + } else if(eventType == AjaxViewer.KEY_PRESS) { + var X11Keysym = code; + X11Keysym = this.jsKeyPressX11KeysymMap[code]; + if(X11Keysym) { + if($.isArray(X11Keysym)) { + for(var i = 0; i < X11Keysym.length; i++) { + if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser)) + this.mappedInput.push(X11Keysym[i]); + } + } else { + this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: X11Keysym, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_UP, code: X11Keysym, modifiers: modifiers}); + } + } + } + }, + + CookedKeyboardInputHandler : function(eventType, code, modifiers, guestos, browser, browserVersion) { + if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) { + + // special handling for Alt + Ctrl + Ins, convert it into Alt-Ctrl-Del + if(code == AjaxViewer.JS_KEY_INSERT) { + if((modifiers & AjaxViewer.ALT_KEY_MASK) != 0 && (modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) { + this.mappedInput.push({type : eventType, code: 0xffff, modifiers: modifiers}); + return; + } + } + + var X11Keysym = code; + if(this.jsX11KeysymMap[code] != undefined) { + X11Keysym = this.jsX11KeysymMap[code]; + if(typeof this.jsX11KeysymMap[code] == "boolean") { + return; + } else if($.isArray(X11Keysym)) { + for(var i = 0; i < X11Keysym.length; i++) { + if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser, browserVersion)) { + this.mappedInput.push(X11Keysym[i]); + } + } + } else { + this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); + } + } else { + if((modifiers & (AjaxViewer.CTRL_KEY_MASK | AjaxViewer.ALT_KEY_MASK)) != 0) { + this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); + } + } + + // special handling for ALT/CTRL key + if(eventType == AjaxViewer.KEY_UP && (code == AjaxViewer.JS_KEY_ALT || code == code == AjaxViewer.JS_KEY_CTRL)) + this.mappedInput.push({type : eventType, code: this.jsX11KeysymMap[code], modifiers: modifiers}); + + } else if(eventType == AjaxViewer.KEY_PRESS) { + // special handling for * and + key on number pad + if(code == AjaxViewer.JS_NUMPAD_MULTIPLY) { + this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: 42, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_UP, code: 42, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); + return; + } + + if(code == AjaxViewer.JS_NUMPAD_PLUS) { + this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: 43, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_UP, code: 43, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); + return; + } + + // ENTER/BACKSPACE key should already have been sent through KEY DOWN/KEY UP event + if(code == AjaxViewer.JS_KEY_ENTER || code == AjaxViewer.JS_KEY_BACKSPACE) + return; + + if(code > 0) { + var X11Keysym = code; + X11Keysym = this.jsKeyPressX11KeysymMap[code]; + if(X11Keysym) { + if($.isArray(X11Keysym)) { + for(var i = 0; i < X11Keysym.length; i++) { + if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser)) + this.mappedInput.push(X11Keysym[i]); + } + } else { + this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: X11Keysym, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_UP, code: X11Keysym, modifiers: modifiers}); + } + } else { + // if there is no mappting entry, use the JS keypress code directly + this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: code, modifiers: modifiers}); + this.mappedInput.push({type : AjaxViewer.KEY_UP, code: code, modifiers: modifiers}); + } + } + } + }, + + inputFeed : function(eventType, code, modifiers, guestos, browser, browserVersion) { + if(this.keyboardType == KeyboardMapper.KEYBOARD_TYPE_RAW) + this.RawkeyboardInputHandler(eventType, code, modifiers, guestos, browser, browserVersion); + else + this.CookedKeyboardInputHandler(eventType, code, modifiers, guestos, browser, browserVersion); }, getMappedInput : function() { @@ -76,253 +361,44 @@ KeyboardMapper.prototype = { return mappedInput; }, + isConditionalEntryMatched : function(eventType, code, modifiers, entry, guestos, browser, browserVersion) { + if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) { + // for KeyDown/KeyUp events, we require that the type in entry should match with + // the real input + if(entry.type != eventType) + return false; + } + + // check conditional match + if(entry.shift != undefined) { + var shift = ((modifiers & AjaxViewer.SHIFT_KEY_MASK) != 0 ? true : false); + if(entry.shift ^ shift) + return false; + } + + if(entry.guestos != undefined) { + if(entry.guestos != guestos) + return false; + } + + if(entry.browser != undefined) { + if(entry.browser != browser) + return false; + } + + if(entry.browserVersion != undefined) { + if(entry.browserVersion != browserVersion) + return false; + } + + return true; + }, + isModifierInput : function(code) { return $.inArray(code, [AjaxViewer.ALT_KEY_MASK, AjaxViewer.SHIFT_KEY_MASK, AjaxViewer.CTRL_KEY_MASK, AjaxViewer.META_KEY_MASK]) >= 0; } }; -///////////////////////////////////////////////////////////////////////////// -// JsX11KeyboardMapper -// -function JsX11KeyboardMapper() { - KeyboardMapper.apply(this, arguments); - - this.jsX11KeysymMap = []; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CAPSLOCK] = AjaxViewer.X11_KEY_CAPSLOCK; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACKSPACE] = AjaxViewer.X11_KEY_BACKSPACE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_TAB] = AjaxViewer.X11_KEY_TAB; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ENTER] = AjaxViewer.X11_KEY_ENTER; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ESCAPE] = AjaxViewer.X11_KEY_ESCAPE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_INSERT] = AjaxViewer.X11_KEY_INSERT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DELETE] = AjaxViewer.X11_KEY_DELETE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_HOME] = AjaxViewer.X11_KEY_HOME; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_END] = AjaxViewer.X11_KEY_END; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEUP] = AjaxViewer.X11_KEY_PAGEUP; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEDOWN] = AjaxViewer.X11_KEY_PAGEDOWN; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_LEFT] = AjaxViewer.X11_KEY_LEFT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_UP] = AjaxViewer.X11_KEY_UP; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_RIGHT] = AjaxViewer.X11_KEY_RIGHT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DOWN] = AjaxViewer.X11_KEY_DOWN; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F1] = AjaxViewer.X11_KEY_F1; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F2] = AjaxViewer.X11_KEY_F2; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F3] = AjaxViewer.X11_KEY_F3; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F4] = AjaxViewer.X11_KEY_F4; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F5] = AjaxViewer.X11_KEY_F5; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F6] = AjaxViewer.X11_KEY_F6; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F7] = AjaxViewer.X11_KEY_F7; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F8] = AjaxViewer.X11_KEY_F8; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F9] = AjaxViewer.X11_KEY_F9; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F10] = AjaxViewer.X11_KEY_F10; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F11] = AjaxViewer.X11_KEY_F11; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F12] = AjaxViewer.X11_KEY_F12; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SHIFT] = AjaxViewer.X11_KEY_SHIFT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CTRL] = AjaxViewer.X11_KEY_CTRL; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ALT] = AjaxViewer.X11_KEY_ALT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_GRAVE_ACCENT] = AjaxViewer.X11_KEY_GRAVE_ACCENT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SUBSTRACT] = AjaxViewer.X11_KEY_SUBSTRACT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ADD] = AjaxViewer.X11_KEY_ADD; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_OPEN_BRACKET] = AjaxViewer.X11_KEY_OPEN_BRACKET; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CLOSE_BRACKET] = AjaxViewer.X11_KEY_CLOSE_BRACKET; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACK_SLASH] = AjaxViewer.X11_KEY_BACK_SLASH; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SINGLE_QUOTE] = AjaxViewer.X11_KEY_SINGLE_QUOTE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_COMMA] = AjaxViewer.X11_KEY_COMMA; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PERIOD] = AjaxViewer.X11_KEY_PERIOD; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_FORWARD_SLASH] = AjaxViewer.X11_KEY_FORWARD_SLASH; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DASH] = AjaxViewer.X11_KEY_DASH; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SEMI_COLON] = AjaxViewer.X11_KEY_SEMI_COLON; - - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD0] = AjaxViewer.X11_KEY_NUMPAD0; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD1] = AjaxViewer.X11_KEY_NUMPAD1; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD2] = AjaxViewer.X11_KEY_NUMPAD2; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD3] = AjaxViewer.X11_KEY_NUMPAD3; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD4] = AjaxViewer.X11_KEY_NUMPAD4; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD5] = AjaxViewer.X11_KEY_NUMPAD5; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD6] = AjaxViewer.X11_KEY_NUMPAD6; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD7] = AjaxViewer.X11_KEY_NUMPAD7; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD8] = AjaxViewer.X11_KEY_NUMPAD8; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_NUMPAD9] = AjaxViewer.X11_KEY_NUMPAD9; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DECIMAL_POINT] = AjaxViewer.X11_KEY_DECIMAL_POINT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DIVIDE] = AjaxViewer.X11_KEY_DIVIDE; - - this.jsX11KeysymMap[AjaxViewer.JS_KEY_MULTIPLY] = [ - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0 }, - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ASTERISK, modifiers: 0 }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ASTERISK, modifiers: 0 }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0 } - ]; - - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ADD] = false; - this.jsKeyPressX11KeysymMap = []; - this.jsKeyPressX11KeysymMap[61] = [ - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false } - ]; - this.jsKeyPressX11KeysymMap[43] = [ - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false }, - {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true }, - {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true } - ]; -} - -JsX11KeyboardMapper.prototype = new KeyboardMapper(); -JsX11KeyboardMapper.prototype.inputFeed = function(eventType, code, modifiers) { - if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) { - - // special handling for Alt + Ctrl + Ins, convert it into Alt-Ctrl-Del - if(code == AjaxViewer.JS_KEY_INSERT) { - if((modifiers & AjaxViewer.ALT_KEY_MASK) != 0 && (modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) { - this.mappedInput.push({type : eventType, code: 0xffff, modifiers: modifiers}); - return; - } - } - - var X11Keysym = code; - if(this.jsX11KeysymMap[code] != undefined) { - X11Keysym = this.jsX11KeysymMap[code]; - if(typeof this.jsX11KeysymMap[code] == "boolean") { - return; - } else if($.isArray(X11Keysym)) { - for(var i = 0; i < X11Keysym.length; i++) { - if(X11Keysym[i].type == eventType) { - this.mappedInput.push(X11Keysym[i]); - } - } - } else { - this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); - } - } else { - this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); - } - - // special handling for ALT/CTRL key - if(eventType == AjaxViewer.KEY_UP && (code == AjaxViewer.JS_KEY_ALT || code == code == AjaxViewer.JS_KEY_CTRL)) - this.mappedInput.push({type : eventType, code: this.jsX11KeysymMap[code], modifiers: modifiers}); - - } else if(eventType == AjaxViewer.KEY_PRESS) { - var X11Keysym = code; - X11Keysym = this.jsKeyPressX11KeysymMap[code]; - if(X11Keysym) { - if($.isArray(X11Keysym)) { - for(var i = 0; i < X11Keysym.length; i++) { - var shift = ((modifiers & AjaxViewer.SHIFT_KEY_MASK) != 0 ? true : false); - if(!(X11Keysym[i].shift ^ shift)) - this.mappedInput.push(X11Keysym[i]); - } - } else { - this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); - } - } - } -} - -///////////////////////////////////////////////////////////////////////////// -//JsCookedKeyboardMapper -// For Xen/KVM hypervisors, it accepts "cooked" keyborad events -// -function JsCookedKeyboardMapper() { - KeyboardMapper.apply(this, arguments); - - this.jsX11KeysymMap = []; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CAPSLOCK] = AjaxViewer.X11_KEY_CAPSLOCK; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACKSPACE] = AjaxViewer.X11_KEY_BACKSPACE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_TAB] = AjaxViewer.X11_KEY_TAB; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ENTER] = AjaxViewer.X11_KEY_ENTER; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ESCAPE] = AjaxViewer.X11_KEY_ESCAPE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_INSERT] = AjaxViewer.X11_KEY_INSERT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DELETE] = AjaxViewer.X11_KEY_DELETE; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_HOME] = AjaxViewer.X11_KEY_HOME; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_END] = AjaxViewer.X11_KEY_END; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEUP] = AjaxViewer.X11_KEY_PAGEUP; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEDOWN] = AjaxViewer.X11_KEY_PAGEDOWN; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_LEFT] = AjaxViewer.X11_KEY_LEFT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_UP] = AjaxViewer.X11_KEY_UP; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_RIGHT] = AjaxViewer.X11_KEY_RIGHT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_DOWN] = AjaxViewer.X11_KEY_DOWN; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F1] = AjaxViewer.X11_KEY_F1; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F2] = AjaxViewer.X11_KEY_F2; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F3] = AjaxViewer.X11_KEY_F3; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F4] = AjaxViewer.X11_KEY_F4; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F5] = AjaxViewer.X11_KEY_F5; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F6] = AjaxViewer.X11_KEY_F6; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F7] = AjaxViewer.X11_KEY_F7; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F8] = AjaxViewer.X11_KEY_F8; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F9] = AjaxViewer.X11_KEY_F9; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F10] = AjaxViewer.X11_KEY_F10; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F11] = AjaxViewer.X11_KEY_F11; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_F12] = AjaxViewer.X11_KEY_F12; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_SHIFT] = AjaxViewer.X11_KEY_SHIFT; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_CTRL] = AjaxViewer.X11_KEY_CTRL; - this.jsX11KeysymMap[AjaxViewer.JS_KEY_ALT] = AjaxViewer.X11_KEY_ALT; -} - -JsCookedKeyboardMapper.prototype = new KeyboardMapper(); -JsCookedKeyboardMapper.prototype.inputFeed = function(eventType, code, modifiers) { - if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) { - - // special handling for Alt + Ctrl + Ins, convert it into Alt-Ctrl-Del - if(code == AjaxViewer.JS_KEY_INSERT) { - if((modifiers & AjaxViewer.ALT_KEY_MASK) != 0 && (modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) { - this.mappedInput.push({type : eventType, code: 0xffff, modifiers: modifiers}); - return; - } - } - - var X11Keysym = code; - if(this.jsX11KeysymMap[code] != undefined) { - X11Keysym = this.jsX11KeysymMap[code]; - if(typeof this.jsX11KeysymMap[code] == "boolean") { - return; - } else if($.isArray(X11Keysym)) { - for(var i = 0; i < X11Keysym.length; i++) { - if(X11Keysym[i].type == eventType) { - this.mappedInput.push(X11Keysym[i]); - } - } - } else { - this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); - } - } else { - if((modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) { - this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); - } - } - - // special handling for ALT/CTRL key - if(eventType == AjaxViewer.KEY_UP && (code == AjaxViewer.JS_KEY_ALT || code == code == AjaxViewer.JS_KEY_CTRL)) - this.mappedInput.push({type : eventType, code: this.jsX11KeysymMap[code], modifiers: modifiers}); - - } else if(eventType == AjaxViewer.KEY_PRESS) { - var X11Keysym = code; - - // special handling for * and + key on number pad - if(code == AjaxViewer.JS_NUMPAD_MULTIPLY) { - this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); - this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: 42, modifiers: modifiers}); - this.mappedInput.push({type : AjaxViewer.KEY_UP, code: 42, modifiers: modifiers}); - this.mappedInput.push({type : AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); - return; - } - - if(code == AjaxViewer.JS_NUMPAD_PLUS) { - this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); - this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: 43, modifiers: modifiers}); - this.mappedInput.push({type : AjaxViewer.KEY_UP, code: 43, modifiers: modifiers}); - this.mappedInput.push({type : AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers}); - return; - } - - // ENTER/BACKSPACE key should already have been sent through KEY DOWN/KEY UP event - if(code == AjaxViewer.JS_KEY_ENTER || code == AjaxViewer.JS_KEY_BACKSPACE) - return; - - this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: X11Keysym, modifiers: modifiers}); - this.mappedInput.push({type : AjaxViewer.KEY_UP, code: X11Keysym, modifiers: modifiers}); - } -} - ///////////////////////////////////////////////////////////////////////////// // class AjaxViewer // @@ -653,12 +729,14 @@ AjaxViewer.prototype = { setupKeyboardTranslationTable : function() { this.keyboardMappers = []; - // this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_ENGLISH] = new JsX11KeyboardMapper(); - this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_ENGLISH] = new JsCookedKeyboardMapper(); - - // setup Japanese keyboard translation table - var mapper = new JsX11KeyboardMapper(); + + var mapper = new KeyboardMapper(); + this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_ENGLISH] = mapper; + mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_COOKED); + + mapper = new KeyboardMapper(); this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_JAPANESE] = mapper; + mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_RAW); // JP keyboard plugged in a English host OS /* @@ -1288,7 +1366,7 @@ AjaxViewer.prototype = { dispatchKeyboardInput : function(event, code, modifiers) { var keyboardMapper = ajaxViewer.getCurrentKeyboardMapper(); - keyboardMapper.inputFeed(event, code, modifiers); + keyboardMapper.inputFeed(event, code, modifiers, this.guestos, $.browser, $.browser.version); this.dispatchMappedKeyboardInput(keyboardMapper.getMappedInput()); }, diff --git a/console-proxy/pom.xml b/console-proxy/pom.xml index 8bfb75363f5..fc758cd04cc 100644 --- a/console-proxy/pom.xml +++ b/console-proxy/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-console-proxy Apache CloudStack Console Proxy org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT @@ -121,12 +120,6 @@ systemvm.zip - - ../patches/target/ - - cloud-scripts.tar.gz - - ../patches/systemvm/debian/config/root/.ssh @@ -138,7 +131,25 @@ - + + + + vmware + + + nonoss + + + + + org.apache.cloudstack + cloud-plugin-hypervisor-vmware + ${project.version} + + + org.apache.cloudstack + cloud-vmware-base + ${project.version} + + + + + systemvm + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + package + + exec + + + + + mkisofs + dist + + -quiet + -r + -o + systemvm.iso + systemvm.zip + cloud-scripts.tgz + authorized_keys + + + + + + + + diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyGCThread.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyGCThread.java index 158f9fec49f..7f82a965f69 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyGCThread.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyGCThread.java @@ -87,6 +87,7 @@ public class ConsoleProxyGCThread extends Thread { synchronized (connMap) { connMap.remove(key); + bReportLoad = true; } // close the server connection diff --git a/console-proxy/systemvm-descriptor.xml b/console-proxy/systemvm-descriptor.xml index 44ce2ebe782..7efe7fdfcb0 100644 --- a/console-proxy/systemvm-descriptor.xml +++ b/console-proxy/systemvm-descriptor.xml @@ -56,6 +56,7 @@ log4j-cloud.xml consoleproxy.properties + agent.properties diff --git a/console-proxy/ui/viewer-bad-sid.ftl b/console-proxy/ui/viewer-bad-sid.ftl index 246cb7f38d5..2f30ec36015 100644 --- a/console-proxy/ui/viewer-bad-sid.ftl +++ b/console-proxy/ui/viewer-bad-sid.ftl @@ -1,29 +1,29 @@ - - - - - - -
-

Unable to start console session as access is denied because of bad sid

-
- - - + + + + + + +
+

Unable to start console session as access is denied because of bad sid

+
+ + + diff --git a/console-proxy/ui/viewer-connect-failed.ftl b/console-proxy/ui/viewer-connect-failed.ftl index 57af5bd7e7b..9d907cacb43 100644 --- a/console-proxy/ui/viewer-connect-failed.ftl +++ b/console-proxy/ui/viewer-connect-failed.ftl @@ -1,29 +1,29 @@ - - - - - - -
-

Unable to start console session as connection is refused by the machine you are accessing

-
- - - + + + + + + +
+

Unable to start console session as connection is refused by the machine you are accessing

+
+ + + diff --git a/console-proxy/ui/viewer.ftl b/console-proxy/ui/viewer.ftl index 0dd7b391b47..d1b2b56d02d 100644 --- a/console-proxy/ui/viewer.ftl +++ b/console-proxy/ui/viewer.ftl @@ -1,59 +1,59 @@ - - - - - - - -${title} - - - - -
- - - - - + + + + + + + +${title} + + + + +
+ + + + + diff --git a/core/pom.xml b/core/pom.xml index 510cb04105e..15f0f7b7302 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-core Apache CloudStack Core org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT @@ -32,17 +31,7 @@ cloud-api ${project.version} - - org.apache.cloudstack - xapi - ${cs.xapi.version} - - - junit - junit - - - + commons-httpclient commons-httpclient @@ -58,6 +47,6 @@ install src - + test diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 2bb1145f1dd..7e53f03e431 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -80,6 +80,7 @@ import com.cloud.utils.component.Manager; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; import com.cloud.utils.script.Script; +import com.cloud.utils.ssh.SshHelper; /** * VirtualNetworkResource controls and configures virtual networking @@ -298,8 +299,77 @@ public class VirtualRoutingResource implements Manager { return new SetStaticNatRulesAnswer(cmd, results, endResult); } + protected Answer VPCLoadBalancerConfig(final LoadBalancerConfigCommand cmd) { + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + + if (routerIp == null) { + return new Answer(cmd); + } + + LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); + String[] config = cfgtr.generateConfiguration(cmd); + String tmpCfgFileContents = ""; + for (int i = 0; i < config.length; i++) { + tmpCfgFileContents += config[i]; + tmpCfgFileContents += "\n"; + } + File permKey = new File("/root/.ssh/id_rsa.cloud"); + + try { + SshHelper.scpTo(routerIp, 3922, "root", permKey, null, "/etc/haproxy/", tmpCfgFileContents.getBytes(), "haproxy.cfg.new", null); + + String[][] rules = cfgtr.generateFwRules(cmd); + + String[] addRules = rules[LoadBalancerConfigurator.ADD]; + String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; + String[] statRules = rules[LoadBalancerConfigurator.STATS]; + + String ip = cmd.getNic().getIp(); + String args = " -i " + ip; + StringBuilder sb = new StringBuilder(); + if (addRules.length > 0) { + for (int i = 0; i < addRules.length; i++) { + sb.append(addRules[i]).append(','); + } + + args += " -a " + sb.toString(); + } + + sb = new StringBuilder(); + if (removeRules.length > 0) { + for (int i = 0; i < removeRules.length; i++) { + sb.append(removeRules[i]).append(','); + } + + args += " -d " + sb.toString(); + } + + sb = new StringBuilder(); + if (statRules.length > 0) { + for (int i = 0; i < statRules.length; i++) { + sb.append(statRules[i]).append(','); + } + + args += " -s " + sb.toString(); + } + + String result = routerProxy("vpc_loadbalancer.sh", routerIp, args); + + if (result != null) { + return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); + } + return new Answer(cmd); + + } catch (Exception e) { + return new Answer(cmd, e); + } + } private Answer execute(LoadBalancerConfigCommand cmd) { + if ( cmd.getVpcId() != null ) { + return VPCLoadBalancerConfig(cmd); + } + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); File tmpCfgFile = null; try { @@ -520,7 +590,7 @@ public class VirtualRoutingResource implements Manager { } final String result = routerProxy("checkbatchs2svpn.sh", routerIP, args); - if (result == null || result.isEmpty()) { + if (result != null) { return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); } return new CheckS2SVpnConnectionsAnswer(cmd, true, result); diff --git a/core/src/com/cloud/async/AsyncJobVO.java b/core/src/com/cloud/async/AsyncJobVO.java index fc2cf5bccdf..742631367a3 100644 --- a/core/src/com/cloud/async/AsyncJobVO.java +++ b/core/src/com/cloud/async/AsyncJobVO.java @@ -119,28 +119,31 @@ public class AsyncJobVO implements AsyncJob { @Transient private boolean fromPreviousSession = false; - public AsyncJobVO() { - this.uuid = UUID.randomUUID().toString(); - } - public AsyncJobVO(long userId, long accountId, String cmd, String cmdInfo) { - this.userId = userId; - this.accountId = accountId; - this.cmd = cmd; - this.cmdInfo = cmdInfo; + public AsyncJobVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public AsyncJobVO(long userId, long accountId, String cmd, String cmdInfo, Long instanceId, Type instanceType) { + this.userId = userId; + this.accountId = accountId; + this.cmd = cmd; + this.cmdInfo = cmdInfo; this.callbackType = CALLBACK_POLLING; this.uuid = UUID.randomUUID().toString(); - } - - public AsyncJobVO(long userId, long accountId, String cmd, String cmdInfo, - int callbackType, String callbackAddress) { - - this(userId, accountId, cmd, cmdInfo); - this.callbackType = callbackType; - this.callbackAddress = callbackAddress; + this.instanceId = instanceId; + } + + public AsyncJobVO(long userId, long accountId, String cmd, String cmdInfo, + int callbackType, String callbackAddress, Long instanceId, Type instanceType) { + + this(userId, accountId, cmd, cmdInfo, instanceId, instanceType); + this.callbackType = callbackType; + this.callbackAddress = callbackAddress; this.uuid = UUID.randomUUID().toString(); } - + + @Override public Long getId() { return id; diff --git a/core/src/com/cloud/async/SyncQueueItemVO.java b/core/src/com/cloud/async/SyncQueueItemVO.java index f70ff852b5b..c3ef2f66711 100644 --- a/core/src/com/cloud/async/SyncQueueItemVO.java +++ b/core/src/com/cloud/async/SyncQueueItemVO.java @@ -24,24 +24,26 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; @Entity @Table(name="sync_queue_item") public class SyncQueueItemVO implements SyncQueueItem{ - @Id + @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private Long id = null; - + @Column(name="queue_id") - private Long queueId; - + private Long queueId; + @Column(name="content_type") - private String contentType; - + private String contentType; + @Column(name="content_id") - private Long contentId; + private Long contentId; @Column(name="queue_proc_msid") private Long lastProcessMsid; @@ -49,76 +51,89 @@ public class SyncQueueItemVO implements SyncQueueItem{ @Column(name="queue_proc_number") private Long lastProcessNumber; - @Column(name="created") - private Date created; + @Column(name="queue_proc_time") + @Temporal(TemporalType.TIMESTAMP) + private Date lastProcessTime; - public Long getId() { - return id; - } + @Column(name="created") + private Date created; + + public Long getId() { + return id; + } - public void setId(Long id) { - this.id = id; - } + public void setId(Long id) { + this.id = id; + } - public Long getQueueId() { - return queueId; - } + public Long getQueueId() { + return queueId; + } - public void setQueueId(Long queueId) { - this.queueId = queueId; - } + public void setQueueId(Long queueId) { + this.queueId = queueId; + } - @Override - public String getContentType() { - return contentType; - } + @Override + public String getContentType() { + return contentType; + } - public void setContentType(String contentType) { - this.contentType = contentType; - } - - @Override - public Long getContentId() { - return contentId; - } + public void setContentType(String contentType) { + this.contentType = contentType; + } + + @Override + public Long getContentId() { + return contentId; + } - public void setContentId(Long contentId) { - this.contentId = contentId; - } + public void setContentId(Long contentId) { + this.contentId = contentId; + } - public Long getLastProcessMsid() { - return lastProcessMsid; - } + public Long getLastProcessMsid() { + return lastProcessMsid; + } + + public void setLastProcessMsid(Long lastProcessMsid) { + this.lastProcessMsid = lastProcessMsid; + } - public void setLastProcessMsid(Long lastProcessMsid) { - this.lastProcessMsid = lastProcessMsid; - } - public Long getLastProcessNumber() { - return lastProcessNumber; - } + return lastProcessNumber; + } - public void setLastProcessNumber(Long lastProcessNumber) { - this.lastProcessNumber = lastProcessNumber; - } + public void setLastProcessNumber(Long lastProcessNumber) { + this.lastProcessNumber = lastProcessNumber; + } - public Date getCreated() { - return created; - } + public Date getCreated() { + return created; + } - public void setCreated(Date created) { - this.created = created; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("SyncQueueItemVO {id:").append(getId()).append(", queueId: ").append(getQueueId()); - sb.append(", contentType: ").append(getContentType()); - sb.append(", contentId: ").append(getContentId()); - sb.append(", lastProcessMsid: ").append(getLastProcessMsid()); - sb.append(", lastprocessNumber: ").append(getLastProcessNumber()); - sb.append(", created: ").append(getCreated()); - sb.append("}"); - return sb.toString(); - } + public void setCreated(Date created) { + this.created = created; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("SyncQueueItemVO {id:").append(getId()).append(", queueId: ").append(getQueueId()); + sb.append(", contentType: ").append(getContentType()); + sb.append(", contentId: ").append(getContentId()); + sb.append(", lastProcessMsid: ").append(getLastProcessMsid()); + sb.append(", lastprocessNumber: ").append(getLastProcessNumber()); + sb.append(", lastProcessTime: ").append(getLastProcessTime()); + sb.append(", created: ").append(getCreated()); + sb.append("}"); + return sb.toString(); + } + + public Date getLastProcessTime() { + return lastProcessTime; + } + + public void setLastProcessTime(Date lastProcessTime) { + this.lastProcessTime = lastProcessTime; + } } diff --git a/core/src/com/cloud/async/SyncQueueVO.java b/core/src/com/cloud/async/SyncQueueVO.java index 741312f74dd..f70b320c786 100644 --- a/core/src/com/cloud/async/SyncQueueVO.java +++ b/core/src/com/cloud/async/SyncQueueVO.java @@ -14,10 +14,10 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. + package com.cloud.async; import java.util.Date; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -30,110 +30,106 @@ import javax.persistence.TemporalType; @Entity @Table(name="sync_queue") public class SyncQueueVO { - @Id + + @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private Long id; @Column(name="sync_objtype") - private String syncObjType; - + + private String syncObjType; + @Column(name="sync_objid") - private Long syncObjId; - + private Long syncObjId; + @Column(name="queue_proc_number") private Long lastProcessNumber; - - @Column(name="queue_proc_time") - @Temporal(TemporalType.TIMESTAMP) - private Date lastProcessTime; - - @Column(name="queue_proc_msid") - private Long lastProcessMsid; - + @Column(name="created") @Temporal(TemporalType.TIMESTAMP) - private Date created; - + private Date created; + @Column(name="last_updated") @Temporal(TemporalType.TIMESTAMP) - private Date lastUpdated; + private Date lastUpdated; + + @Column(name="queue_size") + private long queueSize = 0; + + @Column(name="queue_size_limit") + private long queueSizeLimit = 0; + + public Long getId() { + return id; + } + + public String getSyncObjType() { + return syncObjType; + } + + public void setSyncObjType(String syncObjType) { + this.syncObjType = syncObjType; + } + + public Long getSyncObjId() { + return syncObjId; + } + + public void setSyncObjId(Long syncObjId) { + this.syncObjId = syncObjId; + } - public Long getId() { - return id; - } + public Long getLastProcessNumber() { + return lastProcessNumber; + } + + public void setLastProcessNumber(Long number) { + lastProcessNumber = number; + } - public void setId(Long id) { - this.id = id; - } + public Date getCreated() { + return created; + } - public String getSyncObjType() { - return syncObjType; - } + public void setCreated(Date created) { + this.created = created; + } - public void setSyncObjType(String syncObjType) { - this.syncObjType = syncObjType; - } + public Date getLastUpdated() { + return lastUpdated; + } - public Long getSyncObjId() { - return syncObjId; - } + public void setLastUpdated(Date lastUpdated) { + this.lastUpdated = lastUpdated; + } - public void setSyncObjId(Long syncObjId) { - this.syncObjId = syncObjId; - } - - public Long getLastProcessNumber() { - return lastProcessNumber; - } - - public void setLastProcessNumber(Long number) { - lastProcessNumber = number; - } + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("SyncQueueVO {id:").append(getId()); + sb.append(", syncObjType: ").append(getSyncObjType()); + sb.append(", syncObjId: ").append(getSyncObjId()); + sb.append(", lastProcessNumber: ").append(getLastProcessNumber()); + sb.append(", lastUpdated: ").append(getLastUpdated()); + sb.append(", created: ").append(getCreated()); + sb.append(", count: ").append(getQueueSize()); + sb.append("}"); + return sb.toString(); + } - public Date getLastProcessTime() { - return lastProcessTime; - } + public long getQueueSize() { + return queueSize; + } - public void setLastProcessTime(Date lastProcessTime) { - this.lastProcessTime = lastProcessTime; - } + public void setQueueSize(long queueSize) { + this.queueSize = queueSize; + } - public Long getLastProcessMsid() { - return lastProcessMsid; - } + public long getQueueSizeLimit() { + return queueSizeLimit; + } - public void setLastProcessMsid(Long lastProcessMsid) { - this.lastProcessMsid = lastProcessMsid; - } - - public Date getCreated() { - return created; - } - - public void setCreated(Date created) { - this.created = created; - } - - public Date getLastUpdated() { - return lastUpdated; - } - - public void setLastUpdated(Date lastUpdated) { - this.lastUpdated = lastUpdated; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("SyncQueueVO {id:").append(getId()); - sb.append(", syncObjType: ").append(getSyncObjType()); - sb.append(", syncObjId: ").append(getSyncObjId()); - sb.append(", lastProcessMsid: ").append(getLastProcessMsid()); - sb.append(", lastProcessNumber: ").append(getLastProcessNumber()); - sb.append(", lastProcessTime: ").append(getLastProcessTime()); - sb.append(", lastUpdated: ").append(getLastUpdated()); - sb.append(", created: ").append(getCreated()); - sb.append("}"); - return sb.toString(); - } + public void setQueueSizeLimit(long queueSizeLimit) { + this.queueSizeLimit = queueSizeLimit; + } } diff --git a/debian/changelog b/debian/changelog index c02d7451f06..c3243aad5e3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,27 @@ +cloud (1:4.0.0-1) unstable; urgency=low + + * Bumping the version to 4.0.0 + + -- Chip Childers Fri, 5 Oct 2012 16:00:00 -0500 + +cloud (1:4.0.0-beta6) unstable; urgency=low + + * Bumping the version to 4.0 Beta 6 + + -- Wido den Hollander Fri, 5 Oct 2012 11:41:17 +0200 + +cloud (1:4.0.0-beta1) unstable; urgency=low + + * Bumping the version to 4.0 Beta 1 + + -- Wido den Hollander Wed, 26 Sep 2012 21:14:48 +0200 + +cloud (4.0.0-rc2) unstable; urgency=low + + * Bumping the version to 4.0 RC2 + + -- Wido den Hollander Mon, 24 Sep 2012 11:30:29 +0200 + cloud (4.0.0-rc1) unstable; urgency=low * Bumping the version to 4.0 RC1 diff --git a/debian/cloud-utils.install b/debian/cloud-utils.install index b26a02c5095..39c357a1fa6 100644 --- a/debian/cloud-utils.install +++ b/debian/cloud-utils.install @@ -17,8 +17,6 @@ /usr/share/java/cloud-utils.jar /usr/share/java/cloud-api.jar -/usr/share/doc/cloud/sccs-info /usr/share/doc/cloud/version-info -/usr/share/doc/cloud/configure-info /usr/bin/cloud-sccs /usr/bin/cloud-gitrevs diff --git a/debian/control b/debian/control index 265c050cc13..44736d74511 100644 --- a/debian/control +++ b/debian/control @@ -2,13 +2,13 @@ Source: cloud Section: libs Priority: extra Maintainer: Wido den Hollander -Build-Depends: debhelper (>= 7), openjdk-6-jdk, tomcat6, libws-commons-util-java, libcommons-dbcp-java, libcommons-collections-java, libcommons-httpclient-java, libservlet2.5-java, genisoimage, python-mysqldb, maven3 | maven (>= 3), liblog4j1.2-java (>= 1.2.16) +Build-Depends: debhelper (>= 7), openjdk-6-jdk, tomcat6, libws-commons-util-java, libcommons-codec-java (>= 1.5), libcommons-httpclient-java (>= 3.1), libservlet2.5-java, genisoimage, python-mysqldb, maven3 | maven (>= 3), liblog4j1.2-java (>= 1.2.16) Standards-Version: 3.8.1 Homepage: http://www.cloudstack.org/ Package: cloud-deps Architecture: any -Depends: openjdk-6-jre, libcommons-discovery-java (>= 0.5), libcommons-dbcp-java (>= 1.4), libcommons-pool-java (>= 1.5.6), libcommons-codec-java (>= 1.5) +Depends: openjdk-6-jre, libcommons-codec-java (>= 1.5), libcommons-httpclient-java (>= 3.1) Description: CloudStack library dependencies This package contains a number of third-party dependencies not shipped by distributions, required to run the CloudStack @@ -24,7 +24,7 @@ Description: CloudStack agent library dependencies Package: cloud-utils Architecture: any -Depends: openjdk-6-jre, python, libcglib-java (>= 2.2.2), libjsch-java (>= 0.1.42), libbackport-util-concurrent-java (>= 3.1) +Depends: openjdk-6-jre, python, libcglib-java (>= 2.2.2), libjsch-java (>= 0.1.42), libbackport-util-concurrent-java (>= 3.1), libcommons-dbcp-java (>= 1.4), libcommons-pool-java (>= 1.5.6) Description: CloudStack utility library The CloudStack utility libraries provide a set of Java classes used in the CloudStack environment. @@ -40,7 +40,7 @@ Description: CloudStack management server UI Package: cloud-server Architecture: any -Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), libservlet2.5-java +Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), cloud-scripts (= ${source:Version}), libservlet2.5-java Description: CloudStack server library The CloudStack server libraries provide a set of Java classes used in the CloudStack management server. @@ -84,13 +84,13 @@ Description: CloudStack Python library Package: cloud-agent-libs Architecture: any -Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java +Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}) Description: CloudStack agent libraries The CloudStack agent libraries are used by the Cloud Agent. Package: cloud-agent Architecture: any -Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-scripts (= ${source:Version}), libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, ebtables, vlan, libcommons-httpclient-java, libservlet2.5-java, liblog4j1.2-java (>= 1.2.16), libjna-java, wget, jsvc, lsb-base (>= 3.2) +Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}), cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-scripts (= ${source:Version}), libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, ebtables, vlan, liblog4j1.2-java (>= 1.2.16), libjna-java, wget, jsvc, lsb-base (>= 3.2) Description: CloudStack agent The CloudStack agent is in charge of managing shared computing resources in a CloudStack powered cloud. Install this package if this computer diff --git a/debian/rules b/debian/rules index 5c5ddcbe0a1..daacaf994cc 100755 --- a/debian/rules +++ b/debian/rules @@ -25,7 +25,7 @@ configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. - ./waf configure --prefix=/usr --libdir=/usr/lib --bindir=/usr/bin --javadir=/usr/share/java --sharedstatedir=/var/lib --localstatedir=/var --sysconfdir=/etc --mandir=/usr/share/man --libexecdir=/usr/bin --with-tomcat=/usr/share/tomcat6 --tomcat-user=cloud --fast --package-version=$(PACKAGEVERSION) + ./waf configure --prefix=/usr --libdir=/usr/lib --bindir=/usr/bin --javadir=/usr/share/java --sharedstatedir=/var/lib --localstatedir=/var --sysconfdir=/etc --mandir=/usr/share/man --libexecdir=/usr/bin --with-tomcat=/usr/share/tomcat6 --tomcat-user=cloud --fast ./waf showconfig touch configure-stamp @@ -38,7 +38,7 @@ build-arch: build-arch-stamp build-arch-stamp: configure-stamp # Add here commands to compile the arch part of the package. - ./waf build --build-number=$(BUILDNUMBER) --package-version=$(PACKAGEVERSION) + ./waf build touch $@ # build-indep: build-indep-stamp @@ -90,8 +90,11 @@ install-arch: binary-common: dh_testdir dh_testroot - dh_installchangelogs - dh_installdocs -A README.html + dh_installchangelogs + dh_installdocs LICENSE + dh_installdocs DISCLAIMER + dh_installdocs NOTICE + dh_installdocs INSTALL.md # dh_installexamples # dh_installmenu # dh_installdebconf @@ -114,7 +117,8 @@ binary-common: # dh_shlibdeps dh_gencontrol dh_md5sums - dh_builddeb + mkdir -p ./artifacts/debs + dh_builddeb --destdir=$(CURDIR)/artifacts/debs # Build architecture independant packages using the common target. # binary-indep: build-indep install-indep # $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common diff --git a/deps/XenServerJava/BSD b/deps/XenServerJava/BSD deleted file mode 100644 index 634d6890be7..00000000000 --- a/deps/XenServerJava/BSD +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) Citrix Systems, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - 1) Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2) Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/deps/XenServerJava/LICENSE.Apache-2.0.txt b/deps/XenServerJava/LICENSE.Apache-2.0.txt deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/deps/XenServerJava/LICENSE.Apache-2.0.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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/deps/XenServerJava/LICENSE.txt b/deps/XenServerJava/LICENSE.txt deleted file mode 100644 index 76c4a2240fa..00000000000 --- a/deps/XenServerJava/LICENSE.txt +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) Citrix Systems, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - 1) Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2) Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/deps/XenServerJava/README.txt b/deps/XenServerJava/README.txt deleted file mode 100644 index a7cea3549c8..00000000000 --- a/deps/XenServerJava/README.txt +++ /dev/null @@ -1,46 +0,0 @@ -XenServerJava -============= - -Version 5.6.100-1. - -XenServerJava is a complete SDK for Citrix XenServer, exposing the XenServer -API as Java classes. - -For XenServer documentation, see http://docs.xensource.com. -XenServerJava includes a class for every XenServer class, and a method for -each XenServer API call, so API documentation and examples written for -for other languages will apply equally well to Java. -In particular, the SDK Guide and API Documentation are ideal for developers -wishing to use XenServerJava. - -For community content, blogs, and downloads, visit the XenServer Developer -Network at http://community.citrix.com/cdn/xs. - -XenServerJava is free sofware. You can redistribute and modify it under the -terms of the BSD 2-clause license. See LICENSE.txt for details. - -This library may be accompanied by pedagogical examples. These do not form -part of this library, and are licensed for redistribution and modification -under less restrictive terms. Such examples are licensed clearly at the top -of each file. - -XenServerJava is dependent upon Apache XML-RPC and WS-Commons, both by The -Apache Software Foundation. We would like to thank the ASF and the -Apache XML-RPC development team in particular. -Both are licensed under the Apache Software License 2.0; see -LICENSE.Apache-2.0.txt for details. - -We test with version 3.1 of Apache XML-RPC, and version 1.0.2 of WS-Commons. -We recommend that you use these versions, though others may work. - -Downloads ---------- - -XenServerJava is available in three separate archives, one for the compiled -binaries, one for the source code, and one containing sample code. - -All three archives are available from the XenServer Developer Network at -http://community.citrix.com/cdn/xs. - -Apache XML-RPC is available from http://ws.apache.org/xmlrpc/. -WS-Commons is available from http://ws.apache.org/commons/. diff --git a/deps/XenServerJava/pom.xml b/deps/XenServerJava/pom.xml index 13375144534..18ba54f56a3 100644 --- a/deps/XenServerJava/pom.xml +++ b/deps/XenServerJava/pom.xml @@ -16,13 +16,12 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml xapi diff --git a/deps/install-non-oss.sh b/deps/install-non-oss.sh index 9c65a311b94..28eb03e1562 100755 --- a/deps/install-non-oss.sh +++ b/deps/install-non-oss.sh @@ -19,7 +19,13 @@ mvn install:install-file -Dfile=cloud-iControl.jar -DgroupId=com.cloud.com.f5 -DartifactId=icontrol -Dversion=1.0 -Dpackaging=jar mvn install:install-file -Dfile=cloud-netscaler.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler -Dversion=1.0 -Dpackaging=jar mvn install:install-file -Dfile=cloud-netscaler-sdx.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler-sdx -Dversion=1.0 -Dpackaging=jar -mvn install:install-file -Dfile=cloud-manageontap.jar -DgroupId=com.cloud.com.netapp -DartifactId=manageontap -Dversion=1.0 -Dpackaging=jar -mvn install:install-file -Dfile=vmware-vim.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim -Dversion=1.0 -Dpackaging=jar -mvn install:install-file -Dfile=vmware-vim25.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25 -Dversion=1.0 -Dpackaging=jar -mvn install:install-file -Dfile=vmware-apputils.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-apputils -Dversion=1.0 -Dpackaging=jar +# +# From http://support.netapp.com/ (not available online, contact your support representative) +# Version: 4.0 +mvn install:install-file -Dfile=manageontap.jar -DgroupId=com.cloud.com.netapp -DartifactId=manageontap -Dversion=4.0 -Dpackaging=jar +# +# From https://my.vmware.com/group/vmware/get-download?downloadGroup=VSDK41 +# Version: 4.1, Release-date: 2010-07-13, Build: 257238 +mvn install:install-file -Dfile=vim25.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25 -Dversion=4.1 -Dpackaging=jar +mvn install:install-file -Dfile=apputils.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-apputils -Dversion=4.1 -Dpackaging=jar +mvn install:install-file -Dfile=vim.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim -Dversion=4.1 -Dpackaging=jar diff --git a/deps/pom.xml b/deps/pom.xml index 1e2008337d5..38bb17108c0 100644 --- a/deps/pom.xml +++ b/deps/pom.xml @@ -16,8 +16,7 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-deps Apache CloudStack Dependencies @@ -25,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT @@ -176,7 +175,20 @@ - + + + + + + org.apache.maven.plugins + maven-dependency-plugin + [2.0,) + + copy-dependencies + + + + diff --git a/developer/pom.xml b/developer/pom.xml new file mode 100644 index 00000000000..bba914be752 --- /dev/null +++ b/developer/pom.xml @@ -0,0 +1,340 @@ + + + 4.0.0 + cloud-developer + Apache CloudStack Developer Tools + pom + + org.apache.cloudstack + cloudstack + 4.1.0-SNAPSHOT + + + + mysql + mysql-connector-java + 5.1.21 + runtime + + + + install + + + + + deploydb + + + deploydb + + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0-alpha-2 + + + initialize + + read-project-properties + + + + ${project.parent.basedir}/utils/conf/db.properties + ${project.parent.basedir}/utils/conf/db.properties.override + + true + + + + + + maven-antrun-plugin + 1.7 + + + generate-resources + + run + + + + + + + + + + + + + + + + + + + + org.codehaus.mojo + sql-maven-plugin + 1.5 + + + + mysql + mysql-connector-java + ${cs.mysql.version} + + + + org.gjt.mm.mysql.Driver + jdbc:mysql://${db.cloud.host}:${db.cloud.port}/cloud + ${db.cloud.username} + ${db.cloud.password} + + ${maven.test.skip} + true + + + + + drop-database + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + drop database if exists `cloud` + + + + create-database + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + create database `cloud` + + + + grant-user-cloud + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + GRANT ALL ON cloud.* to + ${db.cloud.username}@`localhost` identified by + '${db.cloud.password}'; + + + + grant-user-cloud-all + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + GRANT ALL ON cloud.* to + ${db.cloud.username}@`%` identified by + '${db.cloud.password}'; + + + + drop-database-usage + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + drop database if exists `cloud_usage` + + + + create-database-usage + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + create database `cloud_usage` + + + + grant-user-cloud-usage + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + GRANT ALL ON cloud_usage.* to + ${db.cloud.username}@`localhost` identified by + '${db.cloud.password}'; + + + + grant-user-cloud-usage-all + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + GRANT ALL ON cloud_usage.* to + ${db.cloud.username}@`%` identified by + '${db.cloud.password}'; + + + + drop-database-cloudbridge + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + drop database if exists `cloudbridge` + + + + create-database-cloudbridge + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + create database `cloudbridge` + + + + grant-user-cloud-bridge + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + GRANT ALL ON cloudbridge.* to + ${db.cloud.username}@`localhost` identified by + '${db.cloud.password}'; + + + + grant-user-cloud-bridge-all + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.cloud.host}:${db.cloud.port} + GRANT ALL ON cloudbridge.* to + ${db.cloud.username}@`%` identified by + '${db.cloud.password}'; + + + + create-schema + process-test-resources + + execute + + + + ${basedir}/target/db/create-schema.sql + ${basedir}/target/db/create-schema-premium.sql + ${basedir}/target/db/templates.sql + ${basedir}/target/db/create-index-fk.sql + ${basedir}/target/db/cloudbridge_schema.sql + ${basedir}/target/db/cloudbridge_multipart.sql + ${basedir}/target/db/cloudbridge_index.sql + ${basedir}/target/db/cloudbridge_multipart_alter.sql + ${basedir}/target/db/cloudbridge_bucketpolicy.sql + ${basedir}/target/db/cloudbridge_policy_alter.sql + ${basedir}/target/db/cloudbridge_offering.sql + ${basedir}/target/db/cloudbridge_offering_alter.sql + + + + + prefill-schema + process-test-resources + + execute + + + INSERT INTO `cloud`.`domain` (id, name, + parent, path, owner) VALUES (1, 'ROOT', NULL, '/', + 2) + + + + prefill-configuration + process-test-resources + + execute + + + INSERT INTO `cloud`.`configuration` + (category, instance, component, name, value) VALUES + ('Hidden', 'DEFAULT', 'management-server', 'init', + 'false') + INSERT INTO `cloud`.`configuration` + (category, instance, component, name, value) VALUES + ('Advanced', 'DEFAULT', 'management-server', 'integration.api.port', + '8096') + + + + + + + + + diff --git a/docs/.tx/config b/docs/.tx/config new file mode 100644 index 00000000000..9b02286ea66 --- /dev/null +++ b/docs/.tx/config @@ -0,0 +1,2139 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +[main] +host = https://www.transifex.net + +[ACS_DOCS.about-clusters] +file_filter = /about-cluster.po +source_file = pot/about-clusters.pot +source_lang = en +type = PO + +[ACS_DOCS.about-hosts] +file_filter = /about-hosts.po +source_file = pot/about-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.about-physical-networks] +file_filter = /about-physical-networks.po +source_file = pot/about-physical-networks.pot +source_lang = en +type = PO + + + +[ACS_DOCS.about-pods] +file_filter = /about-pods.po +source_file = pot/about-pods.pot +source_lang = en +type = PO + +[ACS_DOCS.about-primary-storage] +file_filter = /about-primary-storage.po +source_file = pot/about-primary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.about-secondary-storage] +file_filter = /about-secondary-storage.po +source_file = pot/about-secondary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.about-virtual-networks] +file_filter = /about-virtual-networks.po +source_file = pot/about-virtual-networks.pot +source_lang = en +type = PO + +[ACS_DOCS.about-working-with-vms] +file_filter = /about-working-with-vms.po +source_file = pot/about-working-with-vms.pot +source_lang = en +type = PO + +[ACS_DOCS.about-zones] +file_filter = /about-zones.po +source_file = pot/about-zones.pot +source_lang = en +type = PO + +[ACS_DOCS.accept-membership-invite] +file_filter = /accept-membership-invite.po +source_file = pot/accept-membership-invite.pot +source_lang = en +type = PO + +[ACS_DOCS.accessing-vms] +file_filter = /accessing-vms.po +source_file = pot/accessing-vms.pot +source_lang = en +type = PO + +[ACS_DOCS.accounts] +file_filter = /accounts.po +source_file = pot/accounts.pot +source_lang = en +type = PO + +[ACS_DOCS.accounts-users-domains] +file_filter = /accounts-users-domains.po +source_file = pot/accounts-users-domains.pot +source_lang = en +type = PO + +[ACS_DOCS.acquire-new-ip-address] +file_filter = /acquire-new-ip-address.po +source_file = pot/acquire-new-ip-address.pot +source_lang = en +type = PO + +[ACS_DOCS.add-additional-guest-network] +file_filter = /add-additional-guest-network.po +source_file = pot/add-additional-guest-network.pot +source_lang = en +type = PO + +[ACS_DOCS.added-API-commands] +file_filter = /added-API-commands.po +source_file = pot/added-API-commands.pot +source_lang = en +type = PO + +[ACS_DOCS.added-cloudPlatform-error-codes] +file_filter = /added-cloudPlatform-error-codes.po +source_file = pot/added-cloudPlatform-error-codes.pot +source_lang = en +type = PO + +[ACS_DOCS.adding-IP-addresses-for-the-public-network] +file_filter = /adding-IP-addresses-for-the-public-network.po +source_file = pot/adding-IP-addresses-for-the-public-network.pot +source_lang = en +type = PO + +[ACS_DOCS.add-ingress-egress-rules] +file_filter = /add-ingress-egress-rules.po +source_file = pot/add-ingress-egress-rules.pot +source_lang = en +type = PO + +[ACS_DOCS.add-iso] +file_filter = /add-iso.po +source_file = pot/add-iso.pot +source_lang = en +type = PO + +[ACS_DOCS.add-load-balancer-rule] +file_filter = /add-load-balancer-rule.po +source_file = pot/add-load-balancer-rule.pot +source_lang = en +type = PO + +[ACS_DOCS.add-members-to-projects] +file_filter = /add-members-to-projects.po +source_file = pot/add-members-to-projects.pot +source_lang = en +type = PO + +[ACS_DOCS.add-more-clusters] +file_filter = /add-more-clusters.po +source_file = pot/add-more-clusters.pot +source_lang = en +type = PO + +[ACS_DOCS.add-password-management-to-templates] +file_filter = /add-password-management-to-templates.po +source_file = pot/add-password-management-to-templates.pot +source_lang = en +type = PO + +[ACS_DOCS.add-primary-storage] +file_filter = /add-primary-storage.po +source_file = pot/add-primary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.add-projects-members-from-ui] +file_filter = /add-projects-members-from-ui.po +source_file = pot/add-projects-members-from-ui.pot +source_lang = en +type = PO + +[ACS_DOCS.add-secondary-storage] +file_filter = /add-secondary-storage.po +source_file = pot/add-secondary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.add-security-group] +file_filter = /add-security-group.po +source_file = pot/add-security-group.pot +source_lang = en +type = PO + +[ACS_DOCS.admin-alerts] +file_filter = /admin-alerts.po +source_file = pot/admin-alerts.pot +source_lang = en +type = PO + +[ACS_DOCS.admin-guide] +file_filter = /admin-guide.po +source_file = pot/admin-guide.pot +source_lang = en +type = PO + +[ACS_DOCS.advanced-zone-configuration] +file_filter = /advanced-zone-configuration.po +source_file = pot/advanced-zone-configuration.pot +source_lang = en +type = PO + +[ACS_DOCS.advanced-zone-guest-ip-addresses] +file_filter = /advanced-zone-guest-ip-addresses.po +source_file = pot/advanced-zone-guest-ip-addresses.pot +source_lang = en +type = PO + +[ACS_DOCS.advanced-zone-network-traffic-types] +file_filter = /advanced-zone-network-traffic-types.po +source_file = pot/advanced-zone-network-traffic-types.pot +source_lang = en +type = PO + +[ACS_DOCS.advanced-zone-physical-network-configuration] +file_filter = /advanced-zone-physical-network-configuration.po +source_file = pot/advanced-zone-physical-network-configuration.pot +source_lang = en +type = PO + +[ACS_DOCS.advanced-zone-public-ip-addresses] +file_filter = /advanced-zone-public-ip-addresses.po +source_file = pot/advanced-zone-public-ip-addresses.pot +source_lang = en +type = PO + +[ACS_DOCS.alerts] +file_filter = /alerts.po +source_file = pot/alerts.pot +source_lang = en +type = PO + +[ACS_DOCS.allocators] +file_filter = /allocators.po +source_file = pot/allocators.pot +source_lang = en +type = PO + +[ACS_DOCS.api-reference] +file_filter = /api-reference.po +source_file = pot/api-reference.pot +source_lang = en +type = PO + +[ACS_DOCS.appendix-a-time-zones] +file_filter = /appendix-a-time-zones.po +source_file = pot/appendix-a-time-zones.pot +source_lang = en +type = PO + +[ACS_DOCS.asynchronous-commands-example] +file_filter = /asynchronous-commands-example.po +source_file = pot/asynchronous-commands-example.pot +source_lang = en +type = PO + +[ACS_DOCS.asynchronous-commands] +file_filter = /asynchronous-commands.po +source_file = pot/asynchronous-commands.pot +source_lang = en +type = PO + +[ACS_DOCS.attaching-volume] +file_filter = /attaching-volume.po +source_file = pot/attaching-volume.pot +source_lang = en +type = PO + +[ACS_DOCS.attach-iso-to-vm] +file_filter = /attach-iso-to-vm.po +source_file = pot/attach-iso-to-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.Author_Group] +file_filter = /Author_Group.po +source_file = pot/Author_Group.pot +source_lang = en +type = PO + +[ACS_DOCS.automatic-snapshot-creation-retention] +file_filter = /automatic-snapshot-creation-retention.po +source_file = pot/automatic-snapshot-creation-retention.pot +source_lang = en +type = PO + +[ACS_DOCS.aws-ec2-configuration] +file_filter = /aws-ec2-configuration.po +source_file = pot/aws-ec2-configuration.pot +source_lang = en +type = PO + +[ACS_DOCS.aws-ec2-introduction] +file_filter = /aws-ec2-introduction.po +source_file = pot/aws-ec2-introduction.pot +source_lang = en +type = PO + +[ACS_DOCS.aws-ec2-requirements] +file_filter = /aws-ec2-requirements.po +source_file = pot/aws-ec2-requirements.pot +source_lang = en +type = PO + +[ACS_DOCS.aws-ec2-supported-commands] +file_filter = /aws-ec2-supported-commands.po +source_file = pot/aws-ec2-supported-commands.pot +source_lang = en +type = PO + +[ACS_DOCS.aws-ec2-user-setup] +file_filter = /aws-ec2-user-setup.po +source_file = pot/aws-ec2-user-setup.pot +source_lang = en +type = PO + +[ACS_DOCS.aws-interface-guide] +file_filter = /aws-interface-guide.po +source_file = pot/aws-interface-guide.pot +source_lang = en +type = PO + +[ACS_DOCS.basic-zone-configuration] +file_filter = /basic-zone-configuration.po +source_file = pot/basic-zone-configuration.pot +source_lang = en +type = PO + +[ACS_DOCS.basic-zone-guest-ip-addresses] +file_filter = /basic-zone-guest-ip-addresses.po +source_file = pot/basic-zone-guest-ip-addresses.pot +source_lang = en +type = PO + +[ACS_DOCS.basic-zone-network-traffic-types] +file_filter = /basic-zone-network-traffic-types.po +source_file = pot/basic-zone-network-traffic-types.pot +source_lang = en +type = PO + +[ACS_DOCS.basic-zone-physical-network-configuration] +file_filter = /basic-zone-physical-network-configuration.po +source_file = pot/basic-zone-physical-network-configuration.pot +source_lang = en +type = PO + +[ACS_DOCS.best-practices-for-vms] +file_filter = /best-practices-for-vms.po +source_file = pot/best-practices-for-vms.pot +source_lang = en +type = PO + +[ACS_DOCS.best-practices-primary-storage] +file_filter = /best-practices-primary-storage.po +source_file = pot/best-practices-primary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.best-practices-secondary-storage] +file_filter = /best-practices-secondary-storage.po +source_file = pot/best-practices-secondary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.best-practices-templates] +file_filter = /best-practices-templates.po +source_file = pot/best-practices-templates.pot +source_lang = en +type = PO + +[ACS_DOCS.best-practices-virtual-router] +file_filter = /best-practices-virtual-router.po +source_file = pot/best-practices-virtual-router.pot +source_lang = en +type = PO + +[ACS_DOCS.Book_Info_Build_All] +file_filter = /Book_Info_Build_All.po +source_file = pot/Book_Info_Build_All.pot +source_lang = en +type = PO + +[ACS_DOCS.Book_Info] +file_filter = /Book_Info.po +source_file = pot/Book_Info.pot +source_lang = en +type = PO + +[ACS_DOCS.change-console-proxy-ssl-certificate-domain] +file_filter = /change-console-proxy-ssl-certificate-domain.po +source_file = pot/change-console-proxy-ssl-certificate-domain.pot +source_lang = en +type = PO + +[ACS_DOCS.change-host-password] +file_filter = /change-host-password.po +source_file = pot/change-host-password.pot +source_lang = en +type = PO + +[ACS_DOCS.change-network-offering-on-guest-network] +file_filter = /change-network-offering-on-guest-network.po +source_file = pot/change-network-offering-on-guest-network.pot +source_lang = en +type = PO + +[ACS_DOCS.change-to-behavior-of-list-commands] +file_filter = /change-to-behavior-of-list-commands.po +source_file = pot/change-to-behavior-of-list-commands.pot +source_lang = en +type = PO + +[ACS_DOCS.changing-root-password] +file_filter = /changing-root-password.po +source_file = pot/changing-root-password.pot +source_lang = en +type = PO + +[ACS_DOCS.changing-secondary-storage-ip] +file_filter = /changing-secondary-storage-ip.po +source_file = pot/changing-secondary-storage-ip.pot +source_lang = en +type = PO + +[ACS_DOCS.changing-secondary-storage-servers] +file_filter = /changing-secondary-storage-servers.po +source_file = pot/changing-secondary-storage-servers.pot +source_lang = en +type = PO + +[ACS_DOCS.changing-secondary-storage-serversp] +file_filter = /changing-secondary-storage-serversp.po +source_file = pot/changing-secondary-storage-serversp.pot +source_lang = en +type = PO + +[ACS_DOCS.changing-service-offering-for-vm] +file_filter = /changing-service-offering-for-vm.po +source_file = pot/changing-service-offering-for-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.changing-vm-name-os-group] +file_filter = /changing-vm-name-os-group.po +source_file = pot/changing-vm-name-os-group.pot +source_lang = en +type = PO + +[ACS_DOCS.choosing_a_deployment_architecture] +file_filter = /choosing_a_deployment_architecture.po +source_file = pot/choosing_a_deployment_architecture.pot +source_lang = en +type = PO + +[ACS_DOCS.citrix-xenserver-installation] +file_filter = /citrix-xenserver-installation.po +source_file = pot/citrix-xenserver-installation.pot +source_lang = en +type = PO + +[ACS_DOCS.cloud-infrastructure-concepts] +file_filter = /cloud-infrastructure-concepts.po +source_file = pot/cloud-infrastructure-concepts.pot +source_lang = en +type = PO + +[ACS_DOCS.cloud-infrastructure-overview] +file_filter = /cloud-infrastructure-overview.po +source_file = pot/cloud-infrastructure-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudplatform-api] +file_filter = /cloudplatform-api.po +source_file = pot/cloudplatform-api.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudstack_admin] +file_filter = /cloudstack_admin.po +source_file = pot/cloudstack_admin.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudstack_developers] +file_filter = /cloudstack_developers.po +source_file = pot/cloudstack_developers.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudstack_features] +file_filter = /cloudstack_features.po +source_file = pot/cloudstack_features.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudstack_installation] +file_filter = /cloudstack_installation.po +source_file = pot/cloudstack_installation.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudstack] +file_filter = /cloudstack.po +source_file = pot/cloudstack.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudstack_system_requirements] +file_filter = /cloudstack_system_requirements.po +source_file = pot/cloudstack_system_requirements.pot +source_lang = en +type = PO + +[ACS_DOCS.cloudstack_whatis] +file_filter = /cloudstack_whatis.po +source_file = pot/cloudstack_whatis.pot +source_lang = en +type = PO + +[ACS_DOCS.cluster-add] +file_filter = /cluster-add.po +source_file = pot/cluster-add.pot +source_lang = en +type = PO + +[ACS_DOCS.compatibility-matrix] +file_filter = /compatibility-matrix.po +source_file = pot/compatibility-matrix.pot +source_lang = en +type = PO + +[ACS_DOCS.compute-disk-service-offerings] +file_filter = /compute-disk-service-offerings.po +source_file = pot/compute-disk-service-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.concepts] +file_filter = /concepts.po +source_file = pot/concepts.pot +source_lang = en +type = PO + +[ACS_DOCS.configure-guest-traffic-in-advanced-zone] +file_filter = /configure-guest-traffic-in-advanced-zone.po +source_file = pot/configure-guest-traffic-in-advanced-zone.pot +source_lang = en +type = PO + +[ACS_DOCS.configure-public-traffic-in-an-advanced-zone] +file_filter = /configure-public-traffic-in-an-advanced-zone.po +source_file = pot/configure-public-traffic-in-an-advanced-zone.pot +source_lang = en +type = PO + +[ACS_DOCS.configure-usage-server] +file_filter = /configure-usage-server.po +source_file = pot/configure-usage-server.pot +source_lang = en +type = PO + +[ACS_DOCS.configure-virtual-router] +file_filter = /configure-virtual-router.po +source_file = pot/configure-virtual-router.pot +source_lang = en +type = PO + +[ACS_DOCS.configure-vpn] +file_filter = /configure-vpn.po +source_file = pot/configure-vpn.pot +source_lang = en +type = PO + +[ACS_DOCS.configure-xenserver-dom0-memory] +file_filter = /configure-xenserver-dom0-memory.po +source_file = pot/configure-xenserver-dom0-memory.pot +source_lang = en +type = PO + +[ACS_DOCS.configure-xenserver-dom-memory] +file_filter = /configure-xenserver-dom-memory.po +source_file = pot/configure-xenserver-dom-memory.pot +source_lang = en +type = PO + +[ACS_DOCS.configuring-projects] +file_filter = /configuring-projects.po +source_file = pot/configuring-projects.pot +source_lang = en +type = PO + +[ACS_DOCS.console-proxy] +file_filter = /console-proxy.po +source_file = pot/console-proxy.pot +source_lang = en +type = PO + +[ACS_DOCS.convert-hyperv-vm-to-template] +file_filter = /convert-hyperv-vm-to-template.po +source_file = pot/convert-hyperv-vm-to-template.pot +source_lang = en +type = PO + +[ACS_DOCS.create-bare-metal-template] +file_filter = /create-bare-metal-template.po +source_file = pot/create-bare-metal-template.pot +source_lang = en +type = PO + +[ACS_DOCS.create-new-projects] +file_filter = /create-new-projects.po +source_file = pot/create-new-projects.pot +source_lang = en +type = PO + +[ACS_DOCS.create-template-from-existing-vm] +file_filter = /create-template-from-existing-vm.po +source_file = pot/create-template-from-existing-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.create-template-from-snapshot] +file_filter = /create-template-from-snapshot.po +source_file = pot/create-template-from-snapshot.pot +source_lang = en +type = PO + +[ACS_DOCS.create-templates-overview] +file_filter = /create-templates-overview.po +source_file = pot/create-templates-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.create-vpn-connection-vpc] +file_filter = /create-vpn-connection-vpc.po +source_file = pot/create-vpn-connection-vpc.pot +source_lang = en +type = PO + +[ACS_DOCS.create-vpn-customer-gateway] +file_filter = /create-vpn-customer-gateway.po +source_file = pot/create-vpn-customer-gateway.pot +source_lang = en +type = PO + +[ACS_DOCS.create-vpn-gateway-for-vpc] +file_filter = /create-vpn-gateway-for-vpc.po +source_file = pot/create-vpn-gateway-for-vpc.pot +source_lang = en +type = PO + +[ACS_DOCS.create-windows-template] +file_filter = /create-windows-template.po +source_file = pot/create-windows-template.pot +source_lang = en +type = PO + +[ACS_DOCS.creating-compute-offerings] +file_filter = /creating-compute-offerings.po +source_file = pot/creating-compute-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.creating-disk-offerings] +file_filter = /creating-disk-offerings.po +source_file = pot/creating-disk-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.creating-network-offerings] +file_filter = /creating-network-offerings.po +source_file = pot/creating-network-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.creating-new-volumes] +file_filter = /creating-new-volumes.po +source_file = pot/creating-new-volumes.pot +source_lang = en +type = PO + +[ACS_DOCS.creating-system-service-offerings] +file_filter = /creating-system-service-offerings.po +source_file = pot/creating-system-service-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.creating-vms] +file_filter = /creating-vms.po +source_file = pot/creating-vms.pot +source_lang = en +type = PO + +[ACS_DOCS.customizing-dns] +file_filter = /customizing-dns.po +source_file = pot/customizing-dns.pot +source_lang = en +type = PO + +[ACS_DOCS.dates-in-usage-record] +file_filter = /dates-in-usage-record.po +source_file = pot/dates-in-usage-record.pot +source_lang = en +type = PO + +[ACS_DOCS.dedicated-ha-hosts] +file_filter = /dedicated-ha-hosts.po +source_file = pot/dedicated-ha-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.default-account-resource-limit] +file_filter = /default-account-resource-limit.po +source_file = pot/default-account-resource-limit.pot +source_lang = en +type = PO + +[ACS_DOCS.default-template] +file_filter = /default-template.po +source_file = pot/default-template.pot +source_lang = en +type = PO + +[ACS_DOCS.delete-templates] +file_filter = /delete-templates.po +source_file = pot/delete-templates.pot +source_lang = en +type = PO + +[ACS_DOCS.deleting-vms] +file_filter = /deleting-vms.po +source_file = pot/deleting-vms.pot +source_lang = en +type = PO + +[ACS_DOCS.deployment-architecture-overview] +file_filter = /deployment-architecture-overview.po +source_file = pot/deployment-architecture-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.detach-move-volumes] +file_filter = /detach-move-volumes.po +source_file = pot/detach-move-volumes.pot +source_lang = en +type = PO + +[ACS_DOCS.developer-getting-started] +file_filter = /developer-getting-started.po +source_file = pot/developer-getting-started.pot +source_lang = en +type = PO + +[ACS_DOCS.developer_guide] +file_filter = /developer_guide.po +source_file = pot/developer_guide.pot +source_lang = en +type = PO + +[ACS_DOCS.developer-guide] +file_filter = /developer-guide.po +source_file = pot/developer-guide.pot +source_lang = en +type = PO + +[ACS_DOCS.developer-introduction] +file_filter = /developer-introduction.po +source_file = pot/developer-introduction.pot +source_lang = en +type = PO + +[ACS_DOCS.disable-enable-zones-pods-clusters] +file_filter = /disable-enable-zones-pods-clusters.po +source_file = pot/disable-enable-zones-pods-clusters.pot +source_lang = en +type = PO + +[ACS_DOCS.disk-volume-usage-record-format] +file_filter = /disk-volume-usage-record-format.po +source_file = pot/disk-volume-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.dns-dhcp] +file_filter = /dns-dhcp.po +source_file = pot/dns-dhcp.pot +source_lang = en +type = PO + +[ACS_DOCS.domains] +file_filter = /domains.po +source_file = pot/domains.pot +source_lang = en +type = PO + +[ACS_DOCS.enable-disable-static-nat] +file_filter = /enable-disable-static-nat.po +source_file = pot/enable-disable-static-nat.pot +source_lang = en +type = PO + +[ACS_DOCS.enable-security-groups] +file_filter = /enable-security-groups.po +source_file = pot/enable-security-groups.pot +source_lang = en +type = PO + +[ACS_DOCS.enabling-api-call-expiration] +file_filter = /enabling-api-call-expiration.po +source_file = pot/enabling-api-call-expiration.pot +source_lang = en +type = PO + +[ACS_DOCS.enabling-port-8096] +file_filter = /enabling-port-8096.po +source_file = pot/enabling-port-8096.pot +source_lang = en +type = PO + +[ACS_DOCS.end-user-ui-overview] +file_filter = /end-user-ui-overview.po +source_file = pot/end-user-ui-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.error-handling] +file_filter = /error-handling.po +source_file = pot/error-handling.pot +source_lang = en +type = PO + +[ACS_DOCS.event-log-queries] +file_filter = /event-log-queries.po +source_file = pot/event-log-queries.pot +source_lang = en +type = PO + +[ACS_DOCS.events-log] +file_filter = /events-log.po +source_file = pot/events-log.pot +source_lang = en +type = PO + +[ACS_DOCS.events] +file_filter = /events.po +source_file = pot/events.pot +source_lang = en +type = PO + +[ACS_DOCS.event-types] +file_filter = /event-types.po +source_file = pot/event-types.pot +source_lang = en +type = PO + +[ACS_DOCS.example-LDAP-configuration-commands] +file_filter = /example-LDAP-configuration-commands.po +source_file = pot/example-LDAP-configuration-commands.pot +source_lang = en +type = PO + +[ACS_DOCS.example-response-from-listUsageRecords] +file_filter = /example-response-from-listUsageRecords.po +source_file = pot/example-response-from-listUsageRecords.pot +source_lang = en +type = PO + +[ACS_DOCS.export-template] +file_filter = /export-template.po +source_file = pot/export-template.pot +source_lang = en +type = PO + +[ACS_DOCS.external-firewalls-and-load-balancers] +file_filter = /external-firewalls-and-load-balancers.po +source_file = pot/external-firewalls-and-load-balancers.pot +source_lang = en +type = PO + +[ACS_DOCS.feature-overview] +file_filter = /feature-overview.po +source_file = pot/feature-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.firewall-rules] +file_filter = /firewall-rules.po +source_file = pot/firewall-rules.pot +source_lang = en +type = PO + +[ACS_DOCS.first_ms_node_install] +file_filter = /first_ms_node_install.po +source_file = pot/first_ms_node_install.pot +source_lang = en +type = PO + +[ACS_DOCS.globally-configured-limit] +file_filter = /globally-configured-limit.po +source_file = pot/globally-configured-limit.pot +source_lang = en +type = PO + +[ACS_DOCS.globally-configured-limits] +file_filter = /globally-configured-limits.po +source_file = pot/globally-configured-limits.pot +source_lang = en +type = PO + +[ACS_DOCS.guest-ip-ranges] +file_filter = /guest-ip-ranges.po +source_file = pot/guest-ip-ranges.pot +source_lang = en +type = PO + +[ACS_DOCS.guest-network] +file_filter = /guest-network.po +source_file = pot/guest-network.pot +source_lang = en +type = PO + +[ACS_DOCS.guest-traffic] +file_filter = /guest-traffic.po +source_file = pot/guest-traffic.pot +source_lang = en +type = PO + +[ACS_DOCS.ha-enabled-vm] +file_filter = /ha-enabled-vm.po +source_file = pot/ha-enabled-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.ha-for-hosts] +file_filter = /ha-for-hosts.po +source_file = pot/ha-for-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.ha-management-server] +file_filter = /ha-management-server.po +source_file = pot/ha-management-server.pot +source_lang = en +type = PO + +[ACS_DOCS.host-add] +file_filter = /host-add.po +source_file = pot/host-add.pot +source_lang = en +type = PO + +[ACS_DOCS.host-allocation] +file_filter = /host-allocation.po +source_file = pot/host-allocation.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-agent] +file_filter = /hypervisor-host-install-agent.po +source_file = pot/hypervisor-host-install-agent.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-firewall] +file_filter = /hypervisor-host-install-firewall.po +source_file = pot/hypervisor-host-install-firewall.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-flow] +file_filter = /hypervisor-host-install-flow.po +source_file = pot/hypervisor-host-install-flow.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-libvirt] +file_filter = /hypervisor-host-install-libvirt.po +source_file = pot/hypervisor-host-install-libvirt.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-network] +file_filter = /hypervisor-host-install-network.po +source_file = pot/hypervisor-host-install-network.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-overview] +file_filter = /hypervisor-host-install-overview.po +source_file = pot/hypervisor-host-install-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-prepare-os] +file_filter = /hypervisor-host-install-prepare-os.po +source_file = pot/hypervisor-host-install-prepare-os.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-host-install-security-policies] +file_filter = /hypervisor-host-install-security-policies.po +source_file = pot/hypervisor-host-install-security-policies.pot +source_lang = en +type = PO + +[ACS_DOCS.hypervisor-support-for-primarystorage] +file_filter = /hypervisor-support-for-primarystorage.po +source_file = pot/hypervisor-support-for-primarystorage.pot +source_lang = en +type = PO + +[ACS_DOCS.import-ami] +file_filter = /import-ami.po +source_file = pot/import-ami.pot +source_lang = en +type = PO + +[ACS_DOCS.increase-management-server-max-memory] +file_filter = /increase-management-server-max-memory.po +source_file = pot/increase-management-server-max-memory.pot +source_lang = en +type = PO + +[ACS_DOCS.incremental-snapshots-backup] +file_filter = /incremental-snapshots-backup.po +source_file = pot/incremental-snapshots-backup.pot +source_lang = en +type = PO + +[ACS_DOCS.initialize-and-test] +file_filter = /initialize-and-test.po +source_file = pot/initialize-and-test.pot +source_lang = en +type = PO + +[ACS_DOCS.initial-setup-of-external-firewalls-loadbalancers] +file_filter = /initial-setup-of-external-firewalls-loadbalancers.po +source_file = pot/initial-setup-of-external-firewalls-loadbalancers.pot +source_lang = en +type = PO + +[ACS_DOCS.installation-complete] +file_filter = /installation-complete.po +source_file = pot/installation-complete.pot +source_lang = en +type = PO + +[ACS_DOCS.installation_overview] +file_filter = /installation_overview.po +source_file = pot/installation_overview.pot +source_lang = en +type = PO + +[ACS_DOCS.installation] +file_filter = /installation.po +source_file = pot/installation.pot +source_lang = en +type = PO + +[ACS_DOCS.installation_steps_overview] +file_filter = /installation_steps_overview.po +source_file = pot/installation_steps_overview.pot +source_lang = en +type = PO + +[ACS_DOCS.installation-steps-overview] +file_filter = /installation-steps-overview.po +source_file = pot/installation-steps-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.introduction] +file_filter = /introduction.po +source_file = pot/introduction.pot +source_lang = en +type = PO + +[ACS_DOCS.ipaddress-usage-record-format] +file_filter = /ipaddress-usage-record-format.po +source_file = pot/ipaddress-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.ip-forwarding-firewalling] +file_filter = /ip-forwarding-firewalling.po +source_file = pot/ip-forwarding-firewalling.pot +source_lang = en +type = PO + +[ACS_DOCS.ip-load-balancing] +file_filter = /ip-load-balancing.po +source_file = pot/ip-load-balancing.pot +source_lang = en +type = PO + +[ACS_DOCS.isolated-networks] +file_filter = /isolated-networks.po +source_file = pot/isolated-networks.pot +source_lang = en +type = PO + +[ACS_DOCS.job-status] +file_filter = /job-status.po +source_file = pot/job-status.pot +source_lang = en +type = PO + +[ACS_DOCS.large_scale_redundant_setup] +file_filter = /large_scale_redundant_setup.po +source_file = pot/large_scale_redundant_setup.pot +source_lang = en +type = PO + +[ACS_DOCS.LDAPserver-for-user-authentication] +file_filter = /LDAPserver-for-user-authentication.po +source_file = pot/LDAPserver-for-user-authentication.pot +source_lang = en +type = PO + +[ACS_DOCS.linux-installation] +file_filter = /linux-installation.po +source_file = pot/linux-installation.pot +source_lang = en +type = PO + +[ACS_DOCS.loadbal-policy-port-fwd-rule-usage-record-fmt] +file_filter = /loadbalancer-policy-port-forwarding-rule-usage-record-format.po +source_file = pot/loadbalancer-policy-port-forwarding-rule-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.load-balancer-rules] +file_filter = /load-balancer-rules.po +source_file = pot/load-balancer-rules.pot +source_lang = en +type = PO + +[ACS_DOCS.log-in] +file_filter = /log-in.po +source_file = pot/log-in.pot +source_lang = en +type = PO + +[ACS_DOCS.log-in-root-admin] +file_filter = /log-in-root-admin.po +source_file = pot/log-in-root-admin.pot +source_lang = en +type = PO + +[ACS_DOCS.long-running-job-events] +file_filter = /long-running-job-events.po +source_file = pot/long-running-job-events.pot +source_lang = en +type = PO + +[ACS_DOCS.maintain-hypervisors-on-hosts] +file_filter = /maintain-hypervisors-on-hosts.po +source_file = pot/maintain-hypervisors-on-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.maintenance-mode-for-primary-storage] +file_filter = /maintenance-mode-for-primary-storage.po +source_file = pot/maintenance-mode-for-primary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.making-api-request] +file_filter = /making-api-request.po +source_file = pot/making-api-request.pot +source_lang = en +type = PO + +[ACS_DOCS.manage-cloud] +file_filter = /manage-cloud.po +source_file = pot/manage-cloud.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-client] +file_filter = /management-server-install-client.po +source_file = pot/management-server-install-client.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-complete] +file_filter = /management-server-install-complete.po +source_file = pot/management-server-install-complete.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-db] +file_filter = /management-server-install-db.po +source_file = pot/management-server-install-db.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-db-external] +file_filter = /management-server-install-db-external.po +source_file = pot/management-server-install-db-external.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-db-local] +file_filter = /management-server-install-db-local.po +source_file = pot/management-server-install-db-local.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-flow] +file_filter = /management-server-install-flow.po +source_file = pot/management-server-install-flow.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-multi-node] +file_filter = /management-server-install-multi-node.po +source_file = pot/management-server-install-multi-node.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-nfs-shares] +file_filter = /management-server-install-nfs-shares.po +source_file = pot/management-server-install-nfs-shares.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-overview] +file_filter = /management-server-install-overview.po +source_file = pot/management-server-install-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-prepare-os] +file_filter = /management-server-install-prepare-os.po +source_file = pot/management-server-install-prepare-os.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-install-systemvm] +file_filter = /management-server-install-systemvm.po +source_file = pot/management-server-install-systemvm.pot +source_lang = en +type = PO + +[ACS_DOCS.management-server-overview] +file_filter = /management-server-overview.po +source_file = pot/management-server-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.manual-live-migration] +file_filter = /manual-live-migration.po +source_file = pot/manual-live-migration.pot +source_lang = en +type = PO + +[ACS_DOCS.max-result-page-returned] +file_filter = /max-result-page-returned.po +source_file = pot/max-result-page-returned.pot +source_lang = en +type = PO + +[ACS_DOCS.migrate-datadisk-volume-new-storage-pool] +file_filter = /migrate-datadisk-volume-new-storage-pool.po +source_file = pot/migrate-datadisk-volume-new-storage-pool.pot +source_lang = en +type = PO + +[ACS_DOCS.migrate-vm-rootvolume-volume-new-storage-pool] +file_filter = /migrate-vm-rootvolume-volume-new-storage-pool.po +source_file = pot/migrate-vm-rootvolume-volume-new-storage-pool.pot +source_lang = en +type = PO + +[ACS_DOCS.minimum-system-requirements] +file_filter = /minimum-system-requirements.po +source_file = pot/minimum-system-requirements.pot +source_lang = en +type = PO + +[ACS_DOCS.modify-delete-service-offerings] +file_filter = /modify-delete-service-offerings.po +source_file = pot/modify-delete-service-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.multi_node_management_server] +file_filter = /multi_node_management_server.po +source_file = pot/multi_node_management_server.pot +source_lang = en +type = PO + +[ACS_DOCS.multi_node_overview] +file_filter = /multi_node_overview.po +source_file = pot/multi_node_overview.pot +source_lang = en +type = PO + +[ACS_DOCS.multiple-system-vm-vmware] +file_filter = /multiple-system-vm-vmware.po +source_file = pot/multiple-system-vm-vmware.pot +source_lang = en +type = PO + +[ACS_DOCS.multi_site_deployment] +file_filter = /multi_site_deployment.po +source_file = pot/multi_site_deployment.pot +source_lang = en +type = PO + +[ACS_DOCS.networking-in-a-pod] +file_filter = /networking-in-a-pod.po +source_file = pot/networking-in-a-pod.pot +source_lang = en +type = PO + +[ACS_DOCS.networking-in-a-zone] +file_filter = /networking-in-a-zone.po +source_file = pot/networking-in-a-zone.pot +source_lang = en +type = PO + +[ACS_DOCS.networking_overview] +file_filter = /networking_overview.po +source_file = pot/networking-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.networking-overview] +file_filter = /networking-overview.po +source_file = pot/networking-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.network-offerings] +file_filter = /network-offerings.po +source_file = pot/network-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.network-offering-usage-record-format] +file_filter = /network-offering-usage-record-format.po +source_file = pot/network-offering-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.network-service-providers] +file_filter = /network-service-providers.po +source_file = pot/network-service-providers.pot +source_lang = en +type = PO + +[ACS_DOCS.network-usage-record-format] +file_filter = /network-usage-record-format.po +source_file = pot/network-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.nfs-shares-on-management-server] +file_filter = /nfs-shares-on-management-server.po +source_file = pot/nfs-shares-on-management-server.pot +source_lang = en +type = PO + +[ACS_DOCS.nfs-shares-on-separate-server] +file_filter = /nfs-shares-on-separate-server.po +source_file = pot/nfs-shares-on-separate-server.pot +source_lang = en +type = PO + +[ACS_DOCS.ongoing-config-of-external-firewall-loadbalancer] +file_filter = /ongoing-configuration-of-external-firewalls-loadbalancer.po +source_file = pot/ongoing-configuration-of-external-firewalls-loadbalancer.pot +source_lang = en +type = PO + +[ACS_DOCS.over-provisioning-service-offering-limits] +file_filter = /over-provisioning-service-offering-limits.po +source_file = pot/over-provisioning-service-offering-limits.pot +source_lang = en +type = PO + +[ACS_DOCS.per-domain-limits] +file_filter = /per-domain-limits.po +source_file = pot/per-domain-limits.pot +source_lang = en +type = PO + +[ACS_DOCS.performance-monitoring] +file_filter = /performance-monitoring.po +source_file = pot/performance-monitoring.pot +source_lang = en +type = PO + +[ACS_DOCS.physical-network-configuration-settings] +file_filter = /physical-network-configuration-settings.po +source_file = pot/physical-network-configuration-settings.pot +source_lang = en +type = PO + +[ACS_DOCS.pod-add] +file_filter = /pod-add.po +source_file = pot/pod-add.pot +source_lang = en +type = PO + +[ACS_DOCS.port-forwarding] +file_filter = /port-forwarding.po +source_file = pot/port-forwarding.pot +source_lang = en +type = PO + +[ACS_DOCS.Preface] +file_filter = /Preface.po +source_file = pot/Preface.pot +source_lang = en +type = PO + +[ACS_DOCS.prepare_os] +file_filter = /prepare_os.po +source_file = pot/prepare_os.pot +source_lang = en +type = PO + +[ACS_DOCS.prepare-system-vm-template] +file_filter = /prepare-system-vm-template.po +source_file = pot/prepare-system-vm-template.pot +source_lang = en +type = PO + +[ACS_DOCS.primary-storage-add] +file_filter = /primary-storage-add.po +source_file = pot/primary-storage-add.pot +source_lang = en +type = PO + +[ACS_DOCS.primary-storage-outage-and-data-loss] +file_filter = /primary-storage-outage-and-data-loss.po +source_file = pot/primary-storage-outage-and-data-loss.pot +source_lang = en +type = PO + +[ACS_DOCS.primary-storage] +file_filter = /primary-storage.po +source_file = pot/primary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.private-public-template] +file_filter = /private-public-template.po +source_file = pot/private-public-template.pot +source_lang = en +type = PO + +[ACS_DOCS.projects] +file_filter = /projects.po +source_file = pot/projects.pot +source_lang = en +type = PO + +[ACS_DOCS.provisioning-auth-api] +file_filter = /provisioning-auth-api.po +source_file = pot/provisioning-auth-api.pot +source_lang = en +type = PO + +[ACS_DOCS.provisioning] +file_filter = /provisioning.po +source_file = pot/provisioning.pot +source_lang = en +type = PO + +[ACS_DOCS.provisioning-steps-overview] +file_filter = /provisioning-steps-overview.po +source_file = pot/provisioning-steps-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.provisioning-steps] +file_filter = /provisioning-steps.po +source_file = pot/provisioning-steps.pot +source_lang = en +type = PO + +[ACS_DOCS.query-filter] +file_filter = /query-filter.po +source_file = pot/query-filter.pot +source_lang = en +type = PO + +[ACS_DOCS.release-ip-address] +file_filter = /release-ip-address.po +source_file = pot/release-ip-address.pot +source_lang = en +type = PO + +[ACS_DOCS.removed-API-commands] +file_filter = /removed-API-commands.po +source_file = pot/removed-API-commands.pot +source_lang = en +type = PO + +[ACS_DOCS.remove-member-from-project] +file_filter = /remove-member-from-project.po +source_file = pot/remove-member-from-project.pot +source_lang = en +type = PO + +[ACS_DOCS.removing-vsphere-hosts] +file_filter = /removing-vsphere-hosts.po +source_file = pot/removing-vsphere-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.removing-xenserver-kvm-hosts] +file_filter = /removing-xenserver-kvm-hosts.po +source_file = pot/removing-xenserver-kvm-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.requirements-templates] +file_filter = /requirements-templates.po +source_file = pot/requirements-templates.pot +source_lang = en +type = PO + +[ACS_DOCS.resizing-volumes] +file_filter = /resizing-volumes.po +source_file = pot/resizing-volumes.pot +source_lang = en +type = PO + +[ACS_DOCS.response-formats] +file_filter = /response-formats.po +source_file = pot/response-formats.pot +source_lang = en +type = PO + +[ACS_DOCS.responses] +file_filter = /responses.po +source_file = pot/responses.pot +source_lang = en +type = PO + +[ACS_DOCS.Revision_History] +file_filter = /Revision_History.po +source_file = pot/Revision_History.pot +source_lang = en +type = PO + +[ACS_DOCS.roles] +file_filter = /roles.po +source_file = pot/roles.pot +source_lang = en +type = PO + +[ACS_DOCS.root-admin-ui-overview] +file_filter = /root-admin-ui-overview.po +source_file = pot/root-admin-ui-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.runtime-allocation-virtual-network-resources] +file_filter = /runtime-allocation-virtual-network-resources.po +source_file = pot/runtime-allocation-virtual-network-resources.pot +source_lang = en +type = PO + +[ACS_DOCS.runtime-behavior-of-primary-storage] +file_filter = /runtime-behavior-of-primary-storage.po +source_file = pot/runtime-behavior-of-primary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.scheduled-maintenance-maintenance-mode-hosts] +file_filter = /scheduled-maintenance-maintenance-mode-hosts.po +source_file = pot/scheduled-maintenance-maintenance-mode-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.search-base] +file_filter = /search-base.po +source_file = pot/search-base.pot +source_lang = en +type = PO + +[ACS_DOCS.search-user-bind-dn] +file_filter = /search-user-bind-dn.po +source_file = pot/search-user-bind-dn.pot +source_lang = en +type = PO + +[ACS_DOCS.secondary-storage-add] +file_filter = /secondary-storage-add.po +source_file = pot/secondary-storage-add.pot +source_lang = en +type = PO + +[ACS_DOCS.secondary-storage-outage-and-data-loss] +file_filter = /secondary-storage-outage-and-data-loss.po +source_file = pot/secondary-storage-outage-and-data-loss.pot +source_lang = en +type = PO + +[ACS_DOCS.secondary-storage] +file_filter = /secondary-storage.po +source_file = pot/secondary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.secondary-storage-vm] +file_filter = /secondary-storage-vm.po +source_file = pot/secondary-storage-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.security-groups] +file_filter = /security-groups.po +source_file = pot/security-groups.pot +source_lang = en +type = PO + +[ACS_DOCS.send-projects-membership-invitation] +file_filter = /send-projects-membership-invitation.po +source_file = pot/send-projects-membership-invitation.pot +source_lang = en +type = PO + +[ACS_DOCS.separate_storage_network] +file_filter = /separate_storage_network.po +source_file = pot/separate_storage_network.pot +source_lang = en +type = PO + +[ACS_DOCS.service-offerings] +file_filter = /service-offerings.po +source_file = pot/service-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.set-database-buffer-pool-size] +file_filter = /set-database-buffer-pool-size.po +source_file = pot/set-database-buffer-pool-size.pot +source_lang = en +type = PO + +[ACS_DOCS.set-monitor-total-vm-limits-per-host] +file_filter = /set-monitor-total-vm-limits-per-host.po +source_file = pot/set-monitor-total-vm-limits-per-host.pot +source_lang = en +type = PO + +[ACS_DOCS.set-projects-creator-permissions] +file_filter = /set-projects-creator-permissions.po +source_file = pot/set-projects-creator-permissions.pot +source_lang = en +type = PO + +[ACS_DOCS.set-resource-limits-for-projects] +file_filter = /set-resource-limits-for-projects.po +source_file = pot/set-resource-limits-for-projects.pot +source_lang = en +type = PO + +[ACS_DOCS.set-up-invitations] +file_filter = /set-up-invitations.po +source_file = pot/set-up-invitations.pot +source_lang = en +type = PO + +[ACS_DOCS.set-up-network-for-users] +file_filter = /set-up-network-for-users.po +source_file = pot/set-up-network-for-users.pot +source_lang = en +type = PO + +[ACS_DOCS.set-usage-limit] +file_filter = /set-usage-limit.po +source_file = pot/set-usage-limit.pot +source_lang = en +type = PO + +[ACS_DOCS.shared-networks] +file_filter = /shared-networks.po +source_file = pot/shared-networks.pot +source_lang = en +type = PO + +[ACS_DOCS.signing-api-requests] +file_filter = /signing-api-requests.po +source_file = pot/signing-api-requests.pot +source_lang = en +type = PO + +[ACS_DOCS.site-to-site-vpn] +file_filter = /site-to-site-vpn.po +source_file = pot/site-to-site-vpn.pot +source_lang = en +type = PO + +[ACS_DOCS.small_scale_deployment] +file_filter = /small_scale_deployment.po +source_file = pot/small_scale_deployment.pot +source_lang = en +type = PO + +[ACS_DOCS.snapshot-restore] +file_filter = /snapshot-restore.po +source_file = pot/snapshot-restore.pot +source_lang = en +type = PO + +[ACS_DOCS.SSL-keystore-path-and-password] +file_filter = /SSL-keystore-path-and-password.po +source_file = pot/SSL-keystore-path-and-password.pot +source_lang = en +type = PO + +[ACS_DOCS.standard-events] +file_filter = /standard-events.po +source_file = pot/standard-events.pot +source_lang = en +type = PO + +[ACS_DOCS.static-nat] +file_filter = /static-nat.po +source_file = pot/static-nat.pot +source_lang = en +type = PO + +[ACS_DOCS.sticky-session-policies-for-lb-rules] +file_filter = /sticky-session-policies-for-lb-rules.po +source_file = pot/sticky-session-policies-for-lb-rules.pot +source_lang = en +type = PO + +[ACS_DOCS.stopped-vm] +file_filter = /stopped-vm.po +source_file = pot/stopped-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.stopping-and-starting-vms] +file_filter = /stopping-and-starting-vms.po +source_file = pot/stopping-and-starting-vms.pot +source_lang = en +type = PO + +[ACS_DOCS.stop-restart-management-server] +file_filter = /stop-restart-management-server.po +source_file = pot/stop-restart-management-server.pot +source_lang = en +type = PO + +[ACS_DOCS.storage] +file_filter = /storage.po +source_file = pot/storage.pot +source_lang = en +type = PO + +[ACS_DOCS.storage-tags] +file_filter = /storage-tags.po +source_file = pot/storage-tags.pot +source_lang = en +type = PO + +[ACS_DOCS.suspend-project] +file_filter = /suspend-project.po +source_file = pot/suspend-project.pot +source_lang = en +type = PO + +[ACS_DOCS.sysprep-for-windows-server-2003R2] +file_filter = /sysprep-for-windows-server-2003R2.po +source_file = pot/sysprep-for-windows-server-2003R2.pot +source_lang = en +type = PO + +[ACS_DOCS.sysprep-windows-server-2008R2] +file_filter = /sysprep-windows-server-2008R2.po +source_file = pot/sysprep-windows-server-2008R2.pot +source_lang = en +type = PO + +[ACS_DOCS.sys-reliability-and-ha] +file_filter = /sys-reliability-and-ha.po +source_file = pot/sys-reliability-and-ha.pot +source_lang = en +type = PO + +[ACS_DOCS.system-reserved-ip-addresses] +file_filter = /system-reserved-ip-addresses.po +source_file = pot/system-reserved-ip-addresses.pot +source_lang = en +type = PO + +[ACS_DOCS.system-service-offerings] +file_filter = /system-service-offerings.po +source_file = pot/system-service-offerings.pot +source_lang = en +type = PO + +[ACS_DOCS.system-vm-template] +file_filter = /system-vm-template.po +source_file = pot/system-vm-template.pot +source_lang = en +type = PO + +[ACS_DOCS.template-iso-snapshot-usage-record-format] +file_filter = /template-iso-snapshot-usage-record-format.po +source_file = pot/template-iso-snapshot-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.templates] +file_filter = /templates.po +source_file = pot/templates.pot +source_lang = en +type = PO + +[ACS_DOCS.time-zones] +file_filter = /time-zones.po +source_file = pot/time-zones.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshooting-alerts] +file_filter = /troubleshooting-alerts.po +source_file = pot/troubleshooting-alerts.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshoot-dataloss-on-exported-primary-storage] +file_filter = /troubleshooting-dataloss-on-exported-primary-storage.po +source_file = pot/troubleshooting-dataloss-on-exported-primary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshooting-lb-rules-fails] +file_filter = /troubleshooting-lb-rules-fails.po +source_file = pot/troubleshooting-lb-rules-fails.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshoot-maint-mode-not-working-on-vCenter] +file_filter = /troubleshooting-maintenance-mode-not-working-on-vCenter.po +source_file = pot/troubleshooting-maintenance-mode-not-working-on-vCenter.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshooting] +file_filter = /troubleshooting.po +source_file = pot/troubleshooting.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshooting-recover-lost-virtual-router] +file_filter = /troubleshooting-recover-lost-virtual-router.po +source_file = pot/troubleshooting-recover-lost-virtual-router.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshooting-unable-to-deploy-vms] +file_filter = /troubleshooting-unable-to-deploy-vms.po +source_file = pot/troubleshooting-unable-to-deploy-vms.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshooting-unable-to-power-on-vm] +file_filter = /troubleshooting-unable-to-power-on-vm.po +source_file = pot/troubleshooting-unable-to-power-on-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.troubleshooting-working-with-server-logs] +file_filter = /troubleshooting-working-with-server-logs.po +source_file = pot/troubleshooting-working-with-server-logs.pot +source_lang = en +type = PO + +[ACS_DOCS.tuning] +file_filter = /tuning.po +source_file = pot/tuning.pot +source_lang = en +type = PO + +[ACS_DOCS.ui] +file_filter = /ui.po +source_file = pot/ui.pot +source_lang = en +type = PO + +[ACS_DOCS.upgrade-virtual-router-with-service-offering] +file_filter = /upgrade-virtual-router-with-service-offering.po +source_file = pot/upgrade-virtual-router-with-service-offering.pot +source_lang = en +type = PO + +[ACS_DOCS.upload-existing-volume-to-vm] +file_filter = /upload-existing-volume-to-vm.po +source_file = pot/upload-existing-volume-to-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.upload-template] +file_filter = /upload-template.po +source_file = pot/upload-template.pot +source_lang = en +type = PO + +[ACS_DOCS.usage-record-format] +file_filter = /usage-record-format.po +source_file = pot/usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.usage-types] +file_filter = /usage-types.po +source_file = pot/usage-types.pot +source_lang = en +type = PO + +[ACS_DOCS.use-project-view] +file_filter = /use-project-view.po +source_file = pot/use-project-view.pot +source_lang = en +type = PO + +[ACS_DOCS.user-data-and-meta-data] +file_filter = /user-data-and-meta-data.po +source_file = pot/user-data-and-meta-data.pot +source_lang = en +type = PO + +[ACS_DOCS.user-services-overview] +file_filter = /user-services-overview.po +source_file = pot/user-services-overview.pot +source_lang = en +type = PO + +[ACS_DOCS.using-multiple-guest-networks] +file_filter = /using-multiple-guest-networks.po +source_file = pot/using-multiple-guest-networks.pot +source_lang = en +type = PO + +[ACS_DOCS.using-netscaler-load-balancers] +file_filter = /using-netscaler-load-balancers.po +source_file = pot/using-netscaler-load-balancers.pot +source_lang = en +type = PO + +[ACS_DOCS.using-sshkeys] +file_filter = /using-sshkeys.po +source_file = pot/using-sshkeys.pot +source_lang = en +type = PO + +[ACS_DOCS.using-swift-for-secondary-storage] +file_filter = /using-swift-for-secondary-storage.po +source_file = pot/using-swift-for-secondary-storage.pot +source_lang = en +type = PO + +[ACS_DOCS.using-vpn-with-mac] +file_filter = /using-vpn-with-mac.po +source_file = pot/using-vpn-with-mac.pot +source_lang = en +type = PO + +[ACS_DOCS.using-vpn-with-windows] +file_filter = /using-vpn-with-windows.po +source_file = pot/using-vpn-with-windows.pot +source_lang = en +type = PO + +[ACS_DOCS.vcenter-maintenance-mode] +file_filter = /vcenter-maintenance-mode.po +source_file = pot/vcenter-maintenance-mode.pot +source_lang = en +type = PO + +[ACS_DOCS.virtual-machine-usage-record-format] +file_filter = /virtual-machine-usage-record-format.po +source_file = pot/virtual-machine-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.virtual-router] +file_filter = /virtual-router.po +source_file = pot/virtual-router.pot +source_lang = en +type = PO + +[ACS_DOCS.vlan-provisioning] +file_filter = /vlan-provisioning.po +source_file = pot/vlan-provisioning.pot +source_lang = en +type = PO + +[ACS_DOCS.vm-lifecycle] +file_filter = /vm-lifecycle.po +source_file = pot/vm-lifecycle.pot +source_lang = en +type = PO + +[ACS_DOCS.vm-storage-migration] +file_filter = /vm-storage-migration.po +source_file = pot/vm-storage-migration.pot +source_lang = en +type = PO + +[ACS_DOCS.volume-deletion-garbage-collection] +file_filter = /volume-deletion-garbage-collection.po +source_file = pot/volume-deletion-garbage-collection.pot +source_lang = en +type = PO + +[ACS_DOCS.volume-status] +file_filter = /volume-status.po +source_file = pot/volume-status.pot +source_lang = en +type = PO + +[ACS_DOCS.vpc] +file_filter = /vpc.po +source_file = pot/vpc.pot +source_lang = en +type = PO + +[ACS_DOCS.vpn] +file_filter = /vpn.po +source_file = pot/vpn.pot +source_lang = en +type = PO + +[ACS_DOCS.VPN-user-usage-record-format] +file_filter = /VPN-user-usage-record-format.po +source_file = pot/VPN-user-usage-record-format.pot +source_lang = en +type = PO + +[ACS_DOCS.whatis] +file_filter = /whatis.po +source_file = pot/whatis.pot +source_lang = en +type = PO + +[ACS_DOCS.whats-in-this-adminguide] +file_filter = /whats-in-this-adminguide.po +source_file = pot/whats-in-this-adminguide.pot +source_lang = en +type = PO + +[ACS_DOCS.whats-new] +file_filter = /whats-new.po +source_file = pot/whats-new.pot +source_lang = en +type = PO + +[ACS_DOCS.who-should-read-installation] +file_filter = /who-should-read-installation.po +source_file = pot/who-should-read-installation.pot +source_lang = en +type = PO + +[ACS_DOCS.windows-installation] +file_filter = /windows-installation.po +source_file = pot/windows-installation.pot +source_lang = en +type = PO + +[ACS_DOCS.working-with-hosts] +file_filter = /working-with-hosts.po +source_file = pot/working-with-hosts.pot +source_lang = en +type = PO + +[ACS_DOCS.working-with-iso] +file_filter = /working-with-iso.po +source_file = pot/working-with-iso.pot +source_lang = en +type = PO + +[ACS_DOCS.working-with-snapshots] +file_filter = /working-with-snapshots.po +source_file = pot/working-with-snapshots.pot +source_lang = en +type = PO + +[ACS_DOCS.working-with-system-vm] +file_filter = /working-with-system-vm.po +source_file = pot/working-with-system-vm.pot +source_lang = en +type = PO + +[ACS_DOCS.working-with-templates] +file_filter = /working-with-templates.po +source_file = pot/working-with-templates.pot +source_lang = en +type = PO + +[ACS_DOCS.working-with-usage-data] +file_filter = /working-with-usage-data.po +source_file = pot/working-with-usage-data.pot +source_lang = en +type = PO + +[ACS_DOCS.working-with-volumes] +file_filter = /working-with-volumes.po +source_file = pot/working-with-volumes.pot +source_lang = en +type = PO + +[ACS_DOCS.work-with-usage] +file_filter = /work-with-usage.po +source_file = pot/work-with-usage.pot +source_lang = en +type = PO + +[ACS_DOCS.xenserver-maintenance-mode] +file_filter = /xenserver-maintenance-mode.po +source_file = pot/xenserver-maintenance-mode.pot +source_lang = en +type = PO + +[ACS_DOCS.zone-add] +file_filter = /zone-add.po +source_file = pot/zone-add.pot +source_lang = en +type = PO diff --git a/docs/README.txt b/docs/README.txt index 7fcfff8eb7d..7f096e4b117 100644 --- a/docs/README.txt +++ b/docs/README.txt @@ -57,10 +57,21 @@ Some of the XML files contain only a series of include tags to pull in content f The master book file contains ... tags. This file is referred to in the Publican configuration file, and is used as the controlling file when building the book. -As a naming convention, start the name of a book file with cloudstack_ ; for example, cloudstack_installation. +Document names are derived from the docname setting in the appropriate .cfg file. +This should not have CloudStack in the name (which is redundant because of +the CloudStack brand that the documentation is built with. The docname variable +sets the name in the doc site table of contents. This name also needs to exist +as .xml and .ent in the en-US directory. Examples of appropriate docnames: +Admin_Guide +API_Developers_Guide +Installation_Guide -A Publican book file must also have certain other tags that are expected by Publican when it builds the project. Copy an existing master book file to get these tags. + + +A Publican book file must also have certain other tags that are expected by +Publican when it builds the project. Copy an existing master book file to +get these tags. ---------------------------------- @@ -71,10 +82,15 @@ CONFIG FILES For each book file, there must be a corresponding publican.cfg (or .cfg) file in order to build the book with Publican. The -docname: attribute in the config file matches the name of the master book file; for example, docname: cloudstack corresponds to the master book file cloudstack.xml. +docname: attribute in the config file matches the name of the master book file; +for example, docname: cloudstack corresponds to the master book file +cloudstack.xml. -The .cfg files reside in the main directory, docs. To build a different book, just use the Publican command line flag --config=.cfg. (We also need per-book entities, Book_Info, Author_Info, and other Publican files. The technique for pulling these in is TBD.) +The .cfg files reside in the main directory, docs. To build a different book, +just use the Publican command line flag --config=.cfg. (We also +need per-book entities, Book_Info, Author_Info, and other Publican files. +The technique for pulling these in is TBD.) ---------------------------------- @@ -83,13 +99,18 @@ TO BUILD A BOOK ---------------------------------- -We will set up an automatic Publican job that generates new output whenever we check in changes to this repository. You can also build a book locally as follows. +We will set up an automatic Publican job that generates new output whenever we +check in changes to this repository. You can also build a book locally as +follows. First, install Publican, and get a local copy of the book source files. -Put the desired publican.cfg in the docs directory. Go to the command line, cd to that directory, and run the publican build command. Specify what output format(s) and what language(s) you want to build. Always start with a test run. For example: +Put the desired publican.cfg in the docs directory. Go to the command line, cd +to that directory, and run the publican build command. Specify what output +format(s) and what language(s) you want to build. Always start with a test +run. For example: publican build --formats test --langs en-US @@ -101,7 +122,7 @@ publican build --formats test --langs en-US publican build --formats html,pdf --langs en-US -Output will be found in the /tmp subdirectory. +Output will be found in the tmp subdirectory of the docs directory. @@ -111,9 +132,29 @@ LOCALIZATION ---------------------------------- -Localized versions of the documentation files can be stored in appropriately named subdirectories parallel to en-US. The language code names to use for these directories are listed in Publican documentation, http://jfearn.fedorapeople.org/en-US/Publican/2.7/html/Users_Guide/appe-Users_Guide-Language_codes.html. +Localized versions of the documentation files can be stored in appropriately +named subdirectories parallel to en-US. The language code names to use for +these directories are listed in Publican documentation, +http://jfearn.fedorapeople.org/en-US/Publican/2.7/html/Users_Guide/appe-Users_Guide-Language_codes.html. For example, Japanese XML files would be stored in the docs/ja-JP directory. +Localization currently happens using Transifex and you can find the strings +to be translated at this location: +https://www.transifex.com/projects/p/ACS_DOCS/ + +In preparation for l10n, authors and docs folks must take not of a number of +things. +All .xml files must contain a translatable string. tags are not enough. +All new .xml files must have a corresponding entry in docs/.tx/config +Filenames should be less than 50 characters long. + +To generate new POT files and upload source do the following: +publican update_pot --config=./publican-all.cfg +tx push -s + +To receive translated files from publican, run the following command: +tx pull + ---------------------------------- @@ -121,7 +162,11 @@ CONTRIBUTING ---------------------------------- -Contributors can create new section, chapter, book, publican.cfg, or localized .xml files at any time. Submit them following the same patch approval procedure that is used for contributing to CloudStack code. More information for contributors is available at https://cwiki.apache.org/confluence/display/CLOUDSTACK/Documentation+Team. +Contributors can create new section, chapter, book, publican.cfg, or localized +.xml files at any time. Submit them following the same patch approval procedure +that is used for contributing to CloudStack code. More information for +contributors is available at +https://cwiki.apache.org/confluence/display/CLOUDSTACK/Documentation+Team. ---------------------------------- @@ -165,8 +210,7 @@ TAGS FOR A SECTION Our publication tool (publican) prefers the note tag. The tool will automatically insert the text NOTE: for you, so please don't type it. Use this for anything that is vital to avoid runtime errors. Don't use - other tags such as caution. Our publication tool (publican) prefers the warning tag. The tool will - automatically insert the text WARNING: for you, so please don't type it. + other tags such as caution. Our publication tool (publican) prefers the warning tag. The tool will automatically insert the text WARNING: for you, so please don't type it. Here's how to do a bulleted list: Bulleted list item text. diff --git a/docs/en-US/API_Developers_Guide.ent b/docs/en-US/API_Developers_Guide.ent new file mode 100644 index 00000000000..47a2b6757f8 --- /dev/null +++ b/docs/en-US/API_Developers_Guide.ent @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/docs/en-US/API_Developers_Guide.xml b/docs/en-US/API_Developers_Guide.xml new file mode 100644 index 00000000000..c691ad02cf6 --- /dev/null +++ b/docs/en-US/API_Developers_Guide.xml @@ -0,0 +1,56 @@ + + +%BOOK_ENTITIES; +]> + + + + + + &PRODUCT; API Developer's Guide + Apache CloudStack + 4.0.0-incubating + + + + + How to integrate with &PRODUCT; using the &PRODUCT; API. + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en-US/cloudstack_developers.ent b/docs/en-US/Admin_Guide.ent similarity index 100% rename from docs/en-US/cloudstack_developers.ent rename to docs/en-US/Admin_Guide.ent diff --git a/docs/en-US/Admin_Guide.xml b/docs/en-US/Admin_Guide.xml new file mode 100644 index 00000000000..07f5e889fc8 --- /dev/null +++ b/docs/en-US/Admin_Guide.xml @@ -0,0 +1,74 @@ + + +%BOOK_ENTITIES; +]> + + + + + + &PRODUCT; Administrator's Guide + Apache CloudStack + 4.0.0-incubating + 1 + + + + Administration Guide for &PRODUCT;. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en-US/Book_Info.xml b/docs/en-US/Book_Info.xml index 3bd6efa176f..c125ab8de2b 100644 --- a/docs/en-US/Book_Info.xml +++ b/docs/en-US/Book_Info.xml @@ -27,7 +27,7 @@ &PRODUCT; Guide Revised August 9, 2012 10:48 pm Pacific Apache CloudStack - 4.0 + 4.0.0-incubating 1 diff --git a/docs/en-US/Book_Info_Release_Notes_4.0.xml b/docs/en-US/Book_Info_Release_Notes_4.0.xml new file mode 100644 index 00000000000..0d57fb6d9a8 --- /dev/null +++ b/docs/en-US/Book_Info_Release_Notes_4.0.xml @@ -0,0 +1,39 @@ + + +%BOOK_ENTITIES; +]> + + + Version 4.0.0-incubating Release Notes + Revised October 17, 2012 19:49 UTC + Apache CloudStack + + + + Release notes for the Apache CloudStack 4.0.0-incubating release. + + + + + + + + + + + diff --git a/docs/en-US/cloudstack-admin.xml b/docs/en-US/CloudStack_Nicira_NVP_Guide.ent similarity index 57% rename from docs/en-US/cloudstack-admin.xml rename to docs/en-US/CloudStack_Nicira_NVP_Guide.ent index c1537638bd8..abb18851bcf 100644 --- a/docs/en-US/cloudstack-admin.xml +++ b/docs/en-US/CloudStack_Nicira_NVP_Guide.ent @@ -1,9 +1,3 @@ - - -%BOOK_ENTITIES; -]> - - - - - - - + + + + diff --git a/docs/en-US/CloudStack_Nicira_NVP_Guide.xml b/docs/en-US/CloudStack_Nicira_NVP_Guide.xml new file mode 100644 index 00000000000..a4c367c26f7 --- /dev/null +++ b/docs/en-US/CloudStack_Nicira_NVP_Guide.xml @@ -0,0 +1,54 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + + + + &PRODUCT; Plugin Guide for the Nicira NVP Plugin + Apache CloudStack + 4.0.0-incubating + 1 + + + + Plugin Guide for the Nicira NVP Plugin. + + + + + + + + + + + + + + + + + + diff --git a/docs/en-US/Installation_Guide.ent b/docs/en-US/Installation_Guide.ent new file mode 100644 index 00000000000..abb18851bcf --- /dev/null +++ b/docs/en-US/Installation_Guide.ent @@ -0,0 +1,22 @@ + + + + + + diff --git a/docs/en-US/Installation_Guide.xml b/docs/en-US/Installation_Guide.xml new file mode 100644 index 00000000000..a40ceed0856 --- /dev/null +++ b/docs/en-US/Installation_Guide.xml @@ -0,0 +1,59 @@ + + +%BOOK_ENTITIES; +]> + + + + + + &PRODUCT; Installation Guide + Apache CloudStack + 4.0.0-incubating + 1 + + + + Installation Guide for &PRODUCT;. + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en-US/release-notes-3.0.4.ent b/docs/en-US/Release_Notes.ent similarity index 100% rename from docs/en-US/release-notes-3.0.4.ent rename to docs/en-US/Release_Notes.ent diff --git a/docs/en-US/Release_Notes.xml b/docs/en-US/Release_Notes.xml new file mode 100644 index 00000000000..849dc5af911 --- /dev/null +++ b/docs/en-US/Release_Notes.xml @@ -0,0 +1,2921 @@ + + +%BOOK_ENTITIES; +]> + + + + + Submitting Feedback and Getting Help + The Apache CloudStack project has mailing lists for users and developers. These are the + official channels of communication for the project and are the best way to get answers about + using and contributing to CloudStack. It's a good idea to subscribe to the cloudstack-users + mailing list if you've deployed or are deploying CloudStack into production, and even for test + deployments. + The CloudStack developer's mailing list (cloudstack-dev) is for discussions about + CloudStack development, and is the best list for discussing possible bugs in CloudStack. + Anyone contributing to CloudStack should be on this mailing list. + You can also report bugs in CloudStack using the Apache Defect Tracking + System + To posts to the lists, you'll need to be subscribed. See the CloudStack Web site + for instructions. + + + Upgrade Instructions +
+ Upgrade from 3.0.2 to 4.0.0-incubating + Perform the following to upgrade from version 3.0.2 to version 4.0.0-incubating. Note + that some of the steps here are only required if you're using a specific hypervisor. The + steps that are hypervisor-specific are called out with a note. + + + Ensure that you query your IP address usage records and process them or make a + backup. During the upgrade you will lose the old IP address usage records. + Starting in 3.0.2, the usage record format for IP addresses is the same as the rest + of the usage types. Instead of a single record with the assignment and release dates, + separate records are generated per aggregation period with start and end dates. After + upgrading, any existing IP address usage records in the old format will no longer be + available. + + + + The following upgrade instructions apply only if you're using VMware hosts. If + you're not using VMware hosts, skip this step and move on to step 3: stopping all + usage servers. + + In each zone that includes VMware hosts, you need to add a new system VM template. + + + While running the existing 3.0.2 system, log in to the UI as root + administrator. + + + In the left navigation bar, click Templates. + + + In Select view, click Templates. + + + Click Register template. + The Register template dialog box is displayed. + + + In the Register template dialog box, specify the following values (do not change + these): + + + + + + + Field + Value + + + + + Name + systemvm-vmware-3.0.5 + + + Description + systemvm-vmware-3.0.5 + + + URL + http://download.cloud.com/templates/burbank/burbank-systemvm-08012012.ova + + + Zone + Choose the zone where this hypervisor is used + + + Hypervisor + VMware + + + Format + OVA + + + OS Type + Debian GNU/Linux 5.0 (32-bit) + + + Extractable + no + + + Password Enabled + no + + + Public + no + + + Featured + no + + + + + + + Watch the screen to be sure that the template downloads successfully and enters + the READY state. Do not proceed until this is successful. + + + + + Stop all Usage Servers if running. Run this on all Usage Server hosts. + # service cloud-usage stop + + + Stop the Management Servers. Run this on all Management Server hosts. + # service cloud-management stop + + + On the MySQL master, take a backup of the MySQL databases. We recommend performing + this step even in test upgrades. If there is an issue, this will assist with + debugging. + In the following commands, it is assumed that you have set the root password on the + database, which is a CloudStack recommended best practice. Substitute your own MySQL + root password. + # mysqldump -u root -pmysql_password cloud > cloud-backup.dmp +# mysqldump -u root -pmysql_password cloud_usage > cloud-usage-backup.dmp + + + Either build RPM/DEB packages as detailed in the Installation Guide, or use one of + the community provided yum/apt repositories to gain access to the &PRODUCT; + binaries. + + + After you have configured an appropriate yum or apt repository, you may execute the + one of the following commands as appropriate for your environment in order to upgrade + &PRODUCT;: # yum update cloud-* + # apt-get update +# apt-get upgrade cloud-* + + + If the upgrade output includes a message similar to the following, then some + custom content was found in your old components.xml, and you need to merge the two + files: + warning: /etc/cloud/management/components.xml created as /etc/cloud/management/components.xml.rpmnew + Instructions follow in the next step. + + + + If you have made changes to your copy of + /etc/cloud/management/components.xml the changes will be + preserved in the upgrade. However, you need to do the following steps to place these + changes in a new version of the file which is compatible with version + 4.0.0-incubating. + + + Make a backup copy of /etc/cloud/management/components.xml. + For example: + # mv /etc/cloud/management/components.xml /etc/cloud/management/components.xml-backup + + + Copy /etc/cloud/management/components.xml.rpmnew to create + a new /etc/cloud/management/components.xml: + # cp -ap /etc/cloud/management/components.xml.rpmnew /etc/cloud/management/components.xml + + + Merge your changes from the backup file into the new + components.xml. + # vi /etc/cloud/management/components.xml + + + + If you have more than one management server node, repeat the upgrade steps on each + node. + + + + Start the first Management Server. Do not start any other Management Server nodes + yet. + # service cloud-management start + Wait until the databases are upgraded. Ensure that the database upgrade is complete. + After confirmation, start the other Management Servers one at a time by running the same + command on each node. + + Failing to restart the Management Server indicates a problem in the upgrade. + Having the Management Server restarted without any issues indicates that the upgrade + is successfully completed. + + + + Start all Usage Servers (if they were running on your previous version). Perform + this on each Usage Server host. + # service cloud-usage start + + + + Additional steps are required for each KVM host. These steps will not affect + running guests in the cloud. These steps are required only for clouds using KVM as + hosts and only on the KVM hosts. + + + + Configure a yum or apt respository containing the &PRODUCT; packages as outlined + in the Installation Guide. + + + Stop the running agent. + # service cloud-agent stop + + + Update the agent software with one of the following command sets as appropriate + for your environment. + # yum update cloud-* + # apt-get update + # apt-get upgrade cloud-* + + + Start the agent. + # service cloud-agent start + + + Edit /etc/cloud/agent/agent.properties to change the + resource parameter from + "com.cloud.agent.resource.computing.LibvirtComputingResource" to + "com.cloud.hypervisor.kvm.resource.LibvirtComputingResource". + + + Start the cloud agent and cloud management services. + + + When the Management Server is up and running, log in to the CloudStack UI and + restart the virtual router for proper functioning of all the features. + + + + + Log in to the CloudStack UI as administrator, and check the status of the hosts. All + hosts should come to Up state (except those that you know to be offline). You may need + to wait 20 or 30 minutes, depending on the number of hosts. + + Troubleshooting: If login fails, clear your browser cache and reload the + page. + + + Do not proceed to the next step until the hosts show in Up state. + + + If you are upgrading from 3.0.2, perform the following: + + + Ensure that the admin port is set to 8096 by using the "integration.api.port" + global parameter. + This port is used by the cloud-sysvmadm script at the end of the upgrade + procedure. For information about how to set this parameter, see "Setting Global + Configuration Parameters" in the Installation Guide. + + + Restart the Management Server. + + If you don't want the admin port to remain open, you can set it to null after + the upgrade is done and restart the management server. + + + + + + Run the cloud-sysvmadm script to stop, then start, all Secondary + Storage VMs, Console Proxy VMs, and virtual routers. Run the script once on each + management server. Substitute your own IP address of the MySQL instance, the MySQL user + to connect as, and the password to use for that user. In addition to those parameters, + provide the -c and -r arguments. For + example: + # nohup cloud-sysvmadm -d 192.168.1.5 -u cloud -p password -c -r > + sysvm.log 2>&1 & + # tail -f sysvm.log + This might take up to an hour or more to run, depending on the number of accounts in + the system. + + + If needed, upgrade all Citrix XenServer hypervisor hosts in your cloud to a version + supported by CloudStack 4.0.0-incubating. The supported versions are XenServer 5.6 SP2 + and 6.0.2. Instructions for upgrade can be found in the CloudStack 4.0.0-incubating + Installation Guide. + + + Now apply the XenServer hotfix XS602E003 (and any other needed hotfixes) to + XenServer v6.0.2 hypervisor hosts. + + + Disconnect the XenServer cluster from CloudStack. + In the left navigation bar of the CloudStack UI, select Infrastructure. Under + Clusters, click View All. Select the XenServer cluster and click Actions - + Unmanage. + This may fail if there are hosts not in one of the states Up, Down, + Disconnected, or Alert. You may need to fix that before unmanaging this + cluster. + Wait until the status of the cluster has reached Unmanaged. Use the CloudStack + UI to check on the status. When the cluster is in the unmanaged state, there is no + connection to the hosts in the cluster. + + + To clean up the VLAN, log in to one XenServer host and run: + /opt/xensource/bin/cloud-clean-vlan.sh + + + Now prepare the upgrade by running the following on one XenServer host: + /opt/xensource/bin/cloud-prepare-upgrade.sh + If you see a message like "can't eject CD", log in to the VM and unmount the CD, + then run this script again. + + + Upload the hotfix to the XenServer hosts. Always start with the Xen pool master, + then the slaves. Using your favorite file copy utility (e.g. WinSCP), copy the + hotfixes to the host. Place them in a temporary folder such as /tmp. + On the Xen pool master, upload the hotfix with this command: + xe patch-upload file-name=XS602E003.xsupdate + Make a note of the output from this command, which is a UUID for the hotfix + file. You'll need it in another step later. + + (Optional) If you are applying other hotfixes as well, you can repeat the + commands in this section with the appropriate hotfix number. For example, + XS602E004.xsupdate. + + + + Manually live migrate all VMs on this host to another host. First, get a list of + the VMs on this host: + # xe vm-list + Then use this command to migrate each VM. Replace the example host name and VM + name with your own: + # xe vm-migrate live=true host=host-name + vm=VM-name + + Troubleshooting + If you see a message like "You attempted an operation on a VM which requires + PV drivers to be installed but the drivers were not detected," run: + /opt/xensource/bin/make_migratable.sh + b6cf79c8-02ee-050b-922f-49583d9f1a14. + + + + Apply the hotfix. First, get the UUID of this host: + # xe host-list + Then use the following command to apply the hotfix. Replace the example host + UUID with the current host ID, and replace the hotfix UUID with the output from the + patch-upload command you ran on this machine earlier. You can also get the hotfix + UUID by running xe patch-list. + xe patch-apply host-uuid=host-uuid uuid=hotfix-uuid + + + Copy the following files from the CloudStack Management Server to the + host. + + + + + + + Copy from here... + ...to here + + + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py + /opt/xensource/sm/NFSSR.py + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/setupxenserver.sh + /opt/xensource/bin/setupxenserver.sh + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/make_migratable.sh + /opt/xensource/bin/make_migratable.sh + + + + + + + (Only for hotfixes XS602E005 and XS602E007) You need to apply a new Cloud + Support Pack. + + + Download the CSP software onto the XenServer host from one of the following + links: + For hotfix XS602E005: http://coltrane.eng.hq.xensource.com/release/XenServer-6.x/XS-6.0.2/hotfixes/XS602E005/56710/xe-phase-2/xenserver-cloud-supp.tgz + For hotfix XS602E007: http://coltrane.eng.hq.xensource.com/release/XenServer-6.x/XS-6.0.2/hotfixes/XS602E007/57824/xe-phase-2/xenserver-cloud-supp.tgz + + + Extract the file: + # tar xf xenserver-cloud-supp.tgz + + + Run the following script: + # xe-install-supplemental-pack xenserver-cloud-supp.iso + + + If the XenServer host is part of a zone that uses basic networking, disable + Open vSwitch (OVS): + # xe-switch-network-backend bridge + + + + + Reboot this XenServer host. + + + Run the following: + /opt/xensource/bin/setupxenserver.sh + + If the message "mv: cannot stat `/etc/cron.daily/logrotate': No such file or + directory" appears, you can safely ignore it. + + + + Run the following: + for pbd in `xe pbd-list currently-attached=false| grep ^uuid | awk '{print $NF}'`; do xe pbd-plug uuid=$pbd ; + + + On each slave host in the Xen pool, repeat these steps, starting from "manually + live migrate VMs." + + + + + + Troubleshooting Tip + If passwords which you know to be valid appear not to work after upgrade, or other UI + issues are seen, try clearing your browser cache and reloading the UI page. + +
+
+ Upgrade from 2.2.14 to 4.0.0-incubating + + + Ensure that you query your IPaddress usage records and process them; for example, + issue invoices for any usage that you have not yet billed users for. + Starting in 3.0.2, the usage record format for IP addresses is the same as the rest + of the usage types. Instead of a single record with the assignment and release dates, + separate records are generated per aggregation period with start and end dates. After + upgrading to 4.0.0-incubating, any existing IP address usage records in the old format + will no longer be available. + + + If you are using version 2.2.0 - 2.2.13, first upgrade to 2.2.14 by using the + instructions in the 2.2.14 Release Notes. + + KVM Hosts + If KVM hypervisor is used in your cloud, be sure you completed the step to insert + a valid username and password into the host_details table on each KVM node as + described in the 2.2.14 Release Notes. This step is critical, as the database will be + encrypted after the upgrade to 4.0.0-incubating. + + + + While running the 2.2.14 system, log in to the UI as root administrator. + + + Using the UI, add a new System VM template for each hypervisor type that is used in + your cloud. In each zone, add a system VM template for each hypervisor used in that + zone + + + In the left navigation bar, click Templates. + + + In Select view, click Templates. + + + Click Register template. + The Register template dialog box is displayed. + + + In the Register template dialog box, specify the following values depending on + the hypervisor type (do not change these): + + + + + + + Hypervisor + Description + + + + + XenServer + Name: systemvm-xenserver-3.0.0 + Description: systemvm-xenserver-3.0.0 + URL: + http://download.cloud.com/templates/acton/acton-systemvm-02062012.vhd.bz2 + Zone: Choose the zone where this hypervisor is used + Hypervisor: XenServer + Format: VHD + OS Type: Debian GNU/Linux 5.0 (32-bit) + Extractable: no + Password Enabled: no + Public: no + Featured: no + + + + KVM + Name: systemvm-kvm-3.0.0 + Description: systemvm-kvm-3.0.0 + URL: + http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 + Zone: Choose the zone where this hypervisor is used + Hypervisor: KVM + Format: QCOW2 + OS Type: Debian GNU/Linux 5.0 (32-bit) + Extractable: no + Password Enabled: no + Public: no + Featured: no + + + + VMware + Name: systemvm-vmware-3.0.5 + Description: systemvm-vmware-3.0.5 + URL: + http://download.cloud.com/templates/burbank/burbank-systemvm-08012012.ova + Zone: Choose the zone where this hypervisor is used + Hypervisor: VMware + Format: OVA + OS Type: Debian GNU/Linux 5.0 (32-bit) + Extractable: no + Password Enabled: no + Public: no + Featured: no + + + + + + + + + + Watch the screen to be sure that the template downloads successfully and enters the + READY state. Do not proceed until this is successful + + + WARNING: If you use more than one type of + hypervisor in your cloud, be sure you have repeated these steps to download the system + VM template for each hypervisor type. Otherwise, the upgrade will fail. + + + Stop all Usage Servers if running. Run this on all Usage Server hosts. + # service cloud-usage stop + + + Stop the Management Servers. Run this on all Management Server hosts. + # service cloud-management stop + + + On the MySQL master, take a backup of the MySQL databases. We recommend performing + this step even in test upgrades. If there is an issue, this will assist with + debugging. + In the following commands, it is assumed that you have set the root password on the + database, which is a CloudStack recommended best practice. Substitute your own MySQL + root password. + # mysqldump -u root -pmysql_password cloud > cloud-backup.dmp +# mysqldump -u root -pmysql_password cloud_usage > cloud-usage-backup.dmp + + + + Either build RPM/DEB packages as detailed in the Installation Guide, or use one of + the community provided yum/apt repositories to gain access to the &PRODUCT; binaries. + + + + After you have configured an appropriate yum or apt repository, you may execute the + one of the following commands as appropriate for your environment in order to upgrade + &PRODUCT;: # yum update cloud-* + # apt-get update +# apt-get upgrade cloud-* + + + + If you have made changes to your existing copy of the file components.xml in your + previous-version CloudStack installation, the changes will be preserved in the upgrade. + However, you need to do the following steps to place these changes in a new version of + the file which is compatible with version 4.0.0-incubating. + + How will you know whether you need to do this? If the upgrade output in the + previous step included a message like the following, then some custom content was + found in your old components.xml, and you need to merge the two files: + + warning: /etc/cloud/management/components.xml created as /etc/cloud/management/components.xml.rpmnew + + + Make a backup copy of your + /etc/cloud/management/components.xml file. For + example: + # mv /etc/cloud/management/components.xml /etc/cloud/management/components.xml-backup + + + Copy /etc/cloud/management/components.xml.rpmnew to create + a new /etc/cloud/management/components.xml: + # cp -ap /etc/cloud/management/components.xml.rpmnew /etc/cloud/management/components.xml + + + Merge your changes from the backup file into the new components.xml file. + # vi /etc/cloud/management/components.xml + + + + + + If you have made changes to your existing copy of the + /etc/cloud/management/db.properties file in your previous-version + CloudStack installation, the changes will be preserved in the upgrade. However, you need + to do the following steps to place these changes in a new version of the file which is + compatible with version 4.0.0-incubating. + + + Make a backup copy of your file + /etc/cloud/management/db.properties. For example: + # mv /etc/cloud/management/db.properties /etc/cloud/management/db.properties-backup + + + Copy /etc/cloud/management/db.properties.rpmnew to create a + new /etc/cloud/management/db.properties: + # cp -ap /etc/cloud/management/db.properties.rpmnew etc/cloud/management/db.properties + + + Merge your changes from the backup file into the new db.properties file. + # vi /etc/cloud/management/db.properties + + + + + On the management server node, run the following command. It is recommended that you + use the command-line flags to provide your own encryption keys. See Password and Key + Encryption in the Installation Guide. + # cloud-setup-encryption -e encryption_type -m management_server_key -k database_key + When used without arguments, as in the following example, the default encryption + type and keys will be used: + + + (Optional) For encryption_type, use file or web to indicate the technique used + to pass in the database encryption password. Default: file. + + + (Optional) For management_server_key, substitute the default key that is used to + encrypt confidential parameters in the properties file. Default: password. It is + highly recommended that you replace this with a more secure value + + + (Optional) For database_key, substitute the default key that is used to encrypt + confidential parameters in the CloudStack database. Default: password. It is highly + recommended that you replace this with a more secure value. + + + + + Repeat steps 10 - 14 on every management server node. If you provided your own + encryption key in step 14, use the same key on all other management servers. + + + Start the first Management Server. Do not start any other Management Server nodes + yet. + # service cloud-management start + Wait until the databases are upgraded. Ensure that the database upgrade is complete. + You should see a message like "Complete! Done." After confirmation, start the other + Management Servers one at a time by running the same command on each node. + + + Start all Usage Servers (if they were running on your previous version). Perform + this on each Usage Server host. + # service cloud-usage start + + + (KVM only) Additional steps are required for each KVM host. These steps will not + affect running guests in the cloud. These steps are required only for clouds using KVM + as hosts and only on the KVM hosts. + + + Configure your CloudStack package repositories as outlined in the Installation + Guide + + + Stop the running agent. + # service cloud-agent stop + + + Update the agent software with one of the following command sets as + appropriate. + # yum update cloud-* + + # apt-get update +# apt-get upgrade cloud-* + + + + Start the agent. + # service cloud-agent start + + + Copy the contents of the agent.properties file to the new + agent.properties file by using the following command + sed -i 's/com.cloud.agent.resource.computing.LibvirtComputingResource/com.cloud.hypervisor.kvm.resource.LibvirtComputingResource/g' /etc/cloud/agent/agent.properties + + + Start the cloud agent and cloud management services. + + + When the Management Server is up and running, log in to the CloudStack UI and + restart the virtual router for proper functioning of all the features. + + + + + Log in to the CloudStack UI as admin, and check the status of the hosts. All hosts + should come to Up state (except those that you know to be offline). You may need to wait + 20 or 30 minutes, depending on the number of hosts. + Do not proceed to the next step until the hosts show in the Up state. If the hosts + do not come to the Up state, contact support. + + + Run the following script to stop, then start, all Secondary Storage VMs, Console + Proxy VMs, and virtual routers. + + + Run the command once on one management server. Substitute your own IP address of + the MySQL instance, the MySQL user to connect as, and the password to use for that + user. In addition to those parameters, provide the "-c" and "-r" arguments. For + example: + # nohup cloud-sysvmadm -d 192.168.1.5 -u cloud -p password -c -r > sysvm.log 2>&1 & +# tail -f sysvm.log + This might take up to an hour or more to run, depending on the number of + accounts in the system. + + + After the script terminates, check the log to verify correct execution: + # tail -f sysvm.log + The content should be like the following: + +Stopping and starting 1 secondary storage vm(s)... +Done stopping and starting secondary storage vm(s) +Stopping and starting 1 console proxy vm(s)... +Done stopping and starting console proxy vm(s). +Stopping and starting 4 running routing vm(s)... +Done restarting router(s). + + + + + + If you would like additional confirmation that the new system VM templates were + correctly applied when these system VMs were rebooted, SSH into the System VM and check + the version. + Use one of the following techniques, depending on the hypervisor. + + XenServer or KVM: + SSH in by using the link local IP address of the system VM. For example, in the + command below, substitute your own path to the private key used to log in to the + system VM and your own link local IP. + + Run the following commands on the XenServer or KVM host on which the system VM is + present: + # ssh -i private-key-path link-local-ip -p 3922 +# cat /etc/cloudstack-release + The output should be like the following: + Cloudstack Release 4.0.0-incubating Mon Oct 9 15:10:04 PST 2012 + + ESXi + SSH in using the private IP address of the system VM. For example, in the command + below, substitute your own path to the private key used to log in to the system VM and + your own private IP. + + Run the following commands on the Management Server: + # ssh -i private-key-path private-ip -p 3922 +# cat /etc/cloudstack-release + + The output should be like the following: + Cloudstack Release 4.0.0-incubating Mon Oct 9 15:10:04 PST 2012 + + + If needed, upgrade all Citrix XenServer hypervisor hosts in your cloud to a version + supported by CloudStack 4.0.0-incubating. The supported versions are XenServer 5.6 SP2 + and 6.0.2. Instructions for upgrade can be found in the CloudStack 4.0.0-incubating + Installation Guide. + + + Apply the XenServer hotfix XS602E003 (and any other needed hotfixes) to XenServer + v6.0.2 hypervisor hosts. + + + Disconnect the XenServer cluster from CloudStack. + In the left navigation bar of the CloudStack UI, select Infrastructure. Under + Clusters, click View All. Select the XenServer cluster and click Actions - + Unmanage. + This may fail if there are hosts not in one of the states Up, Down, + Disconnected, or Alert. You may need to fix that before unmanaging this + cluster. + Wait until the status of the cluster has reached Unmanaged. Use the CloudStack + UI to check on the status. When the cluster is in the unmanaged state, there is no + connection to the hosts in the cluster. + + + To clean up the VLAN, log in to one XenServer host and run: + /opt/xensource/bin/cloud-clean-vlan.sh + + + Prepare the upgrade by running the following on one XenServer host: + /opt/xensource/bin/cloud-prepare-upgrade.sh + If you see a message like "can't eject CD", log in to the VM and umount the CD, + then run this script again. + + + Upload the hotfix to the XenServer hosts. Always start with the Xen pool master, + then the slaves. Using your favorite file copy utility (e.g. WinSCP), copy the + hotfixes to the host. Place them in a temporary folder such as /root or /tmp. + On the Xen pool master, upload the hotfix with this command: + xe patch-upload file-name=XS602E003.xsupdate + Make a note of the output from this command, which is a UUID for the hotfix + file. You'll need it in another step later. + + (Optional) If you are applying other hotfixes as well, you can repeat the + commands in this section with the appropriate hotfix number. For example, + XS602E004.xsupdate. + + + + Manually live migrate all VMs on this host to another host. First, get a list of + the VMs on this host: + # xe vm-list + Then use this command to migrate each VM. Replace the example host name and VM + name with your own: + # xe vm-migrate live=true host=host-name vm=VM-name + + Troubleshooting + If you see a message like "You attempted an operation on a VM which requires + PV drivers to be installed but the drivers were not detected," run: + /opt/xensource/bin/make_migratable.sh + b6cf79c8-02ee-050b-922f-49583d9f1a14. + + + + Apply the hotfix. First, get the UUID of this host: + # xe host-list + Then use the following command to apply the hotfix. Replace the example host + UUID with the current host ID, and replace the hotfix UUID with the output from the + patch-upload command you ran on this machine earlier. You can also get the hotfix + UUID by running xe patch-list. + xe patch-apply host-uuid=host-uuid + uuid=hotfix-uuid + + + Copy the following files from the CloudStack Management Server to the + host. + + + + + + + Copy from here... + ...to here + + + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py + /opt/xensource/sm/NFSSR.py + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/setupxenserver.sh + /opt/xensource/bin/setupxenserver.sh + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/make_migratable.sh + /opt/xensource/bin/make_migratable.sh + + + + + + + (Only for hotfixes XS602E005 and XS602E007) You need to apply a new Cloud + Support Pack. + + + Download the CSP software onto the XenServer host from one of the following + links: + For hotfix XS602E005: http://coltrane.eng.hq.xensource.com/release/XenServer-6.x/XS-6.0.2/hotfixes/XS602E005/56710/xe-phase-2/xenserver-cloud-supp.tgz + For hotfix XS602E007: http://coltrane.eng.hq.xensource.com/release/XenServer-6.x/XS-6.0.2/hotfixes/XS602E007/57824/xe-phase-2/xenserver-cloud-supp.tgz + + + Extract the file: + # tar xf xenserver-cloud-supp.tgz + + + Run the following script: + # xe-install-supplemental-pack + xenserver-cloud-supp.iso + + + If the XenServer host is part of a zone that uses basic networking, disable + Open vSwitch (OVS): + # xe-switch-network-backend bridge + + + + + Reboot this XenServer host. + + + Run the following: + /opt/xensource/bin/setupxenserver.sh + + If the message "mv: cannot stat `/etc/cron.daily/logrotate': No such file or + directory" appears, you can safely ignore it. + + + + Run the following: + for pbd in `xe pbd-list currently-attached=false| grep ^uuid | awk + '{print $NF}'`; do xe pbd-plug uuid=$pbd ; + + + + On each slave host in the Xen pool, repeat these steps, starting from "manually + live migrate VMs." + + + + +
+
+ + Version 4.0.0-incubating +
+ What’s New in 4.0.0-incubating + Apache CloudStack 4.0.0-incubating includes the following new features: +
+ Inter-VLAN Routing + Inter-VLAN Routing is the capability to route network traffic between VLANs. This + feature enables you to set up Virtual Private Clouds (VPC) that can hold multi-tier + applications. These tiers are deployed on different VLANs that can communicate with each + other. You can provision VLANs to the tiers your create, and VMs can be deployed on + different tiers, such as Web, Application, or Database. The VLANs are connected to a + virtual router, which facilitates communication between the VMs. In effect, you can + segment VMs by means of VLANs into different networks that can host multi-tier + applications. Such segmentation by means of VLANs logically separate application VMs for + higher security and lower broadcasts, while remaining physically connected to the same + device. + This feature is supported on XenServer and VMware hypervisors. +
+
+ Site-to-Site VPN + A Site-to-Site VPN connection helps you establish a secure connection from an + enterprise datacenter to the cloud infrastructure. This allows users to access the guest + VMs by establishing a VPN connection to the virtual router of the account from a device in + the datacenter of the enterprise. Having this facility eliminates the need to establish + VPN connections to individual VMs. + The supported endpoints on the remote datacenters are: + + + Cisco ISR with IOS 12.4 or later + + + Juniper J-Series routers with JunOS 9.5 or later + + +
+
+ Local Storage Support for Data Volumes + You can now create data volumes on local storage. The data volume is placed on the + same XenServer host as the VM instance that is attached to the data volume. These local + data volumes can be attached to virtual machines, detached, re-attached, and deleted just + as with the other types of data volume. In earlier releases of CloudStack, only the root + disk could be placed in local storage. + Local storage is ideal for scenarios where persistence of data volumes and HA is not + required. Some of the benefits include reduced disk I/O latency and cost reduction from + using inexpensive local disks. + In order for local volumes to be used, the feature must be enabled for the + zone. + You can create a data disk offering for local storage. When a user creates a new VM, + they can select this disk offering in order to cause the data disk volume to be placed in + local storage. + You can not migrate a VM that has a volume in local storage to a different host, nor + migrate the volume itself away to a different host. If you want to put a host into + maintenance mode, you must first stop any VMs with local data volumes on that host. + Local storage support for volumes is available for XenServer, KVM, and VMware + hypervisors. +
+
+ Tags + A tag is a key-value pair that stores metadata about a resource in the cloud. Tags are + useful for categorizing resources. For example, you can tag a user VM with a value that + indicates the user's city of residence. In this case, the key would be "city" and the + value might be "Toronto" or "Tokyo." You can then request CloudStack to find all resources + that have a given tag; for example, VMs for users in a given city. + You can tag a user virtual machine, volume, snapshot, guest network, template, ISO, + firewall rule, port forwarding rule, public IP address, security group, load balancer + rule, project, VPC, network ACL, or static route. You can not tag a remote access + VPN. + You can work with tags through the UI or through the new API commands createTags, + deleteTags, and listTags. You can define multiple tags for each resource. There is no + limit on the number of tags you can define. Each tag can be up to 255 characters long. + Users can define tags on the resources they own, and administrators can define tags on any + resources in the cloud. + A new optional input parameter, "tags," has been added to many of the list* API + commands. The following example shows how to use this new parameter to find all the + volumes having tag region=canada OR tag city=Toronto: + command=listVolumes +&listAll=true +&tags[0].key=region +&tags[0].value=canada +&tags[1].key=city +&tags[1].value=Toronto + The following API commands have the new "tags" input parameter: + + + listVirtualMachines + + + listVolumes + + + listSnapshots + + + listNetworks + + + listTemplates + + + listIsos + + + listFirewallRules + + + listPortForwardingRules + + + listPublicIpAddresses + + + listSecurityGroups + + + listLoadBalancerRules + + + listProjects + + + listVPCs + + + listNetworkACLs + + + listStaticRoutes + + +
+
+ AWS API Changes for Tags + Some changes have been made to the Amazon Web Services API compatibility support in + order to accommodate the new tagging feature. + New APIs: + + + + + + + + New API + + + Description + + + + + + + ec2-create-tags + + + Add tags to one or more resources. + + + + + ec2-delete-tags + + + Remove tags from one or more resources. + + + + ec2-describe-tags + + Show currently defined tags. + + + + + + Changed APIs: + + + + + + + + Changed API + + + Description + + + + + + ec2-describe-images + + Output now shows tags defined for each image. + + + + + ec2-describe-instances + + + Output now shows tags defined for each image. + The following filters can now be passed in to limit the output result set: + tag-key, tag-value and tag:key + + + + + ec2-describe-snapshots + + + Output now shows tags defined for each image. + The following filters can now be passed in to limit the output result set: + tag-key, tag-value and tag:key + + + + ec2-describe-volumes + + Output now shows tags defined for each image. + The following filters can now be passed in to limit the output result set: + tag-key, tag-value and tag:key + + + + + +
+
+ Secure Console Access on XenServer + With the addition of Secure Console feature, users can now securely access the VM + consoles on the XenServer hypervisor. You can either SSH or use the View Console option in + the Management Server to securely connect to the VMs on the XenServer host. The Management + Server uses the xapi API to stream the VM consoles. However, there is no change in the way + you can access the console of a VM. This feature is supported on XenServer 5.6 and 6.0 + versions. +
+
+ Stopped VM + This release supports creating VMs without starting them on the backend. You can + determine whether the VM needs to be started as part of the VM deployment. A VM can be + deployed in two ways: create and start a VM (the default method); create a VM and leave it + in the stopped state. + A new request parameter, startVM, is introduced in the deployVm API to support the + stopped VM feature. The possible values are: + + + true - The VM starts as a part of the VM deployment + + + false - The VM is left in stopped state at the end of the VM deployment + + +
+
+ Uploading an Existing Volume to a Virtual Machine + Existing data can now be made accessible to a virtual machine. This is called + uploading a volume to the VM. For example, this is useful to upload data from a local file + system and attach it to a VM. Root administrators, domain administrators, and end users + can all upload existing volumes to VMs. The upload is performed by using HTTP. The + uploaded volume is placed in the zone's secondary storage. + This functionality is supported for the following hypervisors: + + + Hypervisor : Disk Image Format + + + XenServer : VHD + + + VMware : OVA + + + KVM : QCOW2 + + + +
+
+ Dedicated High-Availability Hosts + One or more hosts can now be designated for use only by high-availability (HA) enabled + VMs that are restarted due to a host failure. Setting up a pool of such dedicated HA hosts + as the recovery destination for all HA-enabled VMs make it easier to determine which VMs + are restarted as part of the high-availability function. You can designate a host as a + dedicated-HA restart node only if the Dedicated HA Hosts feature is enabled by setting the + appropriate global configuration parameter. +
+
+ Support for Amazon Web Services API + This release supports Amazon Web Services APIs, including Elastic Compute Cloud (EC2) + API. Fidelity with the EC2 API and the installation experience for this functionality are + both enhanced. In prior releases, users were required to install a separate component + called CloudBridge, in addition to installing the Management Server. For new installations + of CloudStack 4.0.0-incubating, this software is installed automatically along with + CloudStack and runs in a more closely integrated fashion. The feature is disabled by + default, but can be easily enabled by setting the appropriate global configuration + parameter and performing a few setup steps. +
+
+ The Nicira NVP Plugin + The Nicira NVP plug-in allows CloudStack to use the Nicira solution for virtualized + network as a provider for CloudStack networks and services. In CloudStack 4.0.0-incubating + this plug-in supports the Connectivity service. This service is responsible for creating + Layer 2 networks supporting the networks created by guests. When a tenant creates a new + network, instead of a traditional VLAN, a logical network will be created by sending the + appropriate calls to the Nicira NVP Controller. The plug-in has been tested with Nicira + NVP versions 2.1.0, 2.2.0 and 2.2.1. +
+
+ Support for CAStor Cluster + CloudStack 4.0.0-incubating supports using a CAStor cluster as the back-end storage + system for a CloudStack S3 front-end. The CAStor back-end storage for CloudStack extends + the existing storage classes and allows the storage configuration attribute to point to a + CAStor cluster. This feature makes use of the CloudStack server's local disk to spool + files before writing them to CAStor when handling the PUT operations. However, a file must + be successfully written into the CAStor cluster prior to the return of a success code to + the S3 client to ensure that the transaction outcome is correctly reported. + The S3 multipart file upload is not supported in this release. You are prompted with + proper error message if a multipart upload is attempted. +
+
+ Clustered Logical Volume Manager Support for KVM + This release adds Clustered Logical Volume Manager (CLVM) storage support for KVM + hosts. With this support, you can use CLVM as primary storage. + The CLVM support for KVM allows root and data disks (primary storage) to reside on + Linux logical volumes. The administrators are required to configure CLVM on the KVM hosts + independent of CloudStack. When the volume groups are available, an administrator can + simply add primary storage of type CLVM, providing the volume group name. Then CloudStack + creates and manages logical volumes as needed. + CLVM also supports Snapshots. CloudStack creates an LVM snapshot, copy the applicable + logical volume to the secondary storage in the qcow2 format, and then delete the LVM + snapshot. +
+
+ Rados Block Device Support for KVM + You can now use Rados Block Device (RBD) to run instances on Apache CloudStack + 4.0.0-incubating. This can be done by adding a RBD pool as primary storage. Before using + RBD, ensure that Qemu is compiled with RBD enabled, and the libvirt version is at least + 0.10 with RBD enabled on the KVM host + Create a disk offering for RBD so that you can ensure that StoragePoolAllocator + chooses the RBD pool to deploy instances. +
+
+
+ Issues Fixed in 4.0.0-incubating + Many bugs include a defect number that reflects the bug number that was held in the bug + tracker run by Citrix (bugs.cloudstack.org). The Apache CloudStack project now uses Jira to manage its bugs, so + some of the bugs that are referenced here may not be available to view. However, we are + still including them for completeness. + + + + + + + + Defect + + + Description + + + + + + Many + vSphere 5.0 now has GA support. Formerly only Beta support was + provided. + + + CS-16135 + Creating volumes after upgrading from snapshot taken in 2.2.14 no longer + deletes the snapshot physically from the secondary storage. + + + CS-16122 + In a site-to-site VPN setup, alerts are generated when the VPC virtual + router is rebooted with multiple vpn connections. + + + CS-16022 + If host connection fails due to a database error, host now disconnects + and the Managerment Server id is removed. + + + CS-16011 + Name of network offering is no longer truncated due to too-narrow field + width in Add Guest Network dialog box. + + + + CS-15978 + When the virtual router and its host go down, the high availability + mechanism now works for the virtual router. + + + + CS-15921 + The 2.2.x security group script now accounts for the VMs created in the + version 2.1 timeframe. + + + + CS-15919 + A level parameter is added to the listVolumes command; therefore queries + return the response more quickly. + + + CS-15904 + Upgrade from version 2.2.14 to CloudStack-3.0.5-0.2944-rhel5 works as + expected. The upgrade script, + /usr/share/cloud/setup/db/schema-2214to30-cleanup.sql, works as + expected. + + + CS-15879 + The database upgrade from version 3.0.4 to 3.0.5 works as + expected. + + + + CS-15807 + Network label for OVM now available in UI. + + + + CS-15779 + When the thumbnail is requested, the console session will not be + terminated. + + + + CS-15778 + Fetching a VM thumbnail now gets a thumbnail of appropriate visual + dimensions. + + + + CS-15734 + KVM Snapshots no longer shows incorrect disk usage. + + + CS-15733 + The domainId parameter for the listNetworks command now lists the + resources belonging to the domain specified. + + + CS-15676 + Stopping the router no longer fails with the null pointer + exception. + + + + CS-15648 + If creating a volume from a snapshot fails, the error is reported on the + UI but the volume is stuck in the creating state. + + + + CS-15646 + createFirewallRule API no longer causes null pointer + exception. + + + CS-15628 + In a KVM host, the high availability mechanism no longer takes a long + time to migrate VMs to another KVM host if there are multiple storage + pools. + + + CS-15627 + Metadata instance-id and vm-id for existing VMs stays the same after + upgrade. + + + CS-15621 + Solved difficulty with allocating disk volumes when running multiple VM + deployment in parallel. + + + CS-15603 + CloudStack now stop the VMs when destroyVM command is + called. + + + CS-15586 + Public Vlan for an account no longer fails if multiple physical networks + are present. + + + CS-15582 + The dns-name filter is now supported for ec2-describe-instances in the + Amazon Web Services API compatibility commands. The filter maps to the name of a + user VM. + + + CS-15503 + An IP address which has static NAT rules can now be released. + Subsequently, restarting this network after it was shutdown can + succeed. + + + CS-15464 + Can now delete static route whose state is set to Revoke. + + + CS-15443 + Creating a firewall rule no longer fails with an internal server + error. + + + CS-15398 + Corrected technique for programming DNS on the user VMs. + + + CS-15356 + Internal DNS 2 entry now correctly shown in UI. + + + CS-15335 + The CloudBridge S3 Engine now connects to the database by using the + deciphered password in the db.properties file. + + + CS-15318 + UI now correctly prevents the user from stopping a VM that is in the + Starting state. + + + CS-15307 + Fixed Japanese localization of instance statuses in the Instances + menu. + + + CS-15278 + The deployment planner no longer takes long time to locate a suitable + host to deploy VMs when large number of clusters are present. + + + CS-15274 + Creating a VLAN range using Zone ID without network ID now + succeeds. + + + CS-15243 + Now check to be sure source NAT and VPN have same + provider. + + + CS-15232 + Ensure that networks using external load balancer/firewall in 2.2.14 or + earlier can properly upgrade. + + + CS-15200 + No exception when trying to attach the same volume while attaching the + first volume is in progress. + + + CS-15173 + Additional cluster can no longer be added with same VSM IP address as + another cluster. + + + CS-15167 + AWS API calls now honor the admin account's ability to view or act on the + resources owned by the regular users. + + + CS-15163 + The minimum limit is not honored when there is not enough capacity to + deploy all the VMs and the ec2-run-instances command with the -n >n1 -n2> + option is used to deploy multiple VMs. + + + CS-15157 + Can now add/enable service providers for multiple physical networks + through the UI. + + + CS-15145 + AWS API call ec2-register has better error handling for negative + cases. + + + CS-15122 + Filters now supported for AWS API call + ec2-describe-availability-zones. + + + CS-15120 + Actions column in UI of Volume page now shows action + links. + + + CS-15099 + Buttons no longer overlap text on Account Deletion confirmation page in + UI. + + + CS-15095 + Ensures you can not create a VM with a CPU frequency greater than the + host CPU frequency. + + + CS-15094 + CPU cap now set properly in VMware. + + + CS-15077 + NullPointerException is no longer observed while executing the command to + list the public IP in a basic zone created with the default shared NetScaler EIP + and ELB network offering. + + + CS-15044 + UI now provides option to view the list of instances which are part of + the guest network. + + + CS-15026 + UI in Deploy VM dialog now lists only templates or ISOs depending on + which is selected in previous dialog. + + + CS-14989 + In KVM, the Create Instance wizard now shows only templates from the + current (KVM) zone. + + + CS-14986, CS-14985 + Listing filters works as expected in the ec2-describe-volumes and + ec2-describe-snapshots commands. + + + CS-14964 + Automatically starting the Console Proxy no longer fails due to its + missing volume on the primary storage + + + CS-14907 + User is now correctly prevented from trying to download an uploaded + volume which has not yet been moved to primary storage. + + + CS-14879 + When a user VM is stopped or terminated, the static NAT associated with + this VM is now disabled. This public IP address is no longer owned by this account + and can be associated to any other user VM. + + + CS-14854 + Only the admin user can change the template permission to Public, so this + option is removed from the UI for domain Admins and regular Users. + + + CS-14817 + While checking if network has any external provider, CloudStack will + consider all providers in the network. + + + CS-14796 + When deploying a VM with ec2-run-instances, userdata is now + encoded. + + + CS-14770 + The API returns the keypair information when a VM is deployed with + sshkey. This affects the API commands related to virtual machines + (deployVirtualMachine, listVirtualMachines, ... *VirtualMachine), as well as the + corresponding AWS APIs. + + + CS-14724 + UI no longer displays the dropdown list of isolation method choices if + sdn.ovs.controller is false. + + + CS-14345 + Logout API returns XML header. + + + CS-14724 + Host IPs now associated with appropriate IPs according to traffic + type. + + + CS-14253 + Can now delete and re-create port forwarding rule on same + firewall. + + + CS-14724 + UI no longer displays the dropdown list of isolation method choices if + sdn.ovs.controller is false. + + + CS-14452 + Data disk volumes are now automatically copied from one cluster to + another. + + + CS-13539 + Windows VM can get IP after reboot. + + + CS-13537 + When user tries to delete a domain that contains sub-domains, an error + message is now sent to convey the reason for the delete failure. + + + CS-13153 + System VMs support HTTP proxy. + + + CS-12642 + Added Close button to Select Project list view popup in + UI. + + + CS-12510 + Deleting and reinserting host_details no longer causes + deadlocks. + + + CS-12407 + F5 and Netscaler - when dedicated is selected, capacity field is + disabled. + + + CS-12111 + Email validation for edit user form. + + + CS-10928 + Network read/write values now always positive numbers. + + + CS-15376, CS-15373 + The AWS APIs (EC2 and S3) now listen on the 7080 port and send request to + CloudStack on the 8080 port just as any other clients of + CloudStack. + + + CS-13944 + The CloudStack 2.2.x to 3.0.x database upgrade for multiple physical + networks is now supported. + + + CS-15300 + The admin accounts of a domain now honour the limits imposed on that + domain just like the regular accounts do. A domain admin now is not allowed to + create an unlimited number of instances, volumes, snapshots, and so + on. + + + CS-15396 + The CloudStack database now contain the UUD information after the 2.2.14 + to 3.0.4 upgrade. + + + CS-15450 + Upgrade from 2.2.14 to 3.0.4 no longer fails on a VMware + host. + + + CS-15449 + Running cloudstack-aws-api-register no longer fails with the "User + registration failed with error: [Errno 113] No route to host" + error. + + + CS-15455 + The iptable rules are configured to open the awsapi port (7080) as part + of the installation. + + + CS-15429 + While creating an instance with data volume, disk offering also is + considered while checking the account limit on volume resources. + + + CS-15414 + After the 2.2.14 to 3.0.4 upgrade, the value of the global parameter + xen.guest.network.device is now decrypted before setting the traffic + label. + + + CS-15382 + During 2.2.14 to 3.0.4 upgrade, the hosts no longer go to the Alert state + if destroyed networks existed with non-existent tags prior to + upgrade. + + + CS-15323 + CloudStack supports the following Citrix XenServer hotfixes: XS602E003, + XS602E004, and XS602E005. + + + CS-15430 + Create snapshot now fails if creating a snapshot exceeds the snapshot + resource limit for a domain admin or a user account. + + + CS-14256 + Virtual Router no longer remains in starting state for subdomain or user + on a KVM 3.0.1 prerlease host on RHEL 6.2. + + + CS-7495 + Implemented a variety of Xen management host improvements. + + + CS-8105 + NFS v4 for primary storage now works as expected on KVM + hosts. + + + CS-9989 + The error messages returned during VM deployment failure will have much + more details than before. + + + CS-12584 + You can no longer add security groups not supported by the hypervisor in + use. + + + CS-12705 + When creating a Network offering by using SRX as the service provider for + SourceNAT servcies, an option is given in the CloudStack UI now to set the + source_nat type to "per Zone"/"per account". + + + CS-12782 + Assigning a VM from Basic to Advanced zone no longer ignores the network + ID. A warning message is displayed for VM movements across zones. + + + CS-12591 + Broadcast Address on the Second Public IP NIC is now + corrected. + + + CS-13272 + When a user is deleted, all the associated properties, such as IPs and + virtual routers, are now deleted. + + + CS-13377 + Creating template from a root disk of a stopped instance now provides an + option to make it a "Featured template". + + + CS-13500 + Reaching the first guest VM by using its public IP from the second guest + VM no longer fails. + + + CS-13853 + The default gateway can no longer be 0.0.0.0 in the Secondary Storage VM + (SSVM). + + + CS-13863 + The queryAsyncJobResult command in XML format now returns the correct + UUIDs. + + + CS-13867 + Corrected CSP xenserver-cloud-supp.tgz for XenServer 5.6 and + 6.0. + + + CS-13904 + Labels and values for the service offerings CPU and memory are now + consistent. + + + CS-13998 + The SSVM kernel panic issue is fixed on XenServer. + + + CS-14090 + The issue is fixed where running the VMware snapshots randomly fails with + the ArrayIndexOutOfBoundsException error. + + + CS-14021 + The java.lang.OutOfMemoryError is fixed on the Management + Server. + + + CS-14025 + The Python Eggs are provided to easily package the test client for each + branch of CloudStack. + + + CS-14068 + Resetting the VM password through the CloudStack UI no longer causes any + error. + + + CS-14156 + The pod which has the administrator's virtual router is no longer + selected while creating the virtual routers for guests. + + + CS-14182 + The users can now delete their ISOs as normal users. + + + CS-14185 + The listOSTypes API now filters out the types of operating system by + using the keywords. + + + CS-14204 + The cloud-setup-bonding.sh command no longer generates the "command not + found" error. + + + CS-14214 + The Specify VLAN option cannot be enabled now for an isolated Network + offering with SourceNAT enabled. + + + CS-14234 + Sending project invite email to an account now requires SMTP configured + in CloudStack. + + + CS-14237 + The garbage collector of the primary storage no longer fails when the + first host in the cluster is not up. + + + CS-14241 + Custom Volume Disk Offering is now matching the Global configuration + value. + + + CS-14270 + The listNetworks API no longer assumes that the broadcast type is always + VLAN. + + + CS-14319 + The internal name of the VM is no longer present in the error message + that is displayed to a domain administrator. + + + CS-14321 + The listVolumes API call now returns a valid value for the isExtractable + parameter for the ISO-derived disk and data disk volumes. + + + CS-14323 + Invalid API calls will now give valid response in json/xml + format. + + + CS-14339 + Custom Disk Size will now allow values larger than 100GB. + + + CS-14357 + The ConsoleProxyLoadReportCommand is no longer fired + continuously. + + + CS-14421 + Fixed the issue of virtual router deployments. The DHCP entries can now + be assigned to the router. + + + CS-14555 + Unzipped downloaded template MD5SUM will no longer override the zipped + template MD5SUM in the database. + + + CS-14598 + The complete screen of the running VM is now displayed in the console + proxy. + + + CS-14600 + Windows or Linux based consoles are no longer lost upon rebooting + VMs. + + + CS-14784 + Multiple subnets with the same VLAN now work as expected. + + + CS-13303, 14874, 13897, 13944, 14088, 14190 + A variety of upgrade issues have been fixed in release + 3.0.3. + + + CS-15080 + Setting a private network on a VLAN for VMWare environment is now + supported. + + + CS-15168 + The console proxy now works as expected and no exception is shown in the + log after upgrading from version 2.2.14 to 3.0.2. + + + CS-15172 + Version 3.0.2 now accepts the valid public key. + + + + +
+
+ Known Issues in 4.0.0-incubating + + + + + + + + Issue ID + + + Description + + + + + + CLOUDSTACK-301 + Nexus 1000v DVS integration is not functional + This source code release includes some partial functionality to support the + Cisco Nexus 1000v Distributed Virtual Switch within a VMware hypervisor + environment. The functionality is not complete at this time. + + + + CLOUDSTACK-368 + OVM - cannot create guest VM + This source code release has regressed from the CloudStack 2.2.x code + and is unable to support Oracle VM (OVM). + + + + CLOUDSTACK-279 + Deleting a project fails when executed by the regular user. This works as + expected for root/domain admin. To workaround, perform either of the + following: + + Use the account cleanup thread which will eventually complete the project + deletion. + + + Execute the call as the root/domain admin on behalf of the regular + user. + + + + + + CS-16067 + The command=listTags&key=city command does not work as expected. The + command does not return tags for the resources of the account with the tag, city + + + + + CS-16063 + The current values of volumes and snapshots are incorrect when using KVM + as a host. To fix this, the database upgrade codes, volumes.size and + snapshots.size, should be changed to show the virtual sizes. + + + + CS-16058 + Null pointer Exception while deleting the host after moving the host to + maintenance state. + + + + CS-16045 + Only the root administrator can handle the API keys. The domain + administrators are not allowed to create, delete, or retrieve API keys for the + users in their domain. + + + + CS-16019 + CIDR list in the Add VPN Customer Gateway dialog does not prompt the user + that they can provide a comma separated CIDRs if multiple CIDRs have to be + supplied. + + + + CS-16015 + Deleting a network is not supported when its network providers are + disabled. + + + + CS-16012 + Unable to delete a zone in the UI because the necessary cleanup cannot be + completed. When the hosts are removed, the expunge process fails to delete the + volumes as no hosts are present to send the commands to. Therefore, the storage + pool removal fails, and zone can't be cleaned and deleted. + + + + CS-16011 + Name of network offering might be truncated due to too-narrow field width + in Add Guest Network dialog box. + + + + CS-15789 + Invalid global setting prevents management server to restart. For + example, if you configure the "project.invite.timeout" parameter to "300" and + attempt to restart management server, it fails without throwing a warning or + setting the value to the default. + + + + CS-15749 + Restarting VPC is resulting in intermittent connection loss to the port + forwarding and StaticNAT rules. + + + + CS-15690 + The IpAssoc command failed as a part of starting the virtual router, but + the final start result is reported as succes. + + + + CS-15672, CS-15635 + The FQDN of the VM is not configured if it is deployed as a part of + default shared network and isolated guest network + (DefaultIsolatedNetworkOfferingWithSourceNatService). + + + + CS-15634 + The FQDN of a VM that is deployed as a part of both a shared network and + default isolated guest network has the suffix of the shared network instead of the + default isolated guest network. + + + + CS-15576 + Stopping a VM on XenServer creates a backlog of API commands. For + example, the Attach volume calls become delayed while waiting for the + stopVirtualMachine command to be executed. + + + + CS-15569 + Misleading error message in the exception when creating a StaticNAT rule + fails in a VPC. + + + + CS-15566 + External device such as Netscaler is not supported in VPC. + + + CS-15557 + Intermittent traffic loss in the VPN connection if Juniper is the remote + router and the life time is 300 seconds. + + + + CS-15361 + Egress rules are not working in NetScaler loadbalancer. + + + + CS-15163 + The minimum limit is not honored when there is not enough capacity to + deploy all the VMs and the ec2-run-instances command with the -n >n1 -n2> + option is used to deploy multiple VMs. + + + CS-15105 + The cloud-sysvmadm script does not work if the integration.api.port + parameter is set to any port other than 8096. + + + CS-15092 + Connecting to the guest VMs through SSH is extremely slow, and it results + in connection timeout. + + + CS-15037 + Hairpin NAT is not supported when NetScaler is used for + EIP. + + + CS-15009 + The port_profile table will not be populated with port profile + information. In this release, CloudStack directly connects to the VSM for all the + port profile operations; therefore, no port profile information is + cached. + + + CS-14939 + Adding a VMware cluster is not supported when the Management Network is + migrated to the Distributed Virtual Switch environment. + + + CS-14780 + You are allowed to ping the elastic IP address of the VM even though no + ingress rule is set that allows the ICMP protocol. + + + CS-14756 + Installing KVM on RHEL 6.2 will result in unreliable network performance. + Workaround: blacklist vhost-net. Edit /etc/modprobe.d/blacklist-kvm.conf and + include vhost-net. + + + CS-14346 + The UpdateVirtualMachine API call does not check whether the VM is + stopped. Therefore, stop the VM manually before issuing this call. + + + CS-14303 (was 14537) + The IP addresses for a shared network are still being consumed even if no + services are defined for that network. + + + CS-14296 (was 14530) + OVM: Network traffic labels are not supported. + + + CS-14291 (was 14523) + The EIP/ELB network offering for basic zones does not support multiple + NetScalers. + + + CS-14275 (was 14506) + F5: Unable to properly remove a F5 device. + + + CS-14201 (was 14430) + VMWare: Template sizes are being reported different depending on whether + the primary storage is using ISCSI or NFS. + + + CS-13758 (was 13963) + vSphere: template download from templates created off of the root volume + does not work properly. + + + CS-13733 (was 13935) + vSphere: detaching an ISO from a restored VM instance + fails. + + + CS-13682 (was 13883) + Multiple NetScalers are not supported in Basic Networking. + + + CS-13599 (was 13359) + Programming F5/NetScaler rules can be better optimized. + + + CS-13337 (was 13518) + Security Groups are not supported in Advanced Networking + + + CS-13173 (was 13336) + vSphere: cross cluster volume migration does not work + properly. + + + CS-12714 (was 12840) + Capacity view is not available for pods or clusters. + + + CS-12624 (was 12741) + vSphere: maintenance mode will not live migrate system VM to another + host. + + + + CS-15476 + + + The 2.2.14 to 4.0.0-incubating upgrade fails if multiple untagged physical + networks exist before the upgrade. + + + + + CS-15407 + + + After the 2.2.14 to 4.0.0-incubating upgrade, VLAN allocation on multiple + physical networks does not happen as expected. + To workaround this issue, follow the instructions given below: + + + Revert to your 2.2.14 setup. + + + Stop all the VMs with the isolated virtual networks in your cloud + setup. + + + Run following query to find if any networks still have the NICs + allocated: + + + Check if any virtual guest networks have the NICs allocated: + #SELECT DISTINCT op.id from `cloud`.`op_networks` op JOIN `cloud`.`networks` n on op.id=n.id WHERE nics_count != 0 AND guest_type = 'Virtual'; + + + If this returns any network IDs, then ensure the following: + + + All the VMs are stopped. + + + No new VM is started. + + + Shutdown the Management Server. + + + + + Remove the NICs count for the virtual network IDs returned in step + (a), and set the NIC count to 0: + UPDATE `cloud`.`op_networks` SET nics_count = 0 WHERE id = enter id of virtual network + + + Restart the Management Server, and wait for all the networks to shut + down. + + Networks shutdown is determined by the network.gc.interval and + network.gc.wait parameters. + + + + + + Ensure that all the networks are shut down and all the guest VNETs are + free. + + + Run the upgrade script. + This allocates all your guest VNET ranges to the first physical + network. + + + By using the updatePhysicalNetwork API, reconfigure the VNET ranges for + each physical network as desired. + + + Start all the VMs. + + + + + + + CS-14680 + + + CloudStack and LDAP user validation cannot happen simultaneously because the + user password is hashed and stored in the database, and LDAP requires the + passwords in plain text. + To work with the LDAP user, the MD5 hash should be disabled in the login + process by commenting the following variable in sharedFunctions.js file available + at /usr/share/cloud/management/webapps/client/scripts, and restart the + cloud-management service. + var md5HashedLogin = false; + However, if md5HashedLogin is set to false, the end user can login with the + LDAP credentials but not with the CloudStack user credentials. + + + + CS-14346 + The UpdateVirtualMachine API call does not check whether the VM is + stopped. Therefore, stop the VM manually before issuing this call. + + + CS-15130 + Data disk volumes are not automatically copied from one cluster to + another. + + + CS-14780 + You are allowed to ping the elastic IP address of the VM even though no + ingress rule is set that allows the ICMP protocol. + + + CS-14939 + Adding a VMware cluster is not supported when the Management Network is + migrated to the Distributed Virtual Switch environment. + + + CS-15009 + The port_profile table will not be populated with port profile + information. In this release, CloudStack directly connects to the VSM for all the + port profile operations; therefore, no port profile information is + cached. + + + CS-15037 + Hairpin NAT is not supported when NetScaler is used for + EIP. + + + CS-15092 + Connecting to the guest VMs through SSH is extremely slow, and it results + in connection timeout. + + + CS-15105 + The cloud-sysvmadm script does not work if the integration.api.port + parameter is set to any port other than 8096. + + + CS-15163 + The minimum limit is not honored when there is not enough capacity to + deploy all the VMs and the ec2-run-instances command with the -n >n1 -n2> + option is used to deploy multiple VMs. + + + + +
+
+ + API Changes from 3.0.2 to 4.0.0-incubating +
+ New API Commands in 4.0.0-incubating + + + createCounter (Adds metric counter) + + + deleteCounter (Deletes a counter) + + + listCounters (List the counters) + + + createCondition (Creates a condition) + + + deleteCondition (Removes a condition) + + + listConditions (List Conditions for the specific user) + + + createTags. Add tags to one or more resources. Example: + command=createTags +&resourceIds=1,10,12 +&resourceType=userVm +&tags[0].key=region +&tags[0].value=canada +&tags[1].key=city +&tags[1].value=Toronto + + + deleteTags. Remove tags from one or more resources. Example: + command=deleteTags +&resourceIds=1,12 +&resourceType=Snapshot +&tags[0].key=city + + + listTags (Show currently defined resource tags) + + + createVPC (Creates a VPC) + + + listVPCs (Lists VPCs) + + + deleteVPC (Deletes a VPC) + + + updateVPC (Updates a VPC) + + + restartVPC (Restarts a VPC) + + + createVPCOffering (Creates VPC offering) + + + updateVPCOffering (Updates VPC offering) + + + deleteVPCOffering (Deletes VPC offering) + + + listVPCOfferings (Lists VPC offerings) + + + createPrivateGateway (Creates a private gateway) + + + listPrivateGateways (List private gateways) + + + deletePrivateGateway (Deletes a Private gateway) + + + createNetworkACL (Creates a ACL rule the given network (the network has to belong to + VPC)) + + + deleteNetworkACL (Deletes a Network ACL) + + + listNetworkACLs (Lists all network ACLs) + + + createStaticRoute (Creates a static route) + + + deleteStaticRoute (Deletes a static route) + + + listStaticRoutes (Lists all static routes) + + + createVpnCustomerGateway (Creates site to site vpn customer gateway) + + + createVpnGateway (Creates site to site vpn local gateway) + + + createVpnConnection (Create site to site vpn connection) + + + deleteVpnCustomerGateway (Delete site to site vpn customer gateway) + + + deleteVpnGateway (Delete site to site vpn gateway) + + + deleteVpnConnection (Delete site to site vpn connection) + + + updateVpnCustomerGateway (Update site to site vpn customer gateway) + + + resetVpnConnection (Reset site to site vpn connection) + + + listVpnCustomerGateways (Lists site to site vpn customer gateways) + + + listVpnGateways (Lists site 2 site vpn gateways) + + + listVpnConnections (Lists site to site vpn connection gateways) + + + markDefaultZoneForAccount (Marks a default zone for the current account) + + + uploadVolume (Uploads a data disk) + + +
+
+ Changed API Commands in 4.0.0-incubating + + + + + + + API Commands + Description + + + + + + copyTemplate + prepareTemplate + registerTemplate + updateTemplate + createProject + activateProject + suspendProject + updateProject + listProjectAccounts + createVolume + migrateVolume + attachVolume + detachVolume + uploadVolume + createSecurityGroup + registerIso + copyIso + updateIso + createIpForwardingRule + listIpForwardingRules + createLoadBalancerRule + updateLoadBalancerRule + createSnapshot + + + The commands in this list have a single new response parameter, and no other + changes. + New response parameter: tags(*) + + Many other commands also have the new tags(*) parameter in addition to other + changes; those commands are listed separately. + + + + + rebootVirtualMachine + attachIso + detachIso + listLoadBalancerRuleInstances + resetPasswordForVirtualMachine + changeServiceForVirtualMachine + recoverVirtualMachine + startVirtualMachine + migrateVirtualMachine + deployVirtualMachine + assignVirtualMachine + updateVirtualMachine + restoreVirtualMachine + stopVirtualMachine + destroyVirtualMachine + + + The commands in this list have two new response parameters, and no other + changes. + New response parameters: keypair, tags(*) + + + + + listSecurityGroups + listFirewallRules + listPortForwardingRules + listSnapshots + listIsos + listProjects + listTemplates + listLoadBalancerRules + + The commands in this list have the following new parameters, and no other + changes. + New request parameter: tags (optional) + New response parameter: tags(*) + + + + + listF5LoadBalancerNetworks + listNetscalerLoadBalancerNetworks + listSrxFirewallNetworks + updateNetwork + + + The commands in this list have three new response parameters, and no other + changes. + New response parameters: canusefordeploy, vpcid, tags(*) + + + + + createZone + updateZone + + The commands in this list have the following new parameters, and no other + changes. + New request parameter: localstorageenabled (optional) + New response parameter: localstorageenabled + + + + listZones + New response parameter: localstorageenabled + + + + rebootRouter + changeServiceForRouter + startRouter + destroyRouter + stopRouter + + The commands in this list have two new response parameters, and no other + changes. + New response parameters: vpcid, nic(*) + + + + updateAccount + disableAccount + listAccounts + markDefaultZoneForAccount + enableAccount + + The commands in this list have three new response parameters, and no + other changes. + New response parameters: vpcavailable, vpclimit, vpctotal + + + listRouters + + New request parameters: forvpc (optional), vpcid (optional) + New response parameters: vpcid, nic(*) + + + + listNetworkOfferings + + New request parameters: forvpc (optional) + New response parameters: forvpc + + + + listVolumes + + New request parameters: details (optional), tags (optional) + New response parameters: tags(*) + + + + addTrafficMonitor + + New request parameters: excludezones (optional), includezones + (optional) + + + + createNetwork + + New request parameters: vpcid (optional) + New response parameters: canusefordeploy, vpcid, tags(*) + + + + listPublicIpAddresses + + New request parameters: tags (optional), vpcid (optional) + New response parameters: vpcid, tags(*) + + + + listNetworks + + New request parameters: canusefordeploy (optional), forvpc (optional), tags + (optional), vpcid (optional) + New response parameters: canusefordeploy, vpcid, tags(*) + + + + restartNetwork + + New response parameters: vpcid, tags(*) + + + + enableStaticNat + + New request parameter: networkid (optional) + + + + createDiskOffering + + New request parameter: storagetype (optional) + New response parameter: storagetype + + + + listDiskOfferings + + New response parameter: storagetype + + + + updateDiskOffering + + New response parameter: storagetype + + + + createFirewallRule + + Changed request parameters: ipaddressid (old version - optional, new version - + required) + New response parameter: tags(*) + + + + listVirtualMachines + + New request parameters: isoid (optional), tags (optional), templateid + (optional) + New response parameters: keypair, tags(*) + + + + updateStorageNetworkIpRange + + New response parameters: id, endip, gateway, netmask, networkid, podid, + startip, vlan, zoneid + + + + reconnectHost + A new response parameter is added: hahost. + + + addCluster + The following request parameters are added: + + + vsmipaddress (optional) + + + vsmpassword (optional) + + + vsmusername (optional) + + + The following parameter is made mandatory: podid + + + + listVolumes + A new response parameter is added: status + + + migrateVolume + A new response parameter is added: status + + + prepareHostForMaintenance + A new response parameter is added: hahost. + + + addSecondaryStorage + A new response parameter is added: hahost. + + + enableAccount + A new response parameter is added: defaultzoneid + + + attachVolume + A new response parameter is added: status + + + cancelHostMaintenance + A new response parameter is added: hahost + + + addSwift + A new response parameter is added: hahost + + + listSwifts + A new response parameter is added: hahost + + + listExternalLoadBalancers + A new response parameter is added: hahost + + + createVolume + A new response parameter is added: status + + + listCapabilities + A new response parameter is added: + customdiskofferingmaxsize + + + disableAccount + A new response parameter is added: defaultzoneid + + + deployVirtualMachine + A new request parameter is added: startvm (optional) + + + deleteStoragePool + A new request parameter is added: forced (optional) + + + updateAccount + A new response parameter is added: defaultzoneid + + + addHost + A new response parameter is added: hahost + + + updateHost + A new response parameter is added: hahost + + + detachVolume + A new response parameter is added: status + + + listAccounts + A new response parameter is added: defaultzoneid + + + listHosts + A new response parameter is added: hahostA new request + parameter is added: hahost (optional) + + + + +
+
+
diff --git a/docs/en-US/Revision_History_Install_Guide.xml b/docs/en-US/Revision_History_Install_Guide.xml new file mode 100644 index 00000000000..ee8dd31325a --- /dev/null +++ b/docs/en-US/Revision_History_Install_Guide.xml @@ -0,0 +1,55 @@ + + +%BOOK_ENTITIES; +]> + + + + + Revision History + + + + 1-0 + October 5 2012 + + Jessica + Tomechak + + + + Radhika + PC + + + + Wido + den Hollander + + + + + Initial publication + + + + + + diff --git a/docs/en-US/about-clusters.xml b/docs/en-US/about-clusters.xml index e328cbaa169..745ad89d118 100644 --- a/docs/en-US/about-clusters.xml +++ b/docs/en-US/about-clusters.xml @@ -24,9 +24,25 @@
About Clusters - A cluster provides a way to group hosts. To be precise, a cluster is a XenServer server pool, a set of KVM servers, a set of OVM hosts, or a VMware cluster preconfigured in vCenter. The hosts in a cluster all have identical hardware, run the same hypervisor, are on the same subnet, and access the same shared primary storage. Virtual machine instances (VMs) can be live-migrated from one host to another within the same cluster, without interrupting service to the user. - A cluster is the third-largest organizational unit within a &PRODUCT; deployment. Clusters are contained within pods, and pods are contained within zones. Size of the cluster is limited by the underlying hypervisor, although the &PRODUCT; recommends less in most cases; see Best Practices. - A cluster consists of one or more hosts and one or more primary storage servers. + + A cluster provides a way to group hosts. To be precise, a cluster is a + XenServer server pool, a set of KVM servers, , or a + VMware cluster preconfigured in vCenter. The hosts in a cluster all + have identical hardware, run the same hypervisor, are on the same subnet, + and access the same shared primary storage. Virtual machine instances + (VMs) can be live-migrated from one host to another within the same + cluster, without interrupting service to the user. + + + A cluster is the third-largest organizational unit within a &PRODUCT; + deployment. Clusters are contained within pods, and pods are contained + within zones. Size of the cluster is limited by the underlying hypervisor, + although the &PRODUCT; recommends less in most cases; see Best Practices. + + + A cluster consists of one or more hosts and one or more primary storage + servers. + @@ -34,6 +50,14 @@ cluster-overview.png: Structure of a simple cluster &PRODUCT; allows multiple clusters in a cloud deployment. - Even when local storage is used, clusters are still required. In this case, there is just one host per cluster. - When VMware is used, every VMware cluster is managed by a vCenter server. Administrator must register the vCenter server with &PRODUCT;. There may be multiple vCenter servers per zone. Each vCenter server may manage multiple VMware clusters. + + Even when local storage is used exclusively, clusters are still required + organizationally, even if there is just one host per cluster. + + + When VMware is used, every VMware cluster is managed by a vCenter server. + Administrator must register the vCenter server with &PRODUCT;. There may + be multiple vCenter servers per zone. Each vCenter server may manage + multiple VMware clusters. +
diff --git a/docs/en-US/about-hosts.xml b/docs/en-US/about-hosts.xml index 956c695a520..49694b25647 100644 --- a/docs/en-US/about-hosts.xml +++ b/docs/en-US/about-hosts.xml @@ -28,7 +28,8 @@ The host is the smallest organizational unit within a &PRODUCT; deployment. Hosts are contained within clusters, clusters are contained within pods, and pods are contained within zones. Hosts in a &PRODUCT; deployment: - Provde the CPU, memory, storage, and networking resources needed to host the virtual machines + Provide the CPU, memory, storage, and networking resources needed to host the virtual + machines Interconnect using a high bandwidth TCP/IP network and connect to the Internet May reside in multiple data centers across different geographic locations May have different capacities (different CPU speeds, different amounts of RAM, etc.), although the hosts within a cluster must all be homogeneous diff --git a/docs/en-US/about-security-groups.xml b/docs/en-US/about-security-groups.xml new file mode 100644 index 00000000000..85e8477cfb1 --- /dev/null +++ b/docs/en-US/about-security-groups.xml @@ -0,0 +1,35 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ About Security Groups + Security groups provide a way to isolate traffic to VMs. A security group is a group of VMs that filter their incoming and outgoing traffic according to a set of rules, called ingress and egress rules. These rules filter network traffic according to the IP address that is attempting to communicate with the VM. Security groups are particularly useful in zones that use basic networking, because there is a single guest network for all guest VMs. In &PRODUCT; 3.0.3 - 3.0.5, security groups are supported only in zones that use basic networking. + In a zone that uses advanced networking, you can instead define multiple guest networks to isolate traffic to VMs. + + + Each &PRODUCT; account comes with a default security group that denies all inbound traffic and allows all outbound traffic. The default security group can be modified so that all new VMs inherit some other desired set of rules. + Any &PRODUCT; user can set up any number of additional security groups. When a new VM is launched, it is assigned to the default security group unless another user-defined security group is specified. A VM can be a member of any number of security groups. Once a VM is assigned to a security group, it remains in that group for its entire lifetime; you can not move a running VM from one security group to another. + You can modify a security group by deleting or adding any number of ingress and egress rules. When you do, the new rules apply to all VMs in the group, whether running or stopped. + If no ingress rules are specified, then no traffic will be allowed in, except for responses to any traffic that has been allowed out through an egress rule. +
diff --git a/docs/en-US/about-virtual-networks.xml b/docs/en-US/about-virtual-networks.xml index 2fc6ba9ddd5..2797423d24d 100644 --- a/docs/en-US/about-virtual-networks.xml +++ b/docs/en-US/about-virtual-networks.xml @@ -24,8 +24,8 @@
About Virtual Networks - A virtual network is a logical construct that enables multi-tenancy on a single physical network. In &PRODUCT;, a virtual network can be shared or isolated. - XenServer and Maintenance Mode - Working with Usage - XenServer and Maintenance Mode -
+ A virtual network is a logical construct that enables multi-tenancy on a single physical network. In &PRODUCT; a virtual network can be shared or isolated. + + + + diff --git a/docs/en-US/accounts.xml b/docs/en-US/accounts.xml index 5292a9ca2f6..e5056866801 100644 --- a/docs/en-US/accounts.xml +++ b/docs/en-US/accounts.xml @@ -22,7 +22,8 @@ under the License. --> -
+ + Accounts -
+ diff --git a/docs/en-US/acquire-new-ip-for-vpc.xml b/docs/en-US/acquire-new-ip-for-vpc.xml new file mode 100644 index 00000000000..785e80bb874 --- /dev/null +++ b/docs/en-US/acquire-new-ip-for-vpc.xml @@ -0,0 +1,73 @@ + + +%BOOK_ENTITIES; +]> + +
+ Acquiring a New IP Address for a VPC + When you acquire an IP address, all IP addresses are allocated to VPC, not to the guest + networks within the VPC. The IPs are associated to the guest network only when the first + port-forwarding, load balancing, or Static NAT rule is created for the IP or the network. IP + can't be associated to more than one network at a time. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to deploy the VMs. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Select IP Addresses. + The IP Addresses page is displayed. + + + Click Acquire New IP, and click Yes in the confirmation dialog. + You are prompted for confirmation because, typically, IP addresses are a limited + resource. Within a few moments, the new IP address should appear with the state Allocated. + You can now use the IP address in port forwarding, load balancing, and static NAT + rules. + + +
\ No newline at end of file diff --git a/docs/en-US/add-additional-guest-network.xml b/docs/en-US/add-additional-guest-network.xml index 57e7ffd57a8..c684da023da 100644 --- a/docs/en-US/add-additional-guest-network.xml +++ b/docs/en-US/add-additional-guest-network.xml @@ -3,41 +3,63 @@ %BOOK_ENTITIES; ]> - -
- Adding an Additional Guest Network - - Log in to the &PRODUCT; UI as an administrator or end user. - In the left navigation, choose Network - Click Add guest network. Provide the following information: - - Name. The name of the network. This will be user-visible. - Description. The description of the network. This will be user-visible. - Network offering. If the administrator has configured multiple network offerings, select the one you want to use for this network. - Pod. The name of the pod this network applies to. Each pod in a basic zone is a broadcast domain, and therefore each pod has a different IP range for the guest network. The administrator must configure the IP range for each pod. - VLAN ID. The VLAN tag for this network. - Gateway. The gateway that the guests should use. - Netmask. The netmask in use on the subnet the guests will use. - Start IP/End IP. Enter the first and last IP addresses that define a range that &PRODUCT; can assign to guests. We strongly recommend the use of multiple NICs. If multiple NICs are used, they may be in a different subnet. If one NIC is used, these IPs should be in the same CIDR as the pod CIDR. - Click Create. - - -
+ Adding an Additional Guest Network + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + Click Add guest network. Provide the following information: + + + Name: The name of the network. This will be + user-visible. + + + Display Text: The description of the network. This + will be user-visible. + + + Zone. The name of the zone this network applies to. + Each zone is a broadcast domain, and therefore each zone has a different IP range for + the guest network. The administrator must configure the IP range for each zone. + + + Network offering: If the administrator has + configured multiple network offerings, select the one you want to use for this + network. + + + Guest Gateway: The gateway that the guests should + use. + + + Guest Netmask: The netmask in use on the subnet the + guests will use. + + + + + Click Create. + + + diff --git a/docs/en-US/add-clusters-kvm-xenserver.xml b/docs/en-US/add-clusters-kvm-xenserver.xml new file mode 100644 index 00000000000..ad5737191fd --- /dev/null +++ b/docs/en-US/add-clusters-kvm-xenserver.xml @@ -0,0 +1,53 @@ + + +%BOOK_ENTITIES; +]> + +
+ Add Cluster: KVM or XenServer + These steps assume you have already installed the hypervisor on the hosts and logged in to + the &PRODUCT; UI. + + + In the left navigation, choose Infrastructure. In Zones, click View More, then click the + zone in which you want to add the cluster. + + + Click the Compute tab. + + + In the Clusters node of the diagram, click View All. + + + Click Add Cluster. + + + Choose the hypervisor type for this cluster. + + + Choose the pod in which you want to create the cluster. + + + Enter a name for the cluster. This can be text of your choosing and is not used by + &PRODUCT;. + + + Click OK. + + +
diff --git a/docs/en-US/add-clusters-ovm.xml b/docs/en-US/add-clusters-ovm.xml new file mode 100644 index 00000000000..11e1a13555f --- /dev/null +++ b/docs/en-US/add-clusters-ovm.xml @@ -0,0 +1,43 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Add Cluster: OVM + To add a Cluster of hosts that run Oracle VM (OVM): + + Add a companion non-OVM cluster to the Pod. This cluster provides an environment where the CloudPlatform System VMs can run. You should have already installed a non-OVM hypervisor on at least one Host to prepare for this step. Depending on which hypervisor you used: + + For VMWare, follow the steps in Add Cluster: vSphere. When finished, return here and continue with the next step. + For KVM or XenServer, follow the steps in . When finished, return here and continue with the next step + + + In the left navigation, choose Infrastructure. In Zones, click View More, then click the zone in which you want to add the cluster. + Click the Compute tab. In the Pods node, click View All. Select the same pod you used in step 1. + Click View Clusters, then click Add Cluster. + The Add Cluster dialog is displayed. + In Hypervisor, choose OVM. + In Cluster, enter a name for the cluster. + Click Add. + +
diff --git a/docs/en-US/add-clusters-vsphere.xml b/docs/en-US/add-clusters-vsphere.xml new file mode 100644 index 00000000000..6b2dff2a595 --- /dev/null +++ b/docs/en-US/add-clusters-vsphere.xml @@ -0,0 +1,110 @@ + + +%BOOK_ENTITIES; +]> + +
+ Add Cluster: vSphere + Host management for vSphere is done through a combination of vCenter and the &PRODUCT; admin + UI. &PRODUCT; requires that all hosts be in a &PRODUCT; cluster, but the cluster may consist of + a single host. As an administrator you must decide if you would like to use clusters of one host + or of multiple hosts. Clusters of multiple hosts allow for features like live migration. + Clusters also require shared storage such as NFS or iSCSI. + For vSphere servers, we recommend creating the cluster of hosts in vCenter and then adding + the entire cluster to &PRODUCT;. Follow these requirements: + + + Do not put more than 8 hosts in a vSphere cluster + + + Make sure the hypervisor hosts do not have any VMs already running before you add them + to &PRODUCT;. + + + To add a vSphere cluster to &PRODUCT;: + + + Create the cluster of hosts in vCenter. Follow the vCenter instructions to do this. You + will create a cluster that looks something like this in vCenter. + + + + + + vsphereclient.png: vSphere client + + + + + Log in to the UI. + + + In the left navigation, choose Infrastructure. In Zones, click View More, then click the + zone in which you want to add the cluster. + + + Click the Compute tab, and click View All on Pods. Choose the pod to which you want to + add the cluster. + + + Click View Clusters. + + + Click Add Cluster. + + + In Hypervisor, choose VMware. + + + Provide the following information in the dialog. The fields below make reference to + values from vCenter. + + + Cluster Name. Enter the name of the cluster you created in vCenter. For example, + "cloud.cluster.2.2.1" + + + vCenter Host. Enter the hostname or IP address of the vCenter server. + + + vCenter Username. Enter the username that &PRODUCT; should use to connect to + vCenter. This user must have all administrative privileges. + + + vCenter Password. Enter the password for the user named above + + + vCenter Datacenter. Enter the vCenter datacenter that the cluster is in. For + example, "cloud.dc.VM". + + + + + + + + addcluster.png: add cluster + + + There might be a slight delay while the cluster is provisioned. It will + automatically display in the UI + + + + +
diff --git a/docs/en-US/add-gateway-vpc.xml b/docs/en-US/add-gateway-vpc.xml new file mode 100644 index 00000000000..616794a51d1 --- /dev/null +++ b/docs/en-US/add-gateway-vpc.xml @@ -0,0 +1,104 @@ + + +%BOOK_ENTITIES; +]> + +
+ Adding a Private Gateway to a VPC + A private gateway can be added by the root admin only. The VPC private network has 1:1 + relationship with the NIC of the physical network. No gateways with duplicated VLAN and IP are + allowed in the same data center. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to configure load balancing + rules. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Private Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Select Private Gateways. + The Gateways page is displayed. + + + Click Add new gateway: + + + + + + add-new-gateway-vpc.png: adding a private gateway for the VPC. + + + + + Specify the following: + + + Physical Network: The physical network you have + created in the zone. + + + IP Address: The IP address associated with the VPC + gateway. + + + Gateway: The gateway through which the traffic is + routed to and from the VPC. + + + Netmask: The netmask associated with the VPC + gateway. + + + VLAN: The VLAN associated with the VPC + gateway. + + + The new gateway appears in the list. You can repeat these steps to add more gateway for + this VPC. + + +
diff --git a/docs/en-US/add-ingress-egress-rules.xml b/docs/en-US/add-ingress-egress-rules.xml index 964045f4076..2490cec43cc 100644 --- a/docs/en-US/add-ingress-egress-rules.xml +++ b/docs/en-US/add-ingress-egress-rules.xml @@ -3,57 +3,129 @@ %BOOK_ENTITIES; ]> - -
- Adding Ingress and Egress Rules to a Security Group - - Log in to the &PRODUCT; UI as an administrator or end user. - In the left navigation, choose Network - In Select view, choose Security Groups, then click the security group you want . - To add an ingress rule, click the Ingress Rules tab and fill out the following fields to specify what network traffic is allowed into VM instances in this security group. If no ingress rules are specified, then no traffic will be allowed in, except for responses to any traffic that has been allowed out through an egress rule. - - Add by CIDR/Account. Indicate whether the source of the traffic will be defined by IP address (CIDR) or an existing security group in a &PRODUCT; account (Account). Choose Account if you want to allow incoming traffic from all VMs in another security group - Protocol. The networking protocol that sources will use to send traffic to the security group. TCP and UDP are typically used for data exchange and end-user communications. ICMP is typically used to send error messages or network monitoring data. - Start Port, End Port. (TCP, UDP only) A range of listening ports that are the destination for the incoming traffic. If you are opening a single port, use the same number in both fields. - ICMP Type, ICMP Code. (ICMP only) The type of message and error code that will be accepted. - CIDR. (Add by CIDR only) To accept only traffic from IP addresses within a particular address block, enter a CIDR or a comma-separated list of CIDRs. The CIDR is the base IP address of the incoming traffic. For example, 192.168.0.0/22. To allow all CIDRs, set to 0.0.0.0/0. - Account, Security Group. (Add by Account only) To accept only traffic from another security group, enter the &PRODUCT; account and name of a security group that has already been defined in that account. To allow traffic between VMs within the security group you are editing now, enter the same name you used in step 7. - - The following example allows inbound HTTP access from anywhere: - - - - - httpaccess.png: allows inbound HTTP access from anywhere - + Adding Ingress and Egress Rules to a Security Group + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network + + + In Select view, choose Security Groups, then click the security group you want . + + + To add an ingress rule, click the Ingress Rules tab and fill out the following fields to + specify what network traffic is allowed into VM instances in this security group. If no + ingress rules are specified, then no traffic will be allowed in, except for responses to any + traffic that has been allowed out through an egress rule. + + + Add by CIDR/Account. Indicate whether the source of + the traffic will be defined by IP address (CIDR) or an existing security group in a + &PRODUCT; account (Account). Choose Account if you want to allow incoming traffic from + all VMs in another security group - To add an egress rule, click the Egress Rules tab and fill out the following fields to specify what type of traffic is allowed to be sent out of VM instances in this security group. If no egress rules are specified, then all traffic will be allowed out. Once egress rules are specified, the following types of traffic are allowed out: traffic specified in egress rules; queries to DNS and DHCP servers; and responses to any traffic that has been allowed in through an ingress rule - - Add by CIDR/Account. Indicate whether the destination of the traffic will be defined by IP address (CIDR) or an existing security group in a &PRODUCT; account (Account). Choose Account if you want to allow outgoing traffic to all VMs in another security group. - Protocol. The networking protocol that VMs will use to send outgoing traffic. TCP and UDP are typically used for data exchange and end-user communications. ICMP is typically used to send error messages or network monitoring data. - Start Port, End Port. (TCP, UDP only) A range of listening ports that are the destination for the outgoing traffic. If you are opening a single port, use the same number in both fields. - ICMP Type, ICMP Code. (ICMP only) The type of message and error code that will be sent - CIDR. (Add by CIDR only) To send traffic only to IP addresses within a particular address block, enter a CIDR or a comma-separated list of CIDRs. The CIDR is the base IP address of the destination. For example, 192.168.0.0/22. To allow all CIDRs, set to 0.0.0.0/0. - Account, Security Group. (Add by Account only) To allow traffic to be sent to another security group, enter the &PRODUCT; account and name of a security group that has already been defined in that account. To allow traffic between VMs within the security group you are editing now, enter its name. - - Click Add. - + + Protocol. The networking protocol that sources will + use to send traffic to the security group. TCP and UDP are typically used for data + exchange and end-user communications. ICMP is typically used to send error messages or + network monitoring data. + + + Start Port, End Port. (TCP, UDP only) A range of + listening ports that are the destination for the incoming traffic. If you are opening a + single port, use the same number in both fields. + + + ICMP Type, ICMP Code. (ICMP only) The type of + message and error code that will be accepted. + + + CIDR. (Add by CIDR only) To accept only traffic + from IP addresses within a particular address block, enter a CIDR or a comma-separated + list of CIDRs. The CIDR is the base IP address of the incoming traffic. For example, + 192.168.0.0/22. To allow all CIDRs, set to 0.0.0.0/0. + + + Account, Security Group. (Add by Account only) To + accept only traffic from another security group, enter the &PRODUCT; account and name of + a security group that has already been defined in that account. To allow traffic between + VMs within the security group you are editing now, enter the same name you used in step + 7. + + + The following example allows inbound HTTP access from anywhere: + + + + + + httpaccess.png: allows inbound HTTP access from anywhere + + + + + To add an egress rule, click the Egress Rules tab and fill out the following fields to + specify what type of traffic is allowed to be sent out of VM instances in this security + group. If no egress rules are specified, then all traffic will be allowed out. Once egress + rules are specified, the following types of traffic are allowed out: traffic specified in + egress rules; queries to DNS and DHCP servers; and responses to any traffic that has been + allowed in through an ingress rule + + + Add by CIDR/Account. Indicate whether the + destination of the traffic will be defined by IP address (CIDR) or an existing security + group in a &PRODUCT; account (Account). Choose Account if you want to allow outgoing + traffic to all VMs in another security group. + + + Protocol. The networking protocol that VMs will use + to send outgoing traffic. TCP and UDP are typically used for data exchange and end-user + communications. ICMP is typically used to send error messages or network monitoring + data. + + + Start Port, End Port. (TCP, UDP only) A range of + listening ports that are the destination for the outgoing traffic. If you are opening a + single port, use the same number in both fields. + + + ICMP Type, ICMP Code. (ICMP only) The type of + message and error code that will be sent + + + CIDR. (Add by CIDR only) To send traffic only to IP + addresses within a particular address block, enter a CIDR or a comma-separated list of + CIDRs. The CIDR is the base IP address of the destination. For example, 192.168.0.0/22. + To allow all CIDRs, set to 0.0.0.0/0. + + + Account, Security Group. (Add by Account only) To + allow traffic to be sent to another security group, enter the &PRODUCT; account and name + of a security group that has already been defined in that account. To allow traffic + between VMs within the security group you are editing now, enter its name. + + + + + Click Add. + +
diff --git a/docs/en-US/add-iso.xml b/docs/en-US/add-iso.xml index f56d10cb0f5..25986e02e92 100644 --- a/docs/en-US/add-iso.xml +++ b/docs/en-US/add-iso.xml @@ -3,89 +3,149 @@ %BOOK_ENTITIES; ]> - -
- Adding an ISO - To make additional operating system or other software available for use with guest VMs, you can add an ISO. The ISO is typically thought of as an operating system image, but you can also add ISOs for other types of software, such as desktop applications that you want to be installed as part of a template. - - Log in to the &PRODUCT; UI as an administrator or end user. - In the left navigation bar, click Templates. - In Select View, choose ISOs. - Click Add ISO. - In the Add ISO screen, provide the following: - - Name. Short name for the ISO image. (E.g. CentOS 6.2 64 bit). - Description. Display test for the ISO image. (E.g. CentOS 6.2 64 bit). - URL. The URL that hosts the ISO image. The Management Server must be able to access this location via HTTP. If needed you can place the ISO image directly on the Management Server - Zone. Choose the zone where you want the ISO to be available, or All Zones to make it available throughout &PRODUCT;. - Bootable. Whether or not a guest could boot off this ISO image. For example, a CentOS ISO is bootable, a Microsoft Office ISO is not bootable. - OS Type. This helps &PRODUCT; and the hypervisor perform certain operations and make assumptions that improve the performance of the guest. Select one of the following. - - If the operating system of your desired ISO image is listed, choose it. - If the OS Type of the ISO is not listed or if the ISO is not bootable, choose Other. - (XenServer only) If you want to boot from this ISO in PV mode, choose Other PV (32-bit) or Other PV (64-bit) - (KVM only) If you choose an OS that is PV-enabled, the VMs created from this ISO will have a SCSI (virtio) root disk. If the OS is not PV-enabled, the VMs will have an IDE root disk. The PV-enabled types are: - - - - - Fedora 13 - Fedora 12 - Fedora 11 - - - - Fedora 10 - Fedora 9 - Other PV - - - - Debian GNU/Linux - CentOS 5.3 - CentOS 5.4 - - - CentOS 5.5 - Red Hat Enterprise Linux 5.3 - Red Hat Enterprise Linux 5.4 - - - Red Hat Enterprise Linux 5.5 - Red Hat Enterprise Linux 6 - - - - - - - Note: It is not recommended to choose an older version of the OS than the version in the image. For example, choosing CentOS 5.4 to support a CentOS 6.2 image will usually not work. In these cases, choose Other. - - Extractable. Choose Yes if the ISO should be available for extraction. - Public. Choose Yes if this ISO should be available to other users. - Featured. Choose Yes if you would like this ISO to be more prominent for users to select. The ISO will appear in the Featured ISOs list. Only an administrator can make an ISO Featured. - - Click OK. - The Management Server will download the ISO. Depending on the size of the ISO, this may take a long time. The ISO status column will display Ready once it has been successfully downloaded into secondary storage. Clicking Refresh updates the download percentage. + Adding an ISO + To make additional operating system or other software available for use with guest VMs, you + can add an ISO. The ISO is typically thought of as an operating system image, but you can also + add ISOs for other types of software, such as desktop applications that you want to be installed + as part of a template. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation bar, click Templates. + + + In Select View, choose ISOs. + + + Click Add ISO. + + + In the Add ISO screen, provide the following: + + + Name: Short name for the ISO image. For example, + CentOS 6.2 64-bit. - Important: Wait for the ISO to finish downloading. If you move on to the next task and try to use the ISO right away, it will appear to fail. The entire ISO must be available before &PRODUCT; can work with it - + + Description: Display test for the ISO image. For + example, CentOS 6.2 64-bit. + + + URL: The URL that hosts the ISO image. The + Management Server must be able to access this location via HTTP. If needed you can place + the ISO image directly on the Management Server + + + Zone: Choose the zone where you want the ISO to be + available, or All Zones to make it available throughout &PRODUCT;. + + + Bootable: Whether or not a guest could boot off + this ISO image. For example, a CentOS ISO is bootable, a Microsoft Office ISO is not + bootable. + + + OS Type: This helps &PRODUCT; and the hypervisor + perform certain operations and make assumptions that improve the performance of the + guest. Select one of the following. + + + If the operating system of your desired ISO image is listed, choose it. + + + If the OS Type of the ISO is not listed or if the ISO is not bootable, choose + Other. + + + (XenServer only) If you want to boot from this ISO in PV mode, choose Other PV + (32-bit) or Other PV (64-bit) + + + (KVM only) If you choose an OS that is PV-enabled, the VMs created from this ISO + will have a SCSI (virtio) root disk. If the OS is not PV-enabled, the VMs will have + an IDE root disk. The PV-enabled types are: + + + + + Fedora 13 + Fedora 12 + Fedora 11 + + + Fedora 10 + Fedora 9 + Other PV + + + Debian GNU/Linux + CentOS 5.3 + CentOS 5.4 + + + CentOS 5.5 + Red Hat Enterprise Linux 5.3 + Red Hat Enterprise Linux 5.4 + + + Red Hat Enterprise Linux 5.5 + Red Hat Enterprise Linux 6 + + + + + + + + + It is not recommended to choose an older version of the OS than the version in the + image. For example, choosing CentOS 5.4 to support a CentOS 6.2 image will usually not + work. In these cases, choose Other. + + + + Extractable: Choose Yes if the ISO should be + available for extraction. + + + Public: Choose Yes if this ISO should be available + to other users. + + + Featured: Choose Yes if you would like this ISO to + be more prominent for users to select. The ISO will appear in the Featured ISOs list. + Only an administrator can make an ISO Featured. + + + + + Click OK. + The Management Server will download the ISO. Depending on the size of the ISO, this may + take a long time. The ISO status column will display Ready once it has been successfully + downloaded into secondary storage. Clicking Refresh updates the download percentage. + + + Important: Wait for the ISO to finish downloading. If + you move on to the next task and try to use the ISO right away, it will appear to fail. The + entire ISO must be available before &PRODUCT; can work with it. + +
diff --git a/docs/en-US/add-load-balancer-rule.xml b/docs/en-US/add-load-balancer-rule.xml index ddbce957926..8cd0da4b7da 100644 --- a/docs/en-US/add-load-balancer-rule.xml +++ b/docs/en-US/add-load-balancer-rule.xml @@ -3,44 +3,80 @@ %BOOK_ENTITIES; ]> - -
- Adding a Load Balancer Rule - - Log in to the &PRODUCT; UI as an administrator or end user. - In the left navigation, choose Network. - Click the name of the network where you want to load balance the traffic. - Click View IP Addresses. - Click the IP address for which you want to create the rule, then click the Configuration tab. - In the Load Balancing node of the diagram, click View All. - Fill in the following: - - Name. A name for the load balancer rule. - Public Port. The port receiving incoming traffic to be balanced. - Private Port. The port that the VMs will use to receive the traffic. - Algorithm. Choose the load balancing algorithm you want &PRODUCT; to use. &PRODUCT; supports a variety of well-known algorithms. If you are not familiar with these choices, you will find plenty of information about them on the Internet. - Stickiness. (Optional) Click Configure and choose the algorithm for the stickiness policy. See Sticky Session Policies for Load Balancer Rules. - - Click Add VMs, then select two or more VMs that will divide the load of incoming traffic, and click Apply. - The new load balancer rule appears in the list. You can repeat these steps to add more load balancer rules for this IP address. - - + Adding a Load Balancer Rule + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + Click the name of the network where you want to load balance the traffic. + + + Click View IP Addresses. + + + Click the IP address for which you want to create the rule, then click the Configuration + tab. + + + In the Load Balancing node of the diagram, click View All. + In a Basic zone, you can also create a load balancing rule without acquiring or + selecting an IP address. &PRODUCT; internally assign an IP when you create the load + balancing rule, which is listed in the IP Addresses page when the rule is created. + To do that, select the name of the network, then click Add Load Balancer tab. Continue + with . + + + Fill in the following: + + + Name: A name for the load balancer rule. + + + Public Port: The port receiving incoming traffic to + be balanced. + + + Private Port: The port that the VMs will use to + receive the traffic. + + + Algorithm: Choose the load balancing algorithm you + want &PRODUCT; to use. &PRODUCT; supports a variety of well-known algorithms. If you are + not familiar with these choices, you will find plenty of information about them on the + Internet. + + + Stickiness: (Optional) Click Configure and choose + the algorithm for the stickiness policy. See Sticky Session Policies for Load Balancer + Rules. + + + + + Click Add VMs, then select two or more VMs that will divide the load of incoming + traffic, and click Apply. + The new load balancer rule appears in the list. You can repeat these steps to add more + load balancer rules for this IP address. + +
diff --git a/docs/en-US/add-loadbalancer-rule-vpc.xml b/docs/en-US/add-loadbalancer-rule-vpc.xml new file mode 100644 index 00000000000..bba3e5ad134 --- /dev/null +++ b/docs/en-US/add-loadbalancer-rule-vpc.xml @@ -0,0 +1,123 @@ + + +%BOOK_ENTITIES; +]> + + +
+ Adding Load Balancing Rules on a VPC + A &PRODUCT; user or administrator may create load balancing rules that balance traffic + received at a public IP to one or more VMs that belong to a network tier that provides load + balancing service in a VPC. A user creates a rule, specifies an algorithm, and assigns the rule + to a set of VMs within a VPC. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to configure load balancing + rules. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Select IP Addresses. + The IP Addresses page is displayed. + + + Click the IP address for which you want to create the rule, then click the Configuration + tab. + + + In the Load Balancing node of the diagram, click View All. + + + Select the tier to which you want to apply the rule. + + In a VPC, the load balancing service is supported only on a single tier. + + + + Specify the following: + + + Name: A name for the load balancer rule. + + + Public Port: The port that receives the incoming + traffic to be balanced. + + + Private Port: The port that the VMs will use to + receive the traffic. + + + Algorithm. Choose the load balancing algorithm you + want &PRODUCT; to use. &PRODUCT; supports the following well-known algorithms: + + + Round-robin + + + Least connections + + + Source + + + + + Stickiness. (Optional) Click Configure and choose + the algorithm for the stickiness policy. See Sticky Session Policies for Load Balancer + Rules. + + + Add VMs: Click Add VMs, then select two or more VMs + that will divide the load of incoming traffic, and click Apply. + + + + + The new load balancing rule appears in the list. You can repeat these steps to add more load + balancing rules for this IP address. +
\ No newline at end of file diff --git a/docs/en-US/add-members-to-projects.xml b/docs/en-US/add-members-to-projects.xml index a51726e14fc..39c3edfb2c3 100644 --- a/docs/en-US/add-members-to-projects.xml +++ b/docs/en-US/add-members-to-projects.xml @@ -29,5 +29,7 @@ If invitations have been enabled, you can send invitations to new members. If invitations are not enabled, you can add members directly through the UI.
+ + diff --git a/docs/en-US/add-more-clusters.xml b/docs/en-US/add-more-clusters.xml new file mode 100644 index 00000000000..894b4d80737 --- /dev/null +++ b/docs/en-US/add-more-clusters.xml @@ -0,0 +1,29 @@ + + +%BOOK_ENTITIES; +]> + +
+ Add More Clusters (Optional) + You need to tell &PRODUCT; about the hosts that it will manage. Hosts exist inside clusters, + so before you begin adding hosts to the cloud, you must add at least one cluster. + + + + +
diff --git a/docs/en-US/add-portforward-rule-vpc.xml b/docs/en-US/add-portforward-rule-vpc.xml new file mode 100644 index 00000000000..c3dbc39bb19 --- /dev/null +++ b/docs/en-US/add-portforward-rule-vpc.xml @@ -0,0 +1,103 @@ + + +%BOOK_ENTITIES; +]> + +
+ Adding a Port Forwarding Rule on a VPC + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to deploy the VMs. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Choose an existing IP address or acquire a new IP address. Click the name of the IP + address in the list. + The IP Addresses page is displayed. + + + Click the IP address for which you want to create the rule, then click the Configuration + tab. + + + In the Port Forwarding node of the diagram, click View All. + + + Select the tier to which you want to apply the rule. + + + Specify the following: + + + Public Port: The port to which public traffic will + be addressed on the IP address you acquired in the previous step. + + + Private Port: The port on which the instance is + listening for forwarded public traffic. + + + Protocol: The communication protocol in use between + the two ports. + + + TCP + + + UDP + + + + + Add VM: Click Add VM. Select the name of the + instance to which this rule applies, and click Apply. + You can test the rule by opening an ssh session to the instance. + + + + +
diff --git a/docs/en-US/add-primary-storage.xml b/docs/en-US/add-primary-storage.xml new file mode 100644 index 00000000000..a43567f5562 --- /dev/null +++ b/docs/en-US/add-primary-storage.xml @@ -0,0 +1,108 @@ + + +%BOOK_ENTITIES; +]> + +
+ Adding Primary Storage + + Ensure that nothing stored on the server. Adding the server to CloudStack will destroy any + existing data. + + When you create a new zone, the first primary storage is added as part of that procedure. + You can add primary storage servers at any time, such as when adding a new cluster or adding + more servers to an existing cluster. + + + Log in to the &PRODUCT; UI. + + + In the left navigation, choose Infrastructure. In Zones, click View More, then click the + zone in which you want to add the primary storage. + + + Click the Compute tab. + + + In the Primary Storage node of the diagram, click View All. + + + Click Add Primary Storage. + + + Provide the following information in the dialog. The information required varies + depending on your choice in Protocol. + + + Pod. The pod for the storage device. + + + Cluster. The cluster for the storage device. + + + Name. The name of the storage device + + + Protocol. For XenServer, choose either NFS, iSCSI, or PreSetup. For KVM, choose NFS + or SharedMountPoint. For vSphere choose either VMFS (iSCSI or FiberChannel) or + NFS + + + Server (for NFS, iSCSI, or PreSetup). The IP address or DNS name of the storage + device + + + Server (for VMFS). The IP address or DNS name of the vCenter server. + + + Path (for NFS). In NFS this is the exported path from the server. + + + Path (for VMFS). In vSphere this is a combination of the datacenter name and the + datastore name. The format is "/" datacenter name "/" datastore name. For example, + "/cloud.dc.VM/cluster1datastore". + + + Path (for SharedMountPoint). With KVM this is the path on each host that is where + this primary storage is mounted. For example, "/mnt/primary". + + + SR Name-Label (for PreSetup). Enter the name-label of the SR that has been set up + outside &PRODUCT;. + + + Target IQN (for iSCSI). In iSCSI this is the IQN of the target. For example, + iqn.1986-03.com.sun:02:01ec9bb549-1271378984 + + + Lun # (for iSCSI). In iSCSI this is the LUN number. For example, 3. + + + Tags (optional). The comma-separated list of tags for this storage device. It should + be an equivalent set or superset of the tags on your disk offerings. + + + The tag sets on primary storage across clusters in a Zone must be identical. For + example, if cluster A provides primary storage that has tags T1 and T2, all other clusters + in the Zone must also provide primary storage that has tags T1 and T2. + + + Click OK. + + +
diff --git a/docs/en-US/add-secondary-storage.xml b/docs/en-US/add-secondary-storage.xml new file mode 100644 index 00000000000..318a6ea79b6 --- /dev/null +++ b/docs/en-US/add-secondary-storage.xml @@ -0,0 +1,48 @@ + + +%BOOK_ENTITIES; +]> + +
+ Adding Secondary Storage + + Be sure there is nothing stored on the server. Adding the server to CloudStack will + destroy any existing data. + + When you create a new zone, the first secondary storage is added as part of that procedure. + You can add secondary storage servers at any time to add more servers to an existing + zone. + + + If you are going to use Swift for cloud-wide secondary storage, you must add the Swift + storage to &PRODUCT; before you add the local zone secondary storage servers. + + + To prepare for local zone secondary storage, you should have created and mounted an NFS + share during Management Server installation. + + + Make sure you prepared the system VM template during Management Server + installation. + + + 4. Now that the secondary storage server for per-zone storage is prepared, add it to + &PRODUCT;. Secondary storage is added as part of the procedure for adding a new zone. + + +
diff --git a/docs/en-US/add-security-group.xml b/docs/en-US/add-security-group.xml index e4c8b3ce2da..85a6ba0b38a 100644 --- a/docs/en-US/add-security-group.xml +++ b/docs/en-US/add-security-group.xml @@ -3,37 +3,47 @@ %BOOK_ENTITIES; ]> - -
- Adding a Security Group - A user or administrator can change the network offering that is associated with an existing guest network. - - Log in to the &PRODUCT; UI as an administrator or end user. - In the left navigation, choose Network - In Select view, choose Security Groups. - Click Add Security Group. - Provide a name and description. - Click OK. - The new security group appears in the Security Groups Details tab. - To make the security group useful, continue to Adding Ingress and Egress Rules to a Security Group. - + Adding a Security Group + A user or administrator can define a new security group. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network + + + In Select view, choose Security Groups. + + + Click Add Security Group. + + + Provide a name and description. + + + Click OK. + The new security group appears in the Security Groups Details tab. + + + To make the security group useful, continue to Adding Ingress and Egress Rules to a + Security Group. + +
- diff --git a/docs/en-US/add-tier.xml b/docs/en-US/add-tier.xml new file mode 100644 index 00000000000..6beaab2a151 --- /dev/null +++ b/docs/en-US/add-tier.xml @@ -0,0 +1,89 @@ + + +%BOOK_ENTITIES; +]> + +
+ Adding Tiers + Tiers are distinct locations within a VPC that act as isolated networks, which do not have + access to other tiers by default. Tiers are set up on different VLANs that can communicate with + each other by using a virtual router. Tiers provide inexpensive, low latency network + connectivity to other tiers within the VPC. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPC that you have created for the account is listed in the page. + + The end users can see their own VPCs, while root and domain admin can see any VPC they + are authorized to see. + + + + Click the Configure button of the VPC for which you want to set up tiers. + The Add new tier dialog is displayed, as follows: + + + + + + add-tier.png: adding a tier to a vpc. + + + If you have already created tiers, the VPC diagram is displayed. Click Create Tier to + add a new tier. + + + Specify the following: + All the fields are mandatory. + + + Name: A unique name for the tier you create. + + + Network Offering: The following default network + offerings are listed: DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, + DefaultIsolatedNetworkOfferingForVpcNetworks + In a VPC, only one tier can be created by using LB-enabled network offering. + + + Gateway: The gateway for the tier you create. + Ensure that the gateway is within the Super CIDR range that you specified while creating + the VPC, and is not overlapped with the CIDR of any existing tier within the VPC. + + + Netmask: The netmask for the tier you create. + For example, if the VPC CIDR is 10.0.0.0/16 and the network tier CIDR is + 10.0.1.0/24, the gateway of the tier is 10.0.1.1, and the netmask of the tier is + 255.255.255.0. + + + + + Click OK. + + + Continue with configuring access control list for the tier. + + +
diff --git a/docs/en-US/add-vm-to-tier.xml b/docs/en-US/add-vm-to-tier.xml new file mode 100644 index 00000000000..e401eed2656 --- /dev/null +++ b/docs/en-US/add-vm-to-tier.xml @@ -0,0 +1,45 @@ + + +%BOOK_ENTITIES; +]> + +
+ Deploying VMs to the Tier + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to deploy the VMs. + The VPC page is displayed where all the tiers you created are listed. + + + Click the Add VM button of the tier for which you want to add a VM. + The Add Instance page is displayed. + Follow the on-screen instruction to add an instance. For information on adding an + instance, see Adding Instances section in the Installation Guide. + + +
diff --git a/docs/en-US/add-vpc.xml b/docs/en-US/add-vpc.xml new file mode 100644 index 00000000000..8c088a0e1fd --- /dev/null +++ b/docs/en-US/add-vpc.xml @@ -0,0 +1,75 @@ + + +%BOOK_ENTITIES; +]> + +
+ Adding a Virtual Private Cloud + When creating the VPC, you simply provide the zone and a set of IP addresses for the VPC + network address space. You specify this set of addresses in the form of a Classless Inter-Domain + Routing (CIDR) block. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + + + Click Add VPC. The Add VPC page is displayed as follows: + + + + + + add-vpc.png: adding a vpc. + + + Provide the following information: + + + Name: A short name for the VPC that you are + creating. + + + Description: A brief description of the VPC. + + + Zone: Choose the zone where you want the VPC to be + available. + + + Super CIDR for Guest Networks: Defines the CIDR + range for all the tiers (guest networks) within a VPC. When you create a tier, ensure + that its CIDR is within the Super CIDR value you enter. The CIDR must be RFC1918 + compliant. + + + DNS domain for Guest Networks: If you want to + assign a special domain name, specify the DNS suffix. This parameter is applied to all + the tiers within the VPC. That implies, all the tiers you create in the VPC belong to + the same DNS domain. If the parameter is not specified, a DNS domain name is generated + automatically. + + + + +
diff --git a/docs/en-US/added-API-commands-4.0.xml b/docs/en-US/added-API-commands-4.0.xml new file mode 100644 index 00000000000..2d86ba4d6dc --- /dev/null +++ b/docs/en-US/added-API-commands-4.0.xml @@ -0,0 +1,164 @@ + + +%BOOK_ENTITIES; +]> + +
+ Added API Commands in 4.0.0-incubating + + + createCounter (Adds metric counter) + + + deleteCounter (Deletes a counter) + + + listCounters (List the counters) + + + createCondition (Creates a condition) + + + deleteCondition (Removes a condition) + + + listConditions (List Conditions for the specific user) + + + createTags. Add tags to one or more resources. Example: + command=createTags +&resourceIds=1,10,12 +&resourceType=userVm +&tags[0].key=region +&tags[0].value=canada +&tags[1].key=city +&tags[1].value=Toronto + + + deleteTags. Remove tags from one or more resources. Example: + command=deleteTags +&resourceIds=1,12 +&resourceType=Snapshot +&tags[0].key=city + + + listTags (Show currently defined resource tags) + + + createVPC (Creates a VPC) + + + listVPCs (Lists VPCs) + + + deleteVPC (Deletes a VPC) + + + updateVPC (Updates a VPC) + + + restartVPC (Restarts a VPC) + + + createVPCOffering (Creates VPC offering) + + + updateVPCOffering (Updates VPC offering) + + + deleteVPCOffering (Deletes VPC offering) + + + listVPCOfferings (Lists VPC offerings) + + + createPrivateGateway (Creates a private gateway) + + + listPrivateGateways (List private gateways) + + + deletePrivateGateway (Deletes a Private gateway) + + + createNetworkACL (Creates a ACL rule the given network (the network has to belong to + VPC)) + + + deleteNetworkACL (Deletes a Network ACL) + + + listNetworkACLs (Lists all network ACLs) + + + createStaticRoute (Creates a static route) + + + deleteStaticRoute (Deletes a static route) + + + listStaticRoutes (Lists all static routes) + + + createVpnCustomerGateway (Creates site to site vpn customer gateway) + + + createVpnGateway (Creates site to site vpn local gateway) + + + createVpnConnection (Create site to site vpn connection) + + + deleteVpnCustomerGateway (Delete site to site vpn customer gateway) + + + deleteVpnGateway (Delete site to site vpn gateway) + + + deleteVpnConnection (Delete site to site vpn connection) + + + updateVpnCustomerGateway (Update site to site vpn customer gateway) + + + resetVpnConnection (Reset site to site vpn connection) + + + listVpnCustomerGateways (Lists site to site vpn customer gateways) + + + listVpnGateways (Lists site 2 site vpn gateways) + + + listVpnConnections (Lists site to site vpn connection gateways) + + + enableCiscoNexusVSM (Enables Nexus 1000v dvSwitch in &PRODUCT;.) + + + disableCiscoNexusVSM (Disables Nexus 1000v dvSwitch in &PRODUCT;.) + + + deleteCiscoNexusVSM (Deletes Nexus 1000v dvSwitch in &PRODUCT;.) + + + listCiscoNexusVSMs (Lists the control VLAN ID, packet VLAN ID, and data VLAN ID, as well + as the IP address of the Nexus 1000v dvSwitch.) + + +
diff --git a/docs/en-US/added-API-commands.xml b/docs/en-US/added-API-commands.xml index b63895e7973..208aac29dc2 100644 --- a/docs/en-US/added-API-commands.xml +++ b/docs/en-US/added-API-commands.xml @@ -3,165 +3,193 @@ %BOOK_ENTITIES; ]> - - - -
- Added API commands - Added in 3.0.3: - - enableCiscoNexusVSM (Enables Nexus 1000v dvSwitch in &PRODUCT;.) - disableCiscoNexusVSM (Disables Nexus 1000v dvSwitch in &PRODUCT;.) - deleteCiscoNexusVSM (Deletes Nexus 1000v dvSwitch in &PRODUCT;.) - listCiscoNexusVSMs (Lists the control VLAN ID, packet VLAN ID, and data VLAN ID, as well as the IP address of the Nexus 1000v dvSwitch.) - - Added in 3.0.2: - - changeServiceForSystemVm - Changes the service offering for a system VM (console proxy or secondary storage). The system VM must be in a "Stopped" state for this command to take effect. - - - Added in 3.0.1: - - changeServiceForSystemVm - Changes the service offering for a system VM (console proxy or secondary storage). The system VM must be in a "Stopped" state for this command to take effect. - - - Added in 3.0.0: - - - - - - - - assignVirtualMachine (Move a user VM to another user under same domain.) - restoreVirtualMachine (Restore a VM to original template or specific snapshot) - createLBStickinessPolicy (Creates a Load Balancer stickiness policy ) - - - deleteLBStickinessPolicy (Deletes a LB stickiness policy.) - listLBStickinessPolicies (Lists LBStickiness policies.) - ldapConfig (Configure the LDAP context for this site.) - - - addSwift (Adds Swift.) - listSwifts (List Swift.) - migrateVolume (Migrate volume) - - - updateStoragePool (Updates a storage pool.) - authorizeSecurityGroupEgress (Authorizes a particular egress rule for this security group) - revokeSecurityGroupEgress (Deletes a particular egress rule from this security group) - - - createNetworkOffering (Creates a network offering.) - deleteNetworkOffering (Deletes a network offering.) - createProject (Creates a project) - - - deleteProject (Deletes a project) - updateProject (Updates a project) - activateProject (Activates a project) - - - suspendProject (Suspends a project) - listProjects (Lists projects and provides detailed information for listed projects) - addAccountToProject (Adds acoount to a project) - - - deleteAccountFromProject (Deletes account from the project) - listProjectAccounts (Lists project's accounts) - listProjectInvitations (Lists an account's invitations to join projects) - - - updateProjectInvitation (Accepts or declines project invitation) - deleteProjectInvitation (Deletes a project invitation) - updateHypervisorCapabilities (Updates a hypervisor capabilities.) - - - listHypervisorCapabilities (Lists all hypervisor capabilities.) - createPhysicalNetwork (Creates a physical network) - deletePhysicalNetwork (Deletes a Physical Network.) - - - listPhysicalNetworks (Lists physical networks) - updatePhysicalNetwork (Updates a physical network) - listSupportedNetworkServices (Lists all network services provided by &PRODUCT; or for the given Provider.) - - - addNetworkServiceProvider (Adds a network serviceProvider to a physical network) - deleteNetworkServiceProvider (Deletes a Network Service Provider.) - listNetworkServiceProviders (Lists network serviceproviders for a given physical network.) - - - updateNetworkServiceProvider (Updates a network serviceProvider of a physical network) - addTrafficType (Adds traffic type to a physical network) - deleteTrafficType (Deletes traffic type of a physical network) - - - listTrafficTypes (Lists traffic types of a given physical network.) - updateTrafficType (Updates traffic type of a physical network) - listTrafficTypeImplementors (Lists implementors of implementor of a network traffic type or implementors of all network traffic types) - - - createStorageNetworkIpRange (Creates a Storage network IP range.) - deleteStorageNetworkIpRange (Deletes a storage network IP Range.) - listStorageNetworkIpRange (List a storage network IP range.) - - - updateStorageNetworkIpRange (Update a Storage network IP range, only allowed when no IPs in this range have been allocated.) - listUsageTypes (List Usage Types) - addF5LoadBalancer (Adds a F5 BigIP load balancer device) - - - configureF5LoadBalancer (configures a F5 load balancer device) - deleteF5LoadBalancer ( delete a F5 load balancer device) - listF5LoadBalancers (lists F5 load balancer devices) - - - listF5LoadBalancerNetworks (lists network that are using a F5 load balancer device) - addSrxFirewall (Adds a SRX firewall device) - deleteSrxFirewall ( delete a SRX firewall device) - - - listSrxFirewalls (lists SRX firewall devices in a physical network) - listSrxFirewallNetworks (lists network that are using SRX firewall device) - addNetscalerLoadBalancer (Adds a netscaler load balancer device) - - - deleteNetscalerLoadBalancer ( delete a netscaler load balancer device) - configureNetscalerLoadBalancer (configures a netscaler load balancer device) - listNetscalerLoadBalancers (lists netscaler load balancer devices) - - - listNetscalerLoadBalancerNetworks (lists network that are using a netscaler load balancer device) - createVirtualRouterElement (Create a virtual router element.) - configureVirtualRouterElement (Configures a virtual router element.) - - - listVirtualRouterElements (Lists all available virtual router elements.) - - - - - - -
+
+ Added API commands in 3.0 +
+ Added in 3.0.2 + + + changeServiceForSystemVm + Changes the service offering for a system VM (console proxy or secondary storage). The + system VM must be in a "Stopped" state for this command to take effect. + + +
+
+ Added in 3.0.1 + + + changeServiceForSystemVm + Changes the service offering for a system VM (console proxy or secondary storage). The + system VM must be in a "Stopped" state for this command to take effect. + + +
+
+ Added in 3.0.0 + + + + + + + + assignVirtualMachine (Move a user VM to another user under same + domain.) + restoreVirtualMachine (Restore a VM to original template or specific + snapshot) + createLBStickinessPolicy (Creates a Load Balancer stickiness policy + ) + + + deleteLBStickinessPolicy (Deletes a LB stickiness policy.) + listLBStickinessPolicies (Lists LBStickiness policies.) + ldapConfig (Configure the LDAP context for this site.) + + + addSwift (Adds Swift.) + listSwifts (List Swift.) + migrateVolume (Migrate volume) + + + updateStoragePool (Updates a storage pool.) + authorizeSecurityGroupEgress (Authorizes a particular egress rule for this + security group) + revokeSecurityGroupEgress (Deletes a particular egress rule from this + security group) + + + createNetworkOffering (Creates a network offering.) + deleteNetworkOffering (Deletes a network offering.) + createProject (Creates a project) + + + deleteProject (Deletes a project) + updateProject (Updates a project) + activateProject (Activates a project) + + + suspendProject (Suspends a project) + listProjects (Lists projects and provides detailed information for listed + projects) + addAccountToProject (Adds acoount to a project) + + + deleteAccountFromProject (Deletes account from the project) + listProjectAccounts (Lists project's accounts) + listProjectInvitations (Lists an account's invitations to join + projects) + + + updateProjectInvitation (Accepts or declines project + invitation) + deleteProjectInvitation (Deletes a project invitation) + updateHypervisorCapabilities (Updates a hypervisor + capabilities.) + + + listHypervisorCapabilities (Lists all hypervisor + capabilities.) + createPhysicalNetwork (Creates a physical network) + deletePhysicalNetwork (Deletes a Physical Network.) + + + listPhysicalNetworks (Lists physical networks) + updatePhysicalNetwork (Updates a physical network) + listSupportedNetworkServices (Lists all network services provided by + &PRODUCT; or for the given Provider.) + + + addNetworkServiceProvider (Adds a network serviceProvider to a physical + network) + deleteNetworkServiceProvider (Deletes a Network Service + Provider.) + listNetworkServiceProviders (Lists network serviceproviders for a given + physical network.) + + + updateNetworkServiceProvider (Updates a network serviceProvider of a physical + network) + addTrafficType (Adds traffic type to a physical network) + deleteTrafficType (Deletes traffic type of a physical network) + + + listTrafficTypes (Lists traffic types of a given physical + network.) + updateTrafficType (Updates traffic type of a physical network) + listTrafficTypeImplementors (Lists implementors of implementor of a network + traffic type or implementors of all network traffic types) + + + createStorageNetworkIpRange (Creates a Storage network IP + range.) + deleteStorageNetworkIpRange (Deletes a storage network IP + Range.) + listStorageNetworkIpRange (List a storage network IP range.) + + + updateStorageNetworkIpRange (Update a Storage network IP range, only allowed + when no IPs in this range have been allocated.) + listUsageTypes (List Usage Types) + addF5LoadBalancer (Adds a F5 BigIP load balancer device) + + + configureF5LoadBalancer (configures a F5 load balancer device) + deleteF5LoadBalancer ( delete a F5 load balancer device) + listF5LoadBalancers (lists F5 load balancer devices) + + + listF5LoadBalancerNetworks (lists network that are using a F5 load balancer + device) + addSrxFirewall (Adds a SRX firewall device) + deleteSrxFirewall ( delete a SRX firewall device) + + + listSrxFirewalls (lists SRX firewall devices in a physical + network) + listSrxFirewallNetworks (lists network that are using SRX firewall + device) + addNetscalerLoadBalancer (Adds a netscaler load balancer + device) + + + deleteNetscalerLoadBalancer ( delete a netscaler load balancer + device) + configureNetscalerLoadBalancer (configures a netscaler load balancer + device) + listNetscalerLoadBalancers (lists netscaler load balancer + devices) + + + listNetscalerLoadBalancerNetworks (lists network that are using a netscaler + load balancer device) + createVirtualRouterElement (Create a virtual router element.) + configureVirtualRouterElement (Configures a virtual router + element.) + + + listVirtualRouterElements (Lists all available virtual router + elements.) + + + + + + +
+
diff --git a/docs/en-US/added-cloudPlatform-error-codes.xml b/docs/en-US/added-error-codes.xml similarity index 99% rename from docs/en-US/added-cloudPlatform-error-codes.xml rename to docs/en-US/added-error-codes.xml index 6b1e6a355ca..4436bf381e0 100644 --- a/docs/en-US/added-cloudPlatform-error-codes.xml +++ b/docs/en-US/added-error-codes.xml @@ -22,7 +22,7 @@ under the License. --> -
+
Added &PRODUCT; Error Codes You can now find the &PRODUCT;-specific error code in the exception response for each type of exception. The following list of error codes is added to the new class named CSExceptionErrorCode. These codes are applicable in &PRODUCT; 3.0.3 and later versions. diff --git a/docs/en-US/advanced-zone-configuration.xml b/docs/en-US/advanced-zone-configuration.xml index 85909e3a08b..03a082f21ac 100644 --- a/docs/en-US/advanced-zone-configuration.xml +++ b/docs/en-US/advanced-zone-configuration.xml @@ -1,182 +1,376 @@ - %BOOK_ENTITIES; ]> - -
- Advanced Zone Configuration - - After you select Advanced in the Add Zone wizard and click Next, you will be asked to enter the following details. Then click Next. - - Name. A name for the zone. - DNS 1 and 2. These are DNS servers for use by guest VMs in the zone. These DNS servers will be accessed via the public network you will add later. The public IP addresses for the zone must have a route to the DNS server named here. - Internal DNS 1 and Internal DNS 2. These are DNS servers for use by system VMs in the zone(these are VMs used by &PRODUCT; itself, such as virtual routers, console proxies,and Secondary Storage VMs.) These DNS servers will be accessed via the management traffic network interface of the System VMs. The private IP address you provide for the pods must have a route to the internal DNS server named here. - Network Domain. (Optional) If you want to assign a special domain name to the guest VM network, specify the DNS suffix. - Guest CIDR. This is the CIDR that describes the IP addresses in use in the guest virtual networks in this zone. For example, 10.1.1.0/24. As a matter of good practice you should set different CIDRs for different zones. This will make it easier to set up VPNs between networks in different zones. - Hypervisor. (Introduced in version 3.0.1) Choose the hypervisor for the first cluster in the zone. You can add clusters with different hypervisors later, after you finish adding the zone. - Public. A public zone is available to all users. A zone that is not public will be assigned to a particular domain. Only users in that domain will be allowed to create guest VMs in this zone. - - - Choose which traffic types will be carried by the physical network. - The traffic types are management, public, guest, and storage traffic. For more information about the types, roll over the icons to display their tool tips, or see . This screen starts out with one network already configured. If you have multiple physical networks, you need to add more. Drag and drop traffic types onto a greyed-out network and it will become active. You can move the traffic icons from one network to another; for example, if the default traffic types shown for Network 1 do not match your actual setup, you can move them down. You can also change the network names if desired. - - (Introduced in version 3.0.1) Assign a network traffic label to each traffic type on each physical network. These labels must match the labels you have already defined on the hypervisor host. To assign each label, click the Edit button under the traffic type icon within each physical network. A popup dialog appears where you can type the label, then click OK. - These traffic labels will be defined only for the hypervisor selected for the first cluster. For all other hypervisors, the labels can be configured after the zone is created. - (VMware only) If you have enabled Nexus dvSwitch in the environment, you must specify the corresponding Ethernet port profile names as network traffic label for each traffic type on the physical network. For more information on Nexus dvSwitch, see Configuring a vSphere Cluster with Nexus 1000v Virtual Switch. - - Click Next. - - Configure the IP range for public Internet traffic. Enter the following details, then click Add. If desired, you can repeat this step to add more public Internet IP ranges. When done, click Next. - - Gateway. The gateway in use for these IP addresses. - Netmask. The netmask associated with this IP range. - VLAN. The VLAN that will be used for public traffic. - Start IP/End IP. A range of IP addresses that are assumed to be accessible from the Internet and will be allocated for access to guest networks. - - - In a new zone, &PRODUCT; adds the first pod for you. You can always add more pods later. For an overview of what a pod is, see . - To configure the first pod, enter the following, then click Next: - - Pod Name. A name for the pod. - Reserved system gateway. The gateway for the hosts in that pod. - Reserved system netmask. The network prefix that defines the pod's subnet. Use CIDR notation. - Start/End Reserved System IP. The IP range in the management network that &PRODUCT; uses to manage various system VMs, such as Secondary Storage VMs, Console Proxy VMs, and DHCP. For more information, see . - - - Specify a range of VLAN IDs to carry guest traffic for each physical network (see VLAN Allocation Example ), then click Next. - - In a new pod, &PRODUCT; adds the first cluster for you. You can always add more clusters later. For an overview of what a cluster is, see . - To configure the first cluster, enter the following, then click Next: - - Hypervisor. (Version 3.0.0 only; in 3.0.1, this field is read only) Choose the type of hypervisor software that all hosts in this cluster will run. If you choose VMware, additional fields appear so you can give information about a vSphere cluster. For vSphere servers, we recommend creating the cluster of hosts in vCenter and then adding the entire cluster to &PRODUCT;. See Add Cluster: vSphere . - Cluster name. Enter a name for the cluster. This can be text of your choosing and is not used by &PRODUCT;. - - - In a new cluster, &PRODUCT; adds the first host for you. You can always add more hosts later. For an overview of what a host is, see . - When you deploy &PRODUCT;, the hypervisor host must not have any VMs already running. - Before you can configure the host, you need to install the hypervisor software on the host. You will need to know which version of the hypervisor software version is supported by &PRODUCT; and what additional configuration is required to ensure the host will work with &PRODUCT;. To find these installation details, see: - - Citrix XenServer Installation for &PRODUCT; - VMware vSphere Installation and Configuration - KVM Installation and Configuration - Oracle VM (OVM) Installation and Configuration - - To configure the first host, enter the following, then click Next: - - Host Name. The DNS name or IP address of the host. - Username. Usually root. - Password. This is the password for the user named above (from your XenServer or KVM install). - Host Tags. (Optional) Any labels that you use to categorize hosts for ease of maintenance. For example, you can set to the cloud's HA tag (set in the ha.tag global configuration parameter) if you want this host to be used only for VMs with the "high availability" feature enabled. For more information, see HA-Enabled Virtual Machines as well as HA for Hosts, both in the Administration Guide. - - - In a new cluster, &PRODUCT; adds the first primary storage server for you. You can always add more servers later. For an overview of what primary storage is, see . - To configure the first primary storage server, enter the following, then click Next: - - Name. The name of the storage device. - Protocol. For XenServer, choose either NFS, iSCSI, or PreSetup. For KVM, choose NFS or SharedMountPoint. For vSphere choose either VMFS (iSCSI or FiberChannel) or NFS. The remaining fields in the screen vary depending on what you choose here. - - - - - - - NFS - - - Server. The IP address or DNS name of the storage device. - Path. The exported path from the server. - - Tags (optional). The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings. - The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2. - - - - - - iSCSI - - - Server. The IP address or DNS name of the storage device. - Target IQN. The IQN of the target. For example, iqn.1986-03.com.sun:02:01ec9bb549-1271378984. - Lun. The LUN number. For example, 3. - - Tags (optional). The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings. - The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2. - - - - - - preSetup - - - Server. The IP address or DNS name of the storage device. - SR Name-Label. Enter the name-label of the SR that has been set up outside &PRODUCT;. - - Tags (optional). The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings. - The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2. - - - - - - SharedMountPoint - - - Path. The path on each host that is where this primary storage is mounted. For example, "/mnt/primary". - - Tags (optional). The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings. - The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2. - - - - - - VMFS - - - Server. The IP address or DNS name of the vCenter server. - Path. A combination of the datacenter name and the datastore name. The format is "/" datacenter name "/" datastore name. For example, "/cloud.dc.VM/cluster1datastore". - - Tags (optional). The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings. - The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2. - - - - - - - - - - - In a new zone, &PRODUCT; adds the first secondary storage server for you. For an overview of what secondary storage is, see . - Before you can fill out this screen, you need to prepare the secondary storage by setting up NFS shares and installing the latest &PRODUCT; System VM template. See Adding Secondary Storage : - - NFS Server. The IP address of the server. - Path. The exported path from the server. - - - Click Launch. - - + Advanced Zone Configuration + + + After you select Advanced in the Add Zone wizard and click Next, you will be asked to + enter the following details. Then click Next. + + + Name. A name for the zone. + + + DNS 1 and 2. These are DNS servers for use by guest + VMs in the zone. These DNS servers will be accessed via the public network you will add + later. The public IP addresses for the zone must have a route to the DNS server named + here. + + + Internal DNS 1 and Internal DNS 2. These are DNS + servers for use by system VMs in the zone(these are VMs used by &PRODUCT; itself, such + as virtual routers, console proxies,and Secondary Storage VMs.) These DNS servers will + be accessed via the management traffic network interface of the System VMs. The private + IP address you provide for the pods must have a route to the internal DNS server named + here. + + + Network Domain. (Optional) If you want to assign a + special domain name to the guest VM network, specify the DNS suffix. + + + Guest CIDR. This is the CIDR that describes the IP + addresses in use in the guest virtual networks in this zone. For example, 10.1.1.0/24. + As a matter of good practice you should set different CIDRs for different zones. This + will make it easier to set up VPNs between networks in different zones. + + + Hypervisor. (Introduced in version 3.0.1) Choose + the hypervisor for the first cluster in the zone. You can add clusters with different + hypervisors later, after you finish adding the zone. + + + Public. A public zone is available to all users. A + zone that is not public will be assigned to a particular domain. Only users in that + domain will be allowed to create guest VMs in this zone. + + + + + Choose which traffic types will be carried by the physical network. + The traffic types are management, public, guest, and storage traffic. For more + information about the types, roll over the icons to display their tool tips, or see . This screen starts out with one network + already configured. If you have multiple physical networks, you need to add more. Drag and + drop traffic types onto a greyed-out network and it will become active. You can move the + traffic icons from one network to another; for example, if the default traffic types shown + for Network 1 do not match your actual setup, you can move them down. You can also change + the network names if desired. + + + (Introduced in version 3.0.1) Assign a network traffic label to each traffic type on + each physical network. These labels must match the labels you have already defined on the + hypervisor host. To assign each label, click the Edit button under the traffic type icon + within each physical network. A popup dialog appears where you can type the label, then + click OK. + These traffic labels will be defined only for the hypervisor selected for the first + cluster. For all other hypervisors, the labels can be configured after the zone is + created. + + + Click Next. + + + Configure the IP range for public Internet traffic. Enter the following details, then + click Add. If desired, you can repeat this step to add more public Internet IP ranges. When + done, click Next. + + + Gateway. The gateway in use for these IP + addresses. + + + Netmask. The netmask associated with this IP + range. + + + VLAN. The VLAN that will be used for public + traffic. + + + Start IP/End IP. A range of IP addresses that are + assumed to be accessible from the Internet and will be allocated for access to guest + networks. + + + + + In a new zone, &PRODUCT; adds the first pod for you. You can always add more pods later. + For an overview of what a pod is, see . + To configure the first pod, enter the following, then click Next: + + + Pod Name. A name for the pod. + + + Reserved system gateway. The gateway for the hosts + in that pod. + + + Reserved system netmask. The network prefix that + defines the pod's subnet. Use CIDR notation. + + + Start/End Reserved System IP. The IP range in the + management network that &PRODUCT; uses to manage various system VMs, such as Secondary + Storage VMs, Console Proxy VMs, and DHCP. For more information, see . + + + + + Specify a range of VLAN IDs to carry guest traffic for each physical network (see VLAN + Allocation Example ), then click Next. + + + In a new pod, &PRODUCT; adds the first cluster for you. You can always add more clusters + later. For an overview of what a cluster is, see . + To configure the first cluster, enter the following, then click Next: + + + Hypervisor. (Version 3.0.0 only; in 3.0.1, this + field is read only) Choose the type of hypervisor software that all hosts in this + cluster will run. If you choose VMware, additional fields appear so you can give + information about a vSphere cluster. For vSphere servers, we recommend creating the + cluster of hosts in vCenter and then adding the entire cluster to &PRODUCT;. See Add + Cluster: vSphere . + + + Cluster name. Enter a name for the cluster. This + can be text of your choosing and is not used by &PRODUCT;. + + + + + In a new cluster, &PRODUCT; adds the first host for you. You can always add more hosts + later. For an overview of what a host is, see . + + When you deploy &PRODUCT;, the hypervisor host must not have any VMs already + running. + + Before you can configure the host, you need to install the hypervisor software on the + host. You will need to know which version of the hypervisor software version is supported by + &PRODUCT; and what additional configuration is required to ensure the host will work with + &PRODUCT;. To find these installation details, see: + + + Citrix XenServer Installation for &PRODUCT; + + + VMware vSphere Installation and Configuration + + + KVM Installation and Configuration + + + + To configure the first host, enter the following, then click Next: + + + Host Name. The DNS name or IP address of the + host. + + + Username. Usually root. + + + Password. This is the password for the user named + above (from your XenServer or KVM install). + + + Host Tags. (Optional) Any labels that you use to + categorize hosts for ease of maintenance. For example, you can set to the cloud's HA tag + (set in the ha.tag global configuration parameter) if you want this host to be used only + for VMs with the "high availability" feature enabled. For more information, see + HA-Enabled Virtual Machines as well as HA for Hosts, both in the Administration + Guide. + + + + + In a new cluster, &PRODUCT; adds the first primary storage server for you. You can + always add more servers later. For an overview of what primary storage is, see . + To configure the first primary storage server, enter the following, then click + Next: + + + Name. The name of the storage device. + + + Protocol. For XenServer, choose either NFS, iSCSI, + or PreSetup. For KVM, choose NFS, SharedMountPoint, CLVM, and RBD. For vSphere choose either VMFS + (iSCSI or FiberChannel) or NFS. The remaining fields in the screen vary depending on + what you choose here. + + + + + + + NFS + + + + Server. The IP address or DNS name of + the storage device. + + + Path. The exported path from the + server. + + + Tags (optional). The comma-separated + list of tags for this storage device. It should be an equivalent set or + superset of the tags on your disk offerings. + + + The tag sets on primary storage across clusters in a Zone must be + identical. For example, if cluster A provides primary storage that has tags T1 + and T2, all other clusters in the Zone must also provide primary storage that + has tags T1 and T2. + + + + iSCSI + + + + Server. The IP address or DNS name of + the storage device. + + + Target IQN. The IQN of the target. + For example, iqn.1986-03.com.sun:02:01ec9bb549-1271378984. + + + Lun. The LUN number. For example, + 3. + + + Tags (optional). The comma-separated + list of tags for this storage device. It should be an equivalent set or + superset of the tags on your disk offerings. + + + The tag sets on primary storage across clusters in a Zone must be + identical. For example, if cluster A provides primary storage that has tags T1 + and T2, all other clusters in the Zone must also provide primary storage that + has tags T1 and T2. + + + + preSetup + + + + Server. The IP address or DNS name of + the storage device. + + + SR Name-Label. Enter the name-label + of the SR that has been set up outside &PRODUCT;. + + + Tags (optional). The comma-separated + list of tags for this storage device. It should be an equivalent set or + superset of the tags on your disk offerings. + + + The tag sets on primary storage across clusters in a Zone must be + identical. For example, if cluster A provides primary storage that has tags T1 + and T2, all other clusters in the Zone must also provide primary storage that + has tags T1 and T2. + + + + SharedMountPoint + + + + Path. The path on each host that is + where this primary storage is mounted. For example, "/mnt/primary". + + + Tags (optional). The comma-separated + list of tags for this storage device. It should be an equivalent set or + superset of the tags on your disk offerings. + + + The tag sets on primary storage across clusters in a Zone must be + identical. For example, if cluster A provides primary storage that has tags T1 + and T2, all other clusters in the Zone must also provide primary storage that + has tags T1 and T2. + + + + VMFS + + + + Server. The IP address or DNS name of + the vCenter server. + + + Path. A combination of the datacenter + name and the datastore name. The format is "/" datacenter name "/" + datastore name. For example, "/cloud.dc.VM/cluster1datastore". + + + Tags (optional). The comma-separated + list of tags for this storage device. It should be an equivalent set or + superset of the tags on your disk offerings. + + + The tag sets on primary storage across clusters in a Zone must be + identical. For example, if cluster A provides primary storage that has tags T1 + and T2, all other clusters in the Zone must also provide primary storage that + has tags T1 and T2. + + + + + + + + + + In a new zone, &PRODUCT; adds the first secondary storage server for you. For an + overview of what secondary storage is, see . + Before you can fill out this screen, you need to prepare the secondary storage by + setting up NFS shares and installing the latest &PRODUCT; System VM template. See Adding + Secondary Storage : + + + NFS Server. The IP address of the server. + + + Path. The exported path from the server. + + + + + Click Launch. + +
diff --git a/docs/en-US/advanced-zone-physical-network-configuration.xml b/docs/en-US/advanced-zone-physical-network-configuration.xml index 4c44c7d4a42..2c3d9b3542a 100644 --- a/docs/en-US/advanced-zone-physical-network-configuration.xml +++ b/docs/en-US/advanced-zone-physical-network-configuration.xml @@ -3,26 +3,27 @@ %BOOK_ENTITIES; ]> - -
- Advanced Zone Physical Network Configuration - Within a zone that uses advanced networking, you need to tell the Management Server how the physical network is set up to carry different kinds of traffic in isolation. -
+ Advanced Zone Physical Network Configuration + Within a zone that uses advanced networking, you need to tell the Management Server how the + physical network is set up to carry different kinds of traffic in isolation. + + +
\ No newline at end of file diff --git a/docs/en-US/alerts.xml b/docs/en-US/alerts.xml index f9030238d43..b7f34d02a56 100644 --- a/docs/en-US/alerts.xml +++ b/docs/en-US/alerts.xml @@ -1,3 +1,8 @@ + + +%BOOK_ENTITIES; +]> -
- Alerts + + Alerts The following is the list of alert type numbers. The current alerts can be found by calling listAlerts. MEMORY = 0 CPU = 1 @@ -45,5 +50,4 @@ DIRECT_ATTACHED_PUBLIC_IP = 23; LOCAL_STORAGE = 24; RESOURCE_LIMIT_EXCEEDED = 25; //Generated when the resource limit exceeds the limit. Currently used for recurring snapshots only -
- + \ No newline at end of file diff --git a/docs/en-US/developer-guide.xml b/docs/en-US/api-calls.xml similarity index 71% rename from docs/en-US/developer-guide.xml rename to docs/en-US/api-calls.xml index c4bdf39d6fc..1fe6f02678b 100644 --- a/docs/en-US/developer-guide.xml +++ b/docs/en-US/api-calls.xml @@ -22,17 +22,11 @@ under the License. --> - - Using the API - - + + Calling the &PRODUCT; API - - - - diff --git a/docs/en-US/api-overview.xml b/docs/en-US/api-overview.xml new file mode 100644 index 00000000000..a541049e116 --- /dev/null +++ b/docs/en-US/api-overview.xml @@ -0,0 +1,38 @@ + + +%BOOK_ENTITIES; +]> + + + &PRODUCT; API + The &PRODUCT; API is a low level API that has been used to implement the &PRODUCT; web UIs. + It is also a good basis for implementing other popular APIs such as EC2/S3 and emerging DMTF + standards. + Many &PRODUCT; API calls are asynchronous. These will return a Job ID immediately when + called. This Job ID can be used to query the status of the job later. Also, status calls on + impacted resources will provide some indication of their state. + The API has a REST-like query basis and returns results in XML or JSON. + See the + Developer’s Guide and the API + Reference. + + + + diff --git a/docs/en-US/appendix-a-time-zones.xml b/docs/en-US/appendix-a-time-zones.xml deleted file mode 100644 index 595e7b5cbf5..00000000000 --- a/docs/en-US/appendix-a-time-zones.xml +++ /dev/null @@ -1,143 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - -
- Appendix A—Time Zones - The following time zone identifiers are accepted by &PRODUCT;. There are several places that have a time zone as a required or optional parameter. These include scheduling recurring snapshots, creating a user, and specifying the usage time zone in the Configuration table. - - - - - Etc/GMT+12 - America/La_Paz - Asia/Jerusalem - - - - Etc/GMT+11 - America/Santiago - Europe/Minsk - - - - Pacific/Samoa - America/St_Johns - Europe/Moscow - - - Pacific/Honolulu - America/Araguaina - Africa/Nairobi - - - US/Alaska - America/Los_Angeles - Mexico/BajaNorte - - - US/Arizona - US/Mountain - America/Chihuahua - - - - America/Chicago - America/Costa_Rica - America/Mexico_City - - - - Canada/Saskatchewan - America/Bogota - America/New_York - - - America/Caracas - America/Asuncion - America/Cuiaba - - - America/Halifax - America/Argentina/Buenos_Aires - America/Cayenne - - - America/Godthab - America/Montevideo - Etc/GMT+2 - - - - Atlantic/Azores - Atlantic/Cape_Verde - Africa/Casablanca - - - - Etc/UTC - Atlantic/Reykjavik - Europe/London - - - CET - Europe/Bucharest - Africa/Johannesburg - - - Asia/Beirut - Africa/Cairo - Asia/Karachi - - - Asia/Kolkata - Asia/Bangkok - Asia/Shanghai - - - Asia/Kuala_Lumpur - Australia/Perth - Asia/Taipei - - - - Asia/Tokyo - Asia/Seoul - Australia/Adelaide - - - - Australia/Darwin - Australia/Brisbane - Australia/Canberra - - - Pacific/Guam - Pacific/Auckland - - - - - - -
diff --git a/docs/en-US/attaching-volume.xml b/docs/en-US/attaching-volume.xml index 385609b8f57..360555eac06 100644 --- a/docs/en-US/attaching-volume.xml +++ b/docs/en-US/attaching-volume.xml @@ -37,7 +37,8 @@ In the Instance popup, choose the VM to which you want to attach the volume. You will only see instances to which you are allowed to attach volumes; for example, a user will see only instances created by that user, but the administrator will have more choices. - If the VM is running in the OVM hypervisor, the VM must be stopped before a new volume can be attached to it. + + When the volume has been attached, you should be able to see it by clicking Instances, the instance name, and View Volumes.
diff --git a/docs/en-US/automatic-snapshot-creation-retention.xml b/docs/en-US/automatic-snapshot-creation-retention.xml index ee4cf73f957..54fbe68e5bb 100644 --- a/docs/en-US/automatic-snapshot-creation-retention.xml +++ b/docs/en-US/automatic-snapshot-creation-retention.xml @@ -3,28 +3,34 @@ %BOOK_ENTITIES; ]> - -
- Automatic Snapshot Creation and Retention - (Supported for the following hypervisors: XenServer, VMware vSphere, and KVM) - Users can set up a recurring snapshot policy to automatically create multiple snapshots of a disk at regular intervals. Snapshots can be created on an hourly, daily, weekly, or monthly interval. One snapshot policy can be set up per disk volume. For example, a user can set up a daily snapshot at 02:30. - With each snapshot schedule, users can also specify the number of scheduled snapshots to be retained. Older snapshots that exceed the retention limit are automatically deleted. This user-defined limit must be equal to or lower than the global limit set by the &PRODUCT; administrator. See . The limit applies only to those snapshots that are taken as part of an automatic recurring snapshot policy. Additional manual snapshots can be created and retained. -
+ Automatic Snapshot Creation and Retention + (Supported for the following hypervisors: XenServer, + VMware vSphere, and KVM) + Users can set up a recurring snapshot policy to automatically create multiple snapshots of a + disk at regular intervals. Snapshots can be created on an hourly, daily, weekly, or monthly + interval. One snapshot policy can be set up per disk volume. For example, a user can set up a + daily snapshot at 02:30. + With each snapshot schedule, users can also specify the number of scheduled snapshots to be + retained. Older snapshots that exceed the retention limit are automatically deleted. This + user-defined limit must be equal to or lower than the global limit set by the &PRODUCT; + administrator. See . The limit applies only to those + snapshots that are taken as part of an automatic recurring snapshot policy. Additional manual + snapshots can be created and retained. + \ No newline at end of file diff --git a/docs/en-US/aws-ec2-configuration.xml b/docs/en-US/aws-ec2-configuration.xml new file mode 100644 index 00000000000..b8966c12495 --- /dev/null +++ b/docs/en-US/aws-ec2-configuration.xml @@ -0,0 +1,48 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Enabling the AWS API Compatible Interface + + The software that provides AWS API compatibility is installed along with CloudPlatform. However, you must enable the feature and perform some setup steps. + + + Set the global configuration parameter enable.ec2.api to true. See . + Create a set of &PRODUCT; service offerings with names that match the Amazon service offerings. + You can do this through the &PRODUCT; UI as described in the Administration Guide. + Be sure you have included the Amazon default service offering, m1.small. + If you did not already do so when you set the configuration parameter in step 1, restart the Management Server. + # service cloud-management restart + (Optional) The AWS API listens for requests on port 7080. If you prefer AWS API to listen on another port, you can change it as follows: + + Edit the files /etc/cloud/management/server.xml, /etc/cloud/management/server-nonssl.xml, and /etc/cloud/management/server-ssl.xml. + In each file, find the tag <Service name="Catalina7080">. Under this tag, locate <Connector executor="tomcatThreadPool-internal" port= ....<. + Change the port to whatever port you want to use, then save the files. + Restart the Management Server. + If you re-install CloudStack, you will have to make these changes again. + + + + +
diff --git a/docs/en-US/aws-ec2-introduction.xml b/docs/en-US/aws-ec2-introduction.xml new file mode 100644 index 00000000000..a4df086d465 --- /dev/null +++ b/docs/en-US/aws-ec2-introduction.xml @@ -0,0 +1,48 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Amazon Web Services EC2 Compatible Interface + &PRODUCT; can translate Amazon Web Services (AWS) API calls to native &PRODUCT; API calls + so that users can continue using existing AWS-compatible tools. This translation service runs as + a separate web application in the same tomcat server as the management server of &PRODUCT;, + listening on the same port. This Amazon EC2-compatible API is accessible through a SOAP web + service. + + This service was previously enabled by separate software called CloudBridge. It is now + fully integrated with the &PRODUCT; management server. + + Limitations + + + Supported only in zones that use basic networking. + + + Available in fresh installations of &PRODUCT;. Not available through upgrade of previous versions. + + + If you need to support features such as elastic IP, set up a Citrix NetScaler to provide this service. The commands such as ec2-associate-address will not work without EIP setup. Users running VMs in this zone will be using the NetScaler-enabled network offering (DefaultSharedNetscalerEIP and ELBNetworkOffering). + + +
diff --git a/docs/en-US/aws-ec2-requirements.xml b/docs/en-US/aws-ec2-requirements.xml new file mode 100644 index 00000000000..59fb5b6f5ab --- /dev/null +++ b/docs/en-US/aws-ec2-requirements.xml @@ -0,0 +1,35 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ System Requirements + + This interface complies with Amazon's WDSL version dated November 15, 2010, available at + http://ec2.amazonaws.com/doc/2010-11-15/. + Compatible with the EC2 command-line + tools EC2 tools v. 1.3.6230, which can be downloaded at http://s3.amazonaws.com/ec2-downloads/ec2-api-tools-1.3-62308.zip. + + +
\ No newline at end of file diff --git a/docs/en-US/aws-ec2-supported-commands.xml b/docs/en-US/aws-ec2-supported-commands.xml new file mode 100644 index 00000000000..9494218cd1c --- /dev/null +++ b/docs/en-US/aws-ec2-supported-commands.xml @@ -0,0 +1,396 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Supported AWS API Calls + The following Amazon EC2 commands are supported by &PRODUCT; when the AWS API compatibility feature is enabled. + For a few commands, there are differences between the &PRODUCT; and Amazon EC2 versions, and these differences are noted. The underlying SOAP call for each command is also given, for those who have built tools using those calls. + + + Elastic IP API mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-allocate-address + AllocateAddress + associateIpAddress + + + ec2-associate-address + AssociateAddress + enableStaticNat + + + ec2-describe-addresses + DescribeAddresses + listPublicIpAddresses + + + ec2-diassociate-address + DisassociateAddress + disableStaticNat + + + ec2-release-address + ReleaseAddress + disassociateIpAddress + + + +
+ + Availability Zone API mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-describe-availability-zones + DescribeAvailabilityZones + listZones + + + +
+ + Images API mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-create-image + CreateImage + createTemplate + + + ec2-deregister + DeregisterImage + DeleteTemplate + + + ec2-describe-images + DescribeImages + listTemplates + + + ec2-register + RegisterImage + registerTemplate + + + +
+ + Image Attributes API mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-describe-image-attribute + DescribeImageAttribute + listTemplatePermissions + + + ec2-modify-image-attribute + ModifyImageAttribute + updateTemplatePermissions + + + ec2-reset-image-attribute + ResetImageAttribute + updateTemplatePermissions + + + +
+ + Instances API mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-describe-instances + DescribeInstances + listVirtualMachines + + + ec2-run-instances + RunInstances + deployVirtualMachine + + + ec2-reboot-instances + RebootInstances + rebootVirtualMachine + + + ec2-start-instances + StartInstances + startVirtualMachine + + + ec2-stop-instances + StopInstances + stopVirtualMachine + + + ec2-terminate-instances + TerminateInstances + destroyVirtualMachine + + + +
+ + Instance Attributes Mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-describe-instance-attribute + DescribeInstanceAttribute + listVirtualMachines + + + +
+ + Keys Pairs Mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-add-keypair + CreateKeyPair + createSSHKeyPair + + + ec2-delete-keypair + DeleteKeyPair + deleteSSHKeyPair + + + ec2-describe-keypairs + DescribeKeyPairs + listSSHKeyPairs + + + ec2-import-keypair + ImportKeyPair + registerSSHKeyPair + + + +
+ + Passwords API Mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-get-password + GetPasswordData + getVMPassword + + + +
+ + Security Groups API Mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-authorize + AuthorizeSecurityGroupIngress + authorizeSecurityGroupIngress + + + ec2-add-group + CreateSecurityGroup + createSecurityGroup + + + ec2-delete-group + DeleteSecurityGroup + deleteSecurityGroup + + + ec2-describe-group + DescribeSecurityGroups + listSecurityGroups + + + ec2-revoke + RevokeSecurityGroupIngress + revokeSecurityGroupIngress + + + +
+ + Snapshots API Mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-create-snapshot + CreateSnapshot + createSnapshot + + + ec2-delete-snapshot + DeleteSnapshot + deleteSnapshot + + + ec2-describe-snapshots + DescribeSnapshots + listSnapshots + + + +
+ + Volumes API Mapping + + + + + EC2 command + SOAP call + &PRODUCT; API call + + + + + ec2-attach-volume + AttachVolume + attachVolume + + + ec2-create-volume + CreateVolume + createVolume + + + ec2-delete-volume + DeleteVolume + deleteVolume + + + ec2-describe-volume + DescribeVolume + listVolumes + + + ec2-detach-volume + DetachVolume + detachVolume + + + +
+
diff --git a/docs/en-US/aws-ec2-timeouts.xml b/docs/en-US/aws-ec2-timeouts.xml new file mode 100644 index 00000000000..c8b3ec6465f --- /dev/null +++ b/docs/en-US/aws-ec2-timeouts.xml @@ -0,0 +1,50 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Using Timeouts to Ensure AWS API Command Completion + The Amazon EC2 command-line tools have a default connection timeout. When used with &PRODUCT;, a longer timeout might be needed for some commands. If you find that commands are not completing due to timeouts, you can gain more time for commands to finish by overriding the default timeouts on individual commands. You can add the following optional command-line parameters to any &PRODUCT;-supported EC2 command: + + + + + + + --connection-timeout TIMEOUT + Specifies a connection timeout (in seconds). + Example: --connection-timeout 30 + + + + --request-timeout TIMEOUT + Specifies a request timeout (in seconds). + Example: --request-timeout 45 + + + + + + Example: + ec2-run-instances 2 –z us-test1 –n 1-3 --connection-timeout 120 --request-timeout 120 +
\ No newline at end of file diff --git a/docs/en-US/aws-ec2-user-setup.xml b/docs/en-US/aws-ec2-user-setup.xml new file mode 100644 index 00000000000..8607378d88c --- /dev/null +++ b/docs/en-US/aws-ec2-user-setup.xml @@ -0,0 +1,97 @@ + + +%BOOK_ENTITIES; +]> + + +
+ AWS API User Setup Steps + In general, users need not be aware that they are using a translation service provided by &PRODUCT;. + They need only send AWS API calls to &PRODUCT;'s endpoint, and it will translate the calls to the native API. + Users of the Amazon EC2 compatible interface will be able to keep their existing EC2 tools + and scripts and use them with their &PRODUCT; deployment, by specifying the endpoint of the + management server and using the proper user credentials. In order to do this, each user must + perform the following configuration steps: + + + + Generate user credentials and register with the service. + + + Set up the environment variables for the EC2 command-line tools. + + + For SOAP access, use the endpoint http://&PRODUCT;-management-server:7080/awsapi. + The &PRODUCT;-management-server can be specified by a fully-qualified domain name or IP address. + + + +
+ AWS API User Registration + Each user must perform a one-time registration. The user follows these steps: + + + Obtain the following by looking in the &PRODUCT; UI, using the API, or asking the cloud administrator: + + The &PRODUCT; server's publicly available DNS name or IP address + The user account's API key and Secret key + + + + + Generate a private key and a self-signed X.509 certificate. The user substitutes their own desired storage location for /path/to/… below. + + $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /path/to/private_key.pem -out /path/to/cert.pem + + + + + Register the mapping from the X.509 certificate to the API/Secret keys. + Download the following script from http://download.cloud.com/releases/3.0.3/cloudstack-aws-api-register and run it. + Substitute the values that were obtained in step 1 in the URL below. + + +$ cloudstack-aws-api-register --apikey=User’s &PRODUCT; API key --secretkey=User’s &PRODUCT; Secret key --cert=/path/to/cert.pem --url=http://&PRODUCT;.server:7080/awsapi + + + + + + A user with an existing AWS certificate could choose to use the same certificate with &PRODUCT;, but the public key would be uploaded to the &PRODUCT; management server database. + + +
+
+ AWS API Command-Line Tools Setup + To use the EC2 command-line tools, the user must perform these steps: + + Be sure you have the right version of EC2 Tools. + The supported version is available at http://s3.amazonaws.com/ec2-downloads/ec2-api-tools-1.3-62308.zip. + + + Set up the environment variables that will direct the tools to the server. As a best practice, you may wish to place these commands in a script that may be sourced before using the AWS API translation feature. + $ export EC2_CERT=/path/to/cert.pem +$ export EC2_PRIVATE_KEY=/path/to/private_key.pem +$ export EC2_URL=http://&PRODUCT;.server:7080/awsapi +$ export EC2_HOME=/path/to/EC2_tools_directory + + +
+
\ No newline at end of file diff --git a/docs/en-US/cloudstack_trial_installation.xml b/docs/en-US/aws-interface-compatibility.xml similarity index 55% rename from docs/en-US/cloudstack_trial_installation.xml rename to docs/en-US/aws-interface-compatibility.xml index 24a1699d1d7..a03d447b50d 100644 --- a/docs/en-US/cloudstack_trial_installation.xml +++ b/docs/en-US/aws-interface-compatibility.xml @@ -1,5 +1,5 @@ - %BOOK_ENTITIES; ]> @@ -22,9 +22,12 @@ under the License. --> - - - - - - + + Amazon Web Service Interface Compatibility + + + + + + + diff --git a/docs/en-US/basic-zone-configuration.xml b/docs/en-US/basic-zone-configuration.xml index 18afa84f794..e27c91493fa 100644 --- a/docs/en-US/basic-zone-configuration.xml +++ b/docs/en-US/basic-zone-configuration.xml @@ -68,7 +68,6 @@ (Introduced in version 3.0.1) Assign a network traffic label to each traffic type on the physical network. These labels must match the labels you have already defined on the hypervisor host. To assign each label, click the Edit button under the traffic type icon. A popup dialog appears where you can type the label, then click OK. These traffic labels will be defined only for the hypervisor selected for the first cluster. For all other hypervisors, the labels can be configured after the zone is created. - (VMware only) If you have enabled Nexus dvSwitch in the environment, you must specify the corresponding Ethernet port profile names as network traffic label for each traffic type on the physical network. For more information on Nexus dvSwitch, see Configuring a vSphere Cluster with Nexus 1000v Virtual Switch. Click Next. (NetScaler only) If you chose the network offering for NetScaler, you have an additional screen to fill out. Provide the requested details to set up the NetScaler, then click Next. @@ -126,7 +125,7 @@ Citrix XenServer Installation and Configuration VMware vSphere Installation and Configuration KVM vSphere Installation and Configuration - Oracle VM (OVM) Installation and Configuration +
To configure the first host, enter the following, then click Next: @@ -140,7 +139,7 @@ To configure the first primary storage server, enter the following, then click Next: Name. The name of the storage device. - Protocol. For XenServer, choose either NFS, iSCSI, or PreSetup. For KVM, choose NFS or SharedMountPoint. For vSphere choose either VMFS (iSCSI or FiberChannel) or NFS. The remaining fields in the screen vary depending on what you choose here. + Protocol. For XenServer, choose either NFS, iSCSI, or PreSetup. For KVM, choose NFS, SharedMountPoint,CLVM, or RBD. For vSphere choose either VMFS (iSCSI or FiberChannel) or NFS. The remaining fields in the screen vary depending on what you choose here. diff --git a/docs/en-US/best-practices-for-vms.xml b/docs/en-US/best-practices-for-vms.xml index a67add4edeb..04c3c0aa276 100644 --- a/docs/en-US/best-practices-for-vms.xml +++ b/docs/en-US/best-practices-for-vms.xml @@ -1,3 +1,8 @@ + + +%BOOK_ENTITIES; +]> -
- VM Lifecycle - The CloudPlatform administrator should monitor the total number of VM instances in each cluster, and disable allocation to the cluster if the total is approaching the maximum that the hypervisor can handle. Be sure to leave a safety margin to allow for the possibility of one or more hosts failing, which would increase the VM load on the other hosts as the VMs are automatically redeployed. Consult the documentation for your chosen hypervisor to find the maximum permitted number of VMs per host, then use CloudPlatform global configuration settings to set this as the default limit. Monitor the VM activity in each cluster at all times. Keep the total number of VMs below a safe level that allows for the occasional host failure. For example, if there are N hosts in the cluster, and you want to allow for one host in the cluster to be down at any given time, the total number of VM instances you can permit in the cluster is at most (N-1) * (per-host-limit). Once a cluster reaches this number of VMs, use the CloudPlatform UI to disable allocation of more VMs to the cluster.. - -
+
+ Best Practices for Virtual Machines + The &PRODUCT; administrator should monitor the total number of VM instances in each + cluster, and disable allocation to the cluster if the total is approaching the maximum that + the hypervisor can handle. Be sure to leave a safety margin to allow for the possibility of + one or more hosts failing, which would increase the VM load on the other hosts as the VMs + are automatically redeployed. Consult the documentation for your chosen hypervisor to find + the maximum permitted number of VMs per host, then use &PRODUCT; global configuration + settings to set this as the default limit. Monitor the VM activity in each cluster at all + times. Keep the total number of VMs below a safe level that allows for the occasional host + failure. For example, if there are N hosts in the cluster, and you want to allow for one + host in the cluster to be down at any given time, the total number of VM instances you can + permit in the cluster is at most (N-1) * (per-host-limit). Once a cluster reaches this + number of VMs, use the &PRODUCT; UI to disable allocation of more VMs to the + cluster. +
\ No newline at end of file diff --git a/docs/en-US/build-deb.xml b/docs/en-US/build-deb.xml new file mode 100644 index 00000000000..deee3ceb1de --- /dev/null +++ b/docs/en-US/build-deb.xml @@ -0,0 +1,123 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Building DEB packages + + In addition to the bootstrap dependencies, you'll also need to install + several other dependencies. Note that we recommend using Maven 3, which + is not currently available in 12.04.1 LTS. So, you'll also need to add a + PPA repository that includes Maven 3. After running the command + add-apt-repository, you will be prompted to continue and + a GPG key will be added. + + +$ sudo apt-get update +$ sudo apt-get install python-software-properties +$ sudo add-apt-repository ppa:natecarlson/maven3 +$ sudo apt-get update +$ sudo apt-get install ant debhelper openjdk-6-jdk tomcat6 libws-commons-util-java genisoimage python-mysqldb libcommons-codec-java libcommons-httpclient-java liblog4j1.2-java maven3 + + + While we have defined, and you have presumably already installed the + bootstrap prerequisites, there are a number of build time prerequisites + that need to be resolved. &PRODUCT; uses maven for dependency resolution. + You can resolve the buildtime depdencies for CloudStack by running: + +$ mvn3 -P deps + + Now that we have resolved the dependencies we can move on to building &PRODUCT; + and packaging them into DEBs by issuing the following command. + + +$ dpkg-buildpackge -uc -us + + + + This command will build 16 Debian packages. You should have all of the following: + + +cloud-agent_4.0.0-incubating_amd64.deb +cloud-agent-deps_4.0.0-incubating_amd64.deb +cloud-agent-libs_4.0.0-incubating_amd64.deb +cloud-awsapi_4.0.0-incubating_amd64.deb +cloud-cli_4.0.0-incubating_amd64.deb +cloud-client_4.0.0-incubating_amd64.deb +cloud-client-ui_4.0.0-incubating_amd64.deb +cloud-core_4.0.0-incubating_amd64.deb +cloud-deps_4.0.0-incubating_amd64.deb +cloud-python_4.0.0-incubating_amd64.deb +cloud-scripts_4.0.0-incubating_amd64.deb +cloud-server_4.0.0-incubating_amd64.deb +cloud-setup_4.0.0-incubating_amd64.deb +cloud-system-iso_4.0.0-incubating_amd64.deb +cloud-usage_4.0.0-incubating_amd64.deb +cloud-utils_4.0.0-incubating_amd64.deb + + +
+ Setting up an APT repo + + After you've created the packages, you'll want to copy them to a system where you can serve the packages over HTTP. You'll create a directory for the packages and then use dpkg-scanpackages to create Packages.gz, which holds information about the archive structure. Finally, you'll add the repository to your system(s) so you can install the packages using APT. + + The first step is to make sure that you have the dpkg-dev package installed. This should have been installed when you pulled in the debhelper application previously, but if you're generating Packages.gz on a different system, be sure that it's installed there as well. + +$ sudo apt-get install dpkg-dev + +The next step is to copy the DEBs to the directory where they can be served over HTTP. We'll use /var/www/cloudstack/repo in the examples, but change the directory to whatever works for you. + + +sudo mkdir -p /var/www/cloudstack/repo/binary +sudo cp *.deb /var/www/cloudstack/repo/binary +sudo cd /var/www/cloudstack/repo/binary +sudo dpkg-scanpackages . /dev/null | tee Packages | gzip -9 > Packages.gz + + +Note: Override Files + You can safely ignore the warning about a missing override file. + + +Now you should have all of the DEB packages and Packages.gz in the binary directory and available over HTTP. (You may want to use wget or curl to test this before moving on to the next step.) + +
+
+ Configuring your machines to use the APT repository + + Now that we have created the repository, you need to configure your machine + to make use of the APT repository. You can do this by adding a repository file + under /etc/apt/sources.list.d. Use your preferred editor to + create /etc/apt/sources.list.d/cloudstack.list with this + line: + + deb http://server.url/cloudstack/repo binary/ + + Now that you have the repository info in place, you'll want to run another + update so that APT knows where to find the &PRODUCT; packages. + +$ sudo apt-get update + +You can now move on to the instructions under Install on Ubuntu. + +
+
diff --git a/docs/en-US/build-rpm.xml b/docs/en-US/build-rpm.xml new file mode 100644 index 00000000000..e983aba8fe5 --- /dev/null +++ b/docs/en-US/build-rpm.xml @@ -0,0 +1,82 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Building RPMs + + While we have defined, and you have presumably already installed the + bootstrap prerequisites, there are a number of build time prerequisites + that need to be resolved. &PRODUCT; uses maven for dependency resolution. + You can resolve the buildtime depdencies for CloudStack by running the + following command: + $ mvn -P deps + + + Now that we have resolved the dependencies we can move on to building &PRODUCT; + and packaging them into RPMs by issuing the following command. + $ ./waf rpm + + + Once this completes, you should find assembled RPMs in + artifacts/rpmbuild/RPMS/x86_64 + +
+ Creating a yum repo + + While RPMs is an ideal packaging format - it's most easily consumed from + yum repositories over a network. We'll move into the directory with the + newly created RPMs by issuing the following command: + $ cd artifacts/rpmbuild/RPMS/x86_64 + + + Next we'll issue a command to create the repository metadata by + issuing the following command: + $ createrepo ./ + + + The files and directories within our current working directory can now + be uploaded to a web server and serve as a yum repository + +
+
+ Configuring your systems to use your new yum repository + + Now that your yum repository is populated with RPMs and metadata + we need to configure our machines that need to install CloudStack. + We will create a file at /etc/yum.repos.d/cloudstack.repo + with the following content: + +[apache-cloudstack] +name=Apache CloudStack +baseurl=http://webserver.tld/path/to/repo +enabled=1 +gpgcheck=0 + + + + Completing this step will allow you to easily install CloudStack on a number of + machines across the network. + +
+
diff --git a/docs/en-US/castor-with-cs.xml b/docs/en-US/castor-with-cs.xml new file mode 100644 index 00000000000..5049d33d638 --- /dev/null +++ b/docs/en-US/castor-with-cs.xml @@ -0,0 +1,87 @@ + + +%BOOK_ENTITIES; +]> + +
+ Using the CAStor Back-end Storage with &PRODUCT; + This section describes how to use a CAStor cluster as the back-end storage system for a + &PRODUCT; S3 front-end. The CAStor back-end storage for &PRODUCT; extends the existing storage + classes and allows the storage configuration attribute to point to a CAStor cluster. + This feature makes use of the &PRODUCT; server's local disk to spool files before writing + them to CAStor when handling the PUT operations. However, a file must be successfully written + into the CAStor cluster prior to the return of a success code to the S3 client to ensure that + the transaction outcome is correctly reported. + + The S3 multipart file upload is not supported in this release. You are prompted with + proper error message if a multipart upload is attempted. + + To configure CAStor: + + + Install &PRODUCT; 4.0.0-incubating by following the instructions given in the INSTALL.txt + file. + + You can use the S3 storage system in &PRODUCT; without setting up and installing the + compute components. + + + + Enable the S3 API by setting "enable.s3.api = true" in the Global parameter section in + the UI and register a user. + For more information, see S3 API in + &PRODUCT;. + + + Edit the cloud-bridge.properties file and modify the "storage.root" parameter. + + + Set "storage.root" to the key word "castor". + + + Specify a CAStor tenant domain to which content is written. If the domain is not + specified, the CAStor default domain, specified by the "cluster" parameter in CAStor's + node.cfg file, will be used. + + + Specify a list of node IP addresses, or set "zeroconf" and the cluster + name. When using a static IP list with a large cluster, it is not necessary to include + every node, only a few is required to initialize the client software. + For example: + storage.root=castor domain=cloudstack 10.1.1.51 10.1.1.52 10.1.1.53 + In this example, the configuration file directs &PRODUCT; to write the S3 files to + CAStor instead of to a file system, where the CAStor domain name is cloudstack, and the + CAStor node IP addresses are those listed. + + + (Optional) The last value is a port number on which to communicate with the CAStor + cluster. If not specified, the default is 80. + #Static IP list with optional port +storage.root=castor domain=cloudstack 10.1.1.51 10.1.1.52 10.1.1.53 80 +#Zeroconf locator for cluster named "castor.example.com" +storage.root=castor domain=cloudstack zeroconf=castor.example.com + + + + + Create the tenant domain within the CAStor storage cluster. If you omit this step before + attempting to store content, you will get HTTP 412 errors in the awsapi.log. + + +
diff --git a/docs/en-US/cloudstack_developers.xml b/docs/en-US/change-database-config.xml similarity index 64% rename from docs/en-US/cloudstack_developers.xml rename to docs/en-US/change-database-config.xml index e847f6a0474..fadb64c27e7 100644 --- a/docs/en-US/cloudstack_developers.xml +++ b/docs/en-US/change-database-config.xml @@ -1,5 +1,5 @@ - %BOOK_ENTITIES; ]> @@ -22,10 +22,7 @@ under the License. --> - - - - - - - +
+ Changing the Database Configuration + The &PRODUCT; Management Server stores database configuration information (e.g., hostname, port, credentials) in the file /etc/cloud/management/db.properties. To effect a change, edit this file on each Management Server, then restart the Management Server. +
\ No newline at end of file diff --git a/docs/en-US/change-to-behavior-of-list-commands.xml b/docs/en-US/change-to-behavior-of-list-commands.xml index 4e53590a773..69b9e4d2beb 100644 --- a/docs/en-US/change-to-behavior-of-list-commands.xml +++ b/docs/en-US/change-to-behavior-of-list-commands.xml @@ -1,89 +1,108 @@ - %BOOK_ENTITIES; ]> - -
- Change to Behavior of List Commands - There was a major change in how our List* API commands work in CloudStack 3.0 compared to 2.2.x. The rules below apply only for managed resources – those that belong to an account, domain, or project. They are irrelevant for the List* commands displaying unmanaged (system) resources, such as hosts, clusters, and external network resources. - When no parameters are passed in to the call, the caller sees only resources owned by the caller (even when the caller is the administrator). Previously, the administrator saw everyone else's resources by default. - When accountName and domainId are passed in: - - The caller sees the resources dedicated to the account specified. - If the call is executed by a regular user, the user is authorized to specify only the user's own account and domainId. - If the caller is a domain administrator, CloudStack performs an authorization check to see whether the caller is permitted to view resources for the given account and domainId. - - When projectId is passed in, only resources belonging to that project are listed. - When domainId is passed in, the call returns only resources belonging to the domain specified. To see the resources of subdomains, use the parameter isRecursive=true. Again, the regular user can see only resources owned by that user, the root administrator can list anything, and a domain administrator is authorized to see only resources of the administrator's own domain and subdomains. - To see all resources the caller is authorized to see, except for Project resources, use the parameter listAll=true. - To see all Project resources the caller is authorized to see, use the parameter projectId=-1. - There is one API command that doesn't fall under the rules above completely: the listTemplates command. This command has its own flags defining the list rules: - - - - - - - listTemplates Flag - Description - - - - - featured - Returns templates that have been marked as featured and public. - - - - self - Returns templates that have been registered or created by the calling user. - - - - selfexecutable - Same as self, but only returns templates that are ready to be deployed with. - - - - sharedexecutable - Ready templates that have been granted to the calling user by another user. - - - - executable - Templates that are owned by the calling user, or public templates, that can be used to deploy a new VM. - - - - community - Returns templates that have been marked as public but not featured. - - - - all - Returns all templates (only usable by admins). - - - - - The &PRODUCT; UI on a general view will display all resources that the logged-in user is authorized to see, except for project resources. To see the project resources, select the project view. -
+ Change to Behavior of List Commands + There was a major change in how our List* API commands work in CloudStack 3.0 compared to + 2.2.x. The rules below apply only for managed resources – those that belong to an account, + domain, or project. They are irrelevant for the List* commands displaying unmanaged (system) + resources, such as hosts, clusters, and external network resources. + When no parameters are passed in to the call, the caller sees only resources owned by the + caller (even when the caller is the administrator). Previously, the administrator saw everyone + else's resources by default. + When accountName and domainId are passed in: + + + The caller sees the resources dedicated to the account specified. + + + If the call is executed by a regular user, the user is authorized to specify only the + user's own account and domainId. + + + If the caller is a domain administrator, CloudStack performs an authorization check to + see whether the caller is permitted to view resources for the given account and + domainId. + + + When projectId is passed in, only resources belonging to that project are listed. + When domainId is passed in, the call returns only resources belonging to the domain + specified. To see the resources of subdomains, use the parameter isRecursive=true. Again, the + regular user can see only resources owned by that user, the root administrator can list + anything, and a domain administrator is authorized to see only resources of the administrator's + own domain and subdomains. + To see all resources the caller is authorized to see, except for Project resources, use the + parameter listAll=true. + To see all Project resources the caller is authorized to see, use the parameter + projectId=-1. + There is one API command that doesn't fall under the rules above completely: the + listTemplates command. This command has its own flags defining the list rules: + + + + + + + listTemplates Flag + Description + + + + + featured + Returns templates that have been marked as featured and + public. + + + self + Returns templates that have been registered or created by the calling + user. + + + selfexecutable + Same as self, but only returns templates that are ready to be deployed + with. + + + sharedexecutable + Ready templates that have been granted to the calling user by another + user. + + + executable + Templates that are owned by the calling user, or public templates, that can + be used to deploy a new VM. + + + community + Returns templates that have been marked as public but not + featured. + + + all + Returns all templates (only usable by admins). + + + + + The &PRODUCT; UI on a general view will display all resources that the logged-in user is + authorized to see, except for project resources. To see the project resources, select the + project view. + diff --git a/docs/en-US/changed-apicommands-4.0.xml b/docs/en-US/changed-apicommands-4.0.xml new file mode 100644 index 00000000000..042d5e2611e --- /dev/null +++ b/docs/en-US/changed-apicommands-4.0.xml @@ -0,0 +1,268 @@ + + +%BOOK_ENTITIES; +]> + +
+ Changed API Commands in 4.0.0-incubating + + + + + + + API Commands + Description + + + + + + copyTemplate + prepareTemplate + registerTemplate + updateTemplate + createProject + activateProject + suspendProject + updateProject + listProjectAccounts + createVolume + migrateVolume + attachVolume + detachVolume + uploadVolume + createSecurityGroup + registerIso + copyIso + updateIso + createIpForwardingRule + listIpForwardingRules + createLoadBalancerRule + updateLoadBalancerRule + createSnapshot + + + The commands in this list have a single new response parameter, and no other + changes. + New response parameter: tags(*) + + Many other commands also have the new tags(*) parameter in addition to other + changes; those commands are listed separately. + + + + + rebootVirtualMachine + attachIso + detachIso + listLoadBalancerRuleInstances + resetPasswordForVirtualMachine + changeServiceForVirtualMachine + recoverVirtualMachine + startVirtualMachine + migrateVirtualMachine + deployVirtualMachine + assignVirtualMachine + updateVirtualMachine + restoreVirtualMachine + stopVirtualMachine + destroyVirtualMachine + + + The commands in this list have two new response parameters, and no other + changes. + New response parameters: keypair, tags(*) + + + + + listSecurityGroups + listFirewallRules + listPortForwardingRules + listSnapshots + listIsos + listProjects + listTemplates + listLoadBalancerRules + + The commands in this list have the following new parameters, and no other + changes. + New request parameter: tags (optional) + New response parameter: tags(*) + + + + + listF5LoadBalancerNetworks + listNetscalerLoadBalancerNetworks + listSrxFirewallNetworks + updateNetwork + + + The commands in this list have three new response parameters, and no other + changes. + New response parameters: canusefordeploy, vpcid, tags(*) + + + + + createZone + updateZone + + The commands in this list have the following new parameters, and no other + changes. + New request parameter: localstorageenabled (optional) + New response parameter: localstorageenabled + + + + listZones + New response parameter: localstorageenabled + + + + rebootRouter + changeServiceForRouter + startRouter + destroyRouter + stopRouter + + The commands in this list have two new response parameters, and no other + changes. + New response parameters: vpcid, nic(*) + + + + updateAccount + disableAccount + listAccounts + markDefaultZoneForAccount + enableAccount + + The commands in this list have three new response parameters, and no other + changes. + New response parameters: vpcavailable, vpclimit, vpctotal + + + listRouters + + New request parameters: forvpc (optional), vpcid (optional) + New response parameters: vpcid, nic(*) + + + + listNetworkOfferings + + New request parameters: forvpc (optional) + New response parameters: forvpc + + + + listVolumes + + New request parameters: details (optional), tags (optional) + New response parameters: tags(*) + + + + addTrafficMonitor + + New request parameters: excludezones (optional), includezones (optional) + + + + createNetwork + + New request parameters: vpcid (optional) + New response parameters: canusefordeploy, vpcid, tags(*) + + + + listPublicIpAddresses + + New request parameters: tags (optional), vpcid (optional) + New response parameters: vpcid, tags(*) + + + + listNetworks + + New request parameters: canusefordeploy (optional), forvpc (optional), tags + (optional), vpcid (optional) + New response parameters: canusefordeploy, vpcid, tags(*) + + + + restartNetwork + + New response parameters: vpcid, tags(*) + + + + enableStaticNat + + New request parameter: networkid (optional) + + + + createDiskOffering + + New request parameter: storagetype (optional) + New response parameter: storagetype + + + + listDiskOfferings + + New response parameter: storagetype + + + + updateDiskOffering + + New response parameter: storagetype + + + + createFirewallRule + + Changed request parameters: ipaddressid (old version - optional, new version - + required) + New response parameter: tags(*) + + + + listVirtualMachines + + New request parameters: isoid (optional), tags (optional), templateid + (optional) + New response parameters: keypair, tags(*) + + + + updateStorageNetworkIpRange + + New response parameters: id, endip, gateway, netmask, networkid, podid, startip, + vlan, zoneid + + + + + +
diff --git a/docs/en-US/choosing-a-deployment-architecture.xml b/docs/en-US/choosing-a-deployment-architecture.xml new file mode 100644 index 00000000000..0503d8c7597 --- /dev/null +++ b/docs/en-US/choosing-a-deployment-architecture.xml @@ -0,0 +1,29 @@ + +%BOOK_ENTITIES; +]> + + + + Choosing a Deployment Architecture + The architecture used in a deployment will vary depending on the size and purpose of the deployment. This section contains examples of deployment architecture, including a small-scale deployment useful for test and trial deployments and a fully-redundant large-scale setup for production deployments. + + + + + + diff --git a/docs/en-US/citrix-xenserver-installation.xml b/docs/en-US/citrix-xenserver-installation.xml index 75ba73d2664..867d36e1b10 100644 --- a/docs/en-US/citrix-xenserver-installation.xml +++ b/docs/en-US/citrix-xenserver-installation.xml @@ -1,5 +1,5 @@ - %BOOK_ENTITIES; ]> @@ -21,469 +21,728 @@ specific language governing permissions and limitations under the License. --> -
- Citrix XenServer Installation for &PRODUCT; - If you want to use the Citrix XenServer hypervisor to run guest virtual machines, install XenServer 6.0 or XenServer 6.0.2 on the host(s) in your cloud. For an initial installation, follow the steps below. If you have previously installed XenServer and want to upgrade to another version, see . -
- System Requirements for XenServer Hosts - - The host must be certified as compatible with one of the following. See the Citrix Hardware Compatibility Guide: http://hcl.xensource.com + Citrix XenServer Installation for &PRODUCT; + If you want to use the Citrix XenServer hypervisor to run guest virtual machines, install + XenServer 6.0 or XenServer 6.0.2 on the host(s) in your cloud. For an initial installation, + follow the steps below. If you have previously installed XenServer and want to upgrade to + another version, see . +
+ System Requirements for XenServer Hosts - XenServer 5.6 SP2 - XenServer 6.0 - XenServer 6.0.2 + + The host must be certified as compatible with one of the following. See the Citrix + Hardware Compatibility Guide: http://hcl.xensource.com + + + XenServer 5.6 SP2 + + + XenServer 6.0 + + + XenServer 6.0.2 + + + + + You must re-install Citrix XenServer if you are going to re-use a host from a previous + install. + + + Must support HVM (Intel-VT or AMD-V enabled) + + + Be sure all the hotfixes provided by the hypervisor vendor are applied. Track the + release of hypervisor patches through your hypervisor vendor’s support channel, and apply + patches as soon as possible after they are released. &PRODUCT; will not track or notify + you of required hypervisor patches. It is essential that your hosts are completely up to + date with the provided hypervisor patches. The hypervisor vendor is likely to refuse to + support any system that is not up to date with patches. + + + All hosts within a cluster must be homogenous. The CPUs must be of the same type, + count, and feature flags. + + + Must support HVM (Intel-VT or AMD-V enabled in BIOS) + + + 64-bit x86 CPU (more cores results in better performance) + + + Hardware virtualization support required + + + 4 GB of memory + + + 36 GB of local disk + + + At least 1 NIC + + + Statically allocated IP Address + + + When you deploy &PRODUCT;, the hypervisor host must not have any VMs already + running + - - All hosts must be 64-bit and must support HVM (Intel-VT or AMD-V enabled in BIOS). - All hosts within a cluster must be homogenous. That means the CPUs must be of the same type, count, and feature flags. - You must re-install Citrix XenServer if you are going to re-use a host from a previous install. - 64-bit x86 CPU (more cores results in better performance) - Hardware virtualization support required - 4 GB of memory - 36 GB of local disk - At least 1 NIC - Statically allocated IP Address - Be sure all the hotfixes provided by the hypervisor vendor are applied. Track the release of hypervisor patches through your hypervisor vendor’s support channel, and apply patches as soon as possible after they are released. &PRODUCT; will not track or notify you of required hypervisor patches. It is essential that your hosts are completely up to date with the provided hypervisor patches. The hypervisor vendor is likely to refuse to support any system that is not up to date with patches. For more information, see Highly Recommended Hotfixes for XenServer in the &PRODUCT; Knowledge Base. - - The lack of up-do-date hotfixes can lead to data corruption and lost VMs. -
-
- XenServer Installation Steps - - From https://www.citrix.com/English/ss/downloads/, download the appropriate version of XenServer for your &PRODUCT; version (see ). Install it using the Citrix XenServer Installation Guide. - After installation, perform the following configuration steps, which are described in the next few sections: - - - - - - - Required - Optional - - - - - - - - - - Set up SR if not using NFS, iSCSI, or local disk; see - - - - - - - - - - - - - - -
-
- Configure XenServer dom0 Memory - Configure the XenServer dom0 settings to allocate more memory to dom0. This can enable XenServer to handle larger numbers of virtual machines. We recommend 2940 MB of RAM for XenServer dom0. For instructions on how to do this, see http://support.citrix.com/article/CTX126531. The article refers to XenServer 5.6, but the same information applies to XenServer 6.0. -
-
- Username and Password - All XenServers in a cluster must have the same username and password as configured in &PRODUCT;. -
-
- Time Synchronization - The host must be set to use NTP. All hosts in a pod must have the same time. - + + The lack of up-do-date hotfixes can lead to data corruption and lost VMs. + +
+
+ XenServer Installation Steps + - Install NTP. - # yum install ntp + From https://www.citrix.com/English/ss/downloads/, download the appropriate version + of XenServer for your &PRODUCT; version (see ). Install it using the Citrix XenServer + Installation Guide. - Edit the NTP configuration file to point to your NTP server. - # vi /etc/ntp.conf - Add one or more server lines in this file with the names of the NTP servers you want to use. For example: - -server 0.xenserver.pool.ntp.org + After installation, perform the following configuration steps, which are described in + the next few sections: + + + + + + + Required + Optional + + + + + + + + + + Set up SR if not using NFS, iSCSI, or local disk; see + + + + + + + + + + + + + + +
+
+ Configure XenServer dom0 Memory + Configure the XenServer dom0 settings to allocate more memory to dom0. This can enable + XenServer to handle larger numbers of virtual machines. We recommend 2940 MB of RAM for + XenServer dom0. For instructions on how to do this, see http://support.citrix.com/article/CTX126531. The article refers to XenServer 5.6, + but the same information applies to XenServer 6.0. +
+
+ Username and Password + All XenServers in a cluster must have the same username and password as configured in + &PRODUCT;. +
+
+ Time Synchronization + The host must be set to use NTP. All hosts in a pod must have the same time. + + + Install NTP. + # yum install ntp + + + Edit the NTP configuration file to point to your NTP server. + # vi /etc/ntp.conf + Add one or more server lines in this file with the names of the NTP servers you want + to use. For example: + server 0.xenserver.pool.ntp.org server 1.xenserver.pool.ntp.org server 2.xenserver.pool.ntp.org server 3.xenserver.pool.ntp.org - Restart the NTP client. - # service ntpd restart + Restart the NTP client. + # service ntpd restart - Make sure NTP will start again upon reboot. - # chkconfig ntpd on + Make sure NTP will start again upon reboot. + # chkconfig ntpd on - -
-
- Licensing - Citrix XenServer Free version provides 30 days usage without a license. Following the 30 day trial, XenServer requires a free activation and license. You can choose to install a license now or skip this step. If you skip this step, you will need to install a license when you activate and license the XenServer. -
+ +
+
+ Licensing + Citrix XenServer Free version provides 30 days usage without a license. Following the 30 + day trial, XenServer requires a free activation and license. You can choose to install a + license now or skip this step. If you skip this step, you will need to install a license when + you activate and license the XenServer. +
Getting and Deploying a License - If you choose to install a license now you will need to use the XenCenter to activate and get a license. + If you choose to install a license now you will need to use the XenCenter to activate + and get a license. - In XenCenter, click Tools > License manager. - Select your XenServer and select Activate Free XenServer. - Request a license. + + In XenCenter, click Tools > License manager. + + + Select your XenServer and select Activate Free XenServer. + + + Request a license. + You can install the license with XenCenter or using the xe command line tool. +
-
-
- Install &PRODUCT; XenServer Support Package (CSP) - (Optional) - To enable security groups, elastic load balancing, and elastic IP on XenServer, download and install the &PRODUCT; XenServer Support Package (CSP). After installing XenServer, perform the following additional steps on each XenServer host. - +
+ Install &PRODUCT; XenServer Support Package (CSP) + (Optional) + To enable security groups, elastic load balancing, and elastic IP on XenServer, download + and install the &PRODUCT; XenServer Support Package (CSP). After installing XenServer, perform + the following additional steps on each XenServer host. + - Download the CSP software onto the XenServer host from one of the following links: - For XenServer 6.0.2: - http://download.cloud.com/releases/3.0.1/XS-6.0.2/xenserver-cloud-supp.tgz - For XenServer 5.6 SP2: - http://download.cloud.com/releases/2.2.0/xenserver-cloud-supp.tgz - For XenServer 6.0: - http://download.cloud.com/releases/3.0/xenserver-cloud-supp.tgz + Download the CSP software onto the XenServer host from one of the following + links: + For XenServer 6.0.2: + http://download.cloud.com/releases/3.0.1/XS-6.0.2/xenserver-cloud-supp.tgz + For XenServer 5.6 SP2: + http://download.cloud.com/releases/2.2.0/xenserver-cloud-supp.tgz + For XenServer 6.0: + http://download.cloud.com/releases/3.0/xenserver-cloud-supp.tgz - Extract the file: - # tar xf xenserver-cloud-supp.tgz + Extract the file: + # tar xf xenserver-cloud-supp.tgz - Run the following script: - # xe-install-supplemental-pack xenserver-cloud-supp.iso + Run the following script: + # xe-install-supplemental-pack xenserver-cloud-supp.iso - If the XenServer host is part of a zone that uses basic networking, disable Open vSwitch (OVS): - # xe-switch-network-backend bridge - Restart the host machine when prompted. + If the XenServer host is part of a zone that uses basic networking, disable Open + vSwitch (OVS): + # xe-switch-network-backend bridge + Restart the host machine when prompted. - - The XenServer host is now ready to be added to &PRODUCT;. -
-
- Primary Storage Setup for XenServer - &PRODUCT; natively supports NFS, iSCSI and local storage. If you are using one of these storage types, there is no need to create the XenServer Storage Repository ("SR"). - If, however, you would like to use storage connected via some other technology, such as FiberChannel, you must set up the SR yourself. To do so, perform the following steps. If you have your hosts in a XenServer pool, perform the steps on the master node. If you are working with a single XenServer which is not part of a cluster, perform the steps on that XenServer. - - Connect FiberChannel cable to all hosts in the cluster and to the FiberChannel storage host. + + The XenServer host is now ready to be added to &PRODUCT;. +
+
+ Primary Storage Setup for XenServer + &PRODUCT; natively supports NFS, iSCSI and local storage. If you are using one of these + storage types, there is no need to create the XenServer Storage Repository ("SR"). + If, however, you would like to use storage connected via some other technology, such as + FiberChannel, you must set up the SR yourself. To do so, perform the following steps. If you + have your hosts in a XenServer pool, perform the steps on the master node. If you are working + with a single XenServer which is not part of a cluster, perform the steps on that + XenServer. + - Rescan the SCSI bus. Either use the following command or use XenCenter to perform an HBA rescan. - # scsi-rescan + Connect FiberChannel cable to all hosts in the cluster and to the FiberChannel storage + host. - Repeat step 2 on every host. - Check to be sure you see the new SCSI disk. - # ls /dev/disk/by-id/scsi-360a98000503365344e6f6177615a516b -l - The output should look like this, although the specific file name will be different (scsi-<scsiID>): - -lrwxrwxrwx 1 root root 9 Mar 16 13:47 + Rescan the SCSI bus. Either use the following command or use XenCenter to perform an + HBA rescan. + # scsi-rescan + + + Repeat step 2 on every host. + + + Check to be sure you see the new SCSI disk. + # ls /dev/disk/by-id/scsi-360a98000503365344e6f6177615a516b -l + The output should look like this, although the specific file name will be different + (scsi-<scsiID>): + lrwxrwxrwx 1 root root 9 Mar 16 13:47 /dev/disk/by-id/scsi-360a98000503365344e6f6177615a516b -> ../../sdc - Repeat step 4 on every host. - On the storage server, run this command to get a unique ID for the new SR. - # uuidgen - The output should look like this, although the specific ID will be different: - e6849e96-86c3-4f2c-8fcc-350cc711be3d + Repeat step 4 on every host. - Create the FiberChannel SR. In name-label, use the unique ID you just generated. - + On the storage server, run this command to get a unique ID for the new SR. + # uuidgen + The output should look like this, although the specific ID will be different: + e6849e96-86c3-4f2c-8fcc-350cc711be3d + + + Create the FiberChannel SR. In name-label, use the unique ID you just + generated. + # xe sr-create type=lvmohba shared=true device-config:SCSIid=360a98000503365344e6f6177615a516b name-label="e6849e96-86c3-4f2c-8fcc-350cc711be3d" - This command returns a unique ID for the SR, like the following example (your ID will be different): - 7a143820-e893-6c6a-236e-472da6ee66bf + This command returns a unique ID for the SR, like the following example (your ID will + be different): + 7a143820-e893-6c6a-236e-472da6ee66bf - To create a human-readable description for the SR, use the following command. In uuid, use the SR ID returned by the previous command. In name-description, set whatever friendly text you prefer. - # xe sr-param-set uuid=7a143820-e893-6c6a-236e-472da6ee66bf name-description="Fiber Channel storage repository" - Make note of the values you will need when you add this storage to &PRODUCT; later (see ). In the Add Primary Storage dialog, in Protocol, you will choose PreSetup. In SR Name-Label, you will enter the name-label you set earlier (in this example, e6849e96-86c3-4f2c-8fcc-350cc711be3d). + To create a human-readable description for the SR, use the following command. In uuid, + use the SR ID returned by the previous command. In name-description, set whatever friendly + text you prefer. + # xe sr-param-set uuid=7a143820-e893-6c6a-236e-472da6ee66bf name-description="Fiber Channel storage repository" + Make note of the values you will need when you add this storage to &PRODUCT; later + (see ). In the Add Primary Storage dialog, in + Protocol, you will choose PreSetup. In SR Name-Label, you will enter the name-label you + set earlier (in this example, e6849e96-86c3-4f2c-8fcc-350cc711be3d). - (Optional) If you want to enable multipath I/O on a FiberChannel SAN, refer to the documentation provided by the SAN vendor. - -
-
- iSCSI Multipath Setup for XenServer (Optional) - When setting up the storage repository on a Citrix XenServer, you can enable multipath I/O, which uses redundant physical components to provide greater reliability in the connection between the server and the SAN. To enable multipathing, use a SAN solution that is supported for Citrix servers and follow the procedures in Citrix documentation. The following links provide a starting point: - - http://support.citrix.com/article/CTX118791 - http://support.citrix.com/article/CTX125403 - - You can also ask your SAN vendor for advice about setting up your Citrix repository for multipathing. - Make note of the values you will need when you add this storage to the &PRODUCT; later (see ). In the Add Primary Storage dialog, in Protocol, you will choose PreSetup. In SR Name-Label, you will enter the same name used to create the SR. - If you encounter difficulty, address the support team for the SAN provided by your vendor. If they are not able to solve your issue, see Contacting Support. -
-
- Physical Networking Setup for XenServer - Once XenServer has been installed, you may need to do some additional network configuration. At this point in the installation, you should have a plan for what NICs the host will have and what traffic each NIC will carry. The NICs should be cabled as necessary to implement your plan. - If you plan on using NIC bonding, the NICs on all hosts in the cluster must be cabled exactly the same. For example, if eth0 is in the private bond on one host in a cluster, then eth0 must be in the private bond on all hosts in the cluster. - The IP address assigned for the management network interface must be static. It can be set on the host itself or obtained via static DHCP. - &PRODUCT; configures network traffic of various types to use different NICs or bonds on the XenServer host. You can control this process and provide input to the Management Server through the use of XenServer network name labels. The name labels are placed on physical interfaces or bonds and configured in &PRODUCT;. In some simple cases the name labels are not required. -
- Configuring Public Network with a Dedicated NIC for XenServer (Optional) - &PRODUCT; supports the use of a second NIC (or bonded pair of NICs, described in ) for the public network. If bonding is not used, the public network can be on any NIC and can be on different NICs on the hosts in a cluster. For example, the public network can be on eth0 on node A and eth1 on node B. However, the XenServer name-label for the public network must be identical across all hosts. The following examples set the network label to "cloud-public". After the management server is installed and running you must configure it with the name of the chosen network label (e.g. "cloud-public"); this is discussed in . - If you are using two NICs bonded together to create a public network, see . - If you are using a single dedicated NIC to provide public network access, follow this procedure on each new host that is added to &PRODUCT; before adding the host. - - Run xe network-list and find the public network. This is usually attached to the NIC that is public. Once you find the network make note of its UUID. Call this <UUID-Public>. - - Run the following command. - # xe network-param-set name-label=cloud-public uuid=<UUID-Public> - - + + (Optional) If you want to enable multipath I/O on a FiberChannel SAN, refer to the + documentation provided by the SAN vendor. + +
-
+
+ iSCSI Multipath Setup for XenServer (Optional) + When setting up the storage repository on a Citrix XenServer, you can enable multipath + I/O, which uses redundant physical components to provide greater reliability in the connection + between the server and the SAN. To enable multipathing, use a SAN solution that is supported + for Citrix servers and follow the procedures in Citrix documentation. The following links + provide a starting point: + + + http://support.citrix.com/article/CTX118791 + + + http://support.citrix.com/article/CTX125403 + + + You can also ask your SAN vendor for advice about setting up your Citrix repository for + multipathing. + Make note of the values you will need when you add this storage to the &PRODUCT; later + (see ). In the Add Primary Storage dialog, in Protocol, + you will choose PreSetup. In SR Name-Label, you will enter the same name used to create the + SR. + If you encounter difficulty, address the support team for the SAN provided by your vendor. + If they are not able to solve your issue, see Contacting Support. +
+
+ Physical Networking Setup for XenServer + Once XenServer has been installed, you may need to do some additional network + configuration. At this point in the installation, you should have a plan for what NICs the + host will have and what traffic each NIC will carry. The NICs should be cabled as necessary to + implement your plan. + If you plan on using NIC bonding, the NICs on all hosts in the cluster must be cabled + exactly the same. For example, if eth0 is in the private bond on one host in a cluster, then + eth0 must be in the private bond on all hosts in the cluster. + The IP address assigned for the management network interface must be static. It can be set + on the host itself or obtained via static DHCP. + &PRODUCT; configures network traffic of various types to use different NICs or bonds on + the XenServer host. You can control this process and provide input to the Management Server + through the use of XenServer network name labels. The name labels are placed on physical + interfaces or bonds and configured in &PRODUCT;. In some simple cases the name labels are not + required. +
+ Configuring Public Network with a Dedicated NIC for XenServer (Optional) + &PRODUCT; supports the use of a second NIC (or bonded pair of NICs, described in ) for the public network. If bonding is not used, the + public network can be on any NIC and can be on different NICs on the hosts in a cluster. For + example, the public network can be on eth0 on node A and eth1 on node B. However, the + XenServer name-label for the public network must be identical across all hosts. The + following examples set the network label to "cloud-public". After the management + server is installed and running you must configure it with the name of the chosen network + label (e.g. "cloud-public"); this is discussed in . + If you are using two NICs bonded together to create a public network, see . + If you are using a single dedicated NIC to provide public network access, follow this + procedure on each new host that is added to &PRODUCT; before adding the host. + + + Run xe network-list and find the public network. This is usually attached to the NIC + that is public. Once you find the network make note of its UUID. Call this + <UUID-Public>. + + + Run the following command. + # xe network-param-set name-label=cloud-public uuid=<UUID-Public> + + +
+
Configuring Multiple Guest Networks for XenServer (Optional) - &PRODUCT; supports the use of multiple guest networks with the XenServer hypervisor. Each network is assigned a name-label in XenServer. For example, you might have two networks with the labels "cloud-guest" and "cloud-guest2". After the management server is installed and running, you must add the networks and use these labels so that &PRODUCT; is aware of the networks. + &PRODUCT; supports the use of multiple guest networks with the XenServer hypervisor. + Each network is assigned a name-label in XenServer. For example, you might have two networks + with the labels "cloud-guest" and "cloud-guest2". After the management + server is installed and running, you must add the networks and use these labels so that + &PRODUCT; is aware of the networks. Follow this procedure on each new host before adding the host to &PRODUCT;: - Run xe network-list and find one of the guest networks. Once you find the network make note of its UUID. Call this <UUID-Guest>. - - Run the following command, substituting your own name-label and uuid values. - # xe network-param-set name-label=<cloud-guestN> uuid=<UUID-Guest> - - Repeat these steps for each additional guest network, using a different name-label and uuid each time. + + Run xe network-list and find one of the guest networks. Once you find the network + make note of its UUID. Call this <UUID-Guest>. + + + Run the following command, substituting your own name-label and uuid values. + # xe network-param-set name-label=<cloud-guestN> uuid=<UUID-Guest> + + + Repeat these steps for each additional guest network, using a different name-label + and uuid each time. + -
-
+
+
Separate Storage Network for XenServer (Optional) - You can optionally set up a separate storage network. This should be done first on the host, before implementing the bonding steps below. This can be done using one or two available NICs. With two NICs bonding may be done as above. It is the administrator's responsibility to set up a separate storage network. - Give the storage network a different name-label than what will be given for other networks. - For the separate storage network to work correctly, it must be the only interface that can ping the primary storage device's IP address. For example, if eth0 is the management network NIC, ping -I eth0 <primary storage device IP> must fail. In all deployments, secondary storage devices must be pingable from the management network NIC or bond. If a secondary storage device has been placed on the storage network, it must also be pingable via the storage network NIC or bond on the hosts as well. - You can set up two separate storage networks as well. For example, if you intend to implement iSCSI multipath, dedicate two non-bonded NICs to multipath. Each of the two networks needs a unique name-label. - If no bonding is done, the administrator must set up and name-label the separate storage network on all hosts (masters and slaves). + You can optionally set up a separate storage network. This should be done first on the + host, before implementing the bonding steps below. This can be done using one or two + available NICs. With two NICs bonding may be done as above. It is the administrator's + responsibility to set up a separate storage network. + Give the storage network a different name-label than what will be given for other + networks. + For the separate storage network to work correctly, it must be the only interface that + can ping the primary storage device's IP address. For example, if eth0 is the + management network NIC, ping -I eth0 <primary storage device IP> must fail. In all + deployments, secondary storage devices must be pingable from the management network NIC or + bond. If a secondary storage device has been placed on the storage network, it must also be + pingable via the storage network NIC or bond on the hosts as well. + You can set up two separate storage networks as well. For example, if you intend to + implement iSCSI multipath, dedicate two non-bonded NICs to multipath. Each of the two + networks needs a unique name-label. + If no bonding is done, the administrator must set up and name-label the separate storage + network on all hosts (masters and slaves). Here is an example to set up eth5 to access a storage network on 172.16.0.0/24. # xe pif-list host-name-label='hostname' device=eth5 -uuid ( RO) : ab0d3dd4-5744-8fae-9693-a022c7a3471d - device ( RO): eth5 +uuid(RO): ab0d3dd4-5744-8fae-9693-a022c7a3471d +device ( RO): eth5 #xe pif-reconfigure-ip DNS=172.16.3.3 gateway=172.16.0.1 IP=172.16.0.55 mode=static netmask=255.255.255.0 uuid=ab0d3dd4-5744-8fae-9693-a022c7a3471d -
-
+
+
NIC Bonding for XenServer (Optional) - XenServer supports Source Level Balancing (SLB) NIC bonding. Two NICs can be bonded together to carry public, private, and guest traffic, or some combination of these. Separate storage networks are also possible. Here are some example supported configurations: + XenServer supports Source Level Balancing (SLB) NIC bonding. Two NICs can be bonded + together to carry public, private, and guest traffic, or some combination of these. Separate + storage networks are also possible. Here are some example supported configurations: - 2 NICs on private, 2 NICs on public, 2 NICs on storage - 2 NICs on private, 1 NIC on public, storage uses management network - 2 NICs on private, 2 NICs on public, storage uses management network - 1 NIC for private, public, and storage + + 2 NICs on private, 2 NICs on public, 2 NICs on storage + + + 2 NICs on private, 1 NIC on public, storage uses management network + + + 2 NICs on private, 2 NICs on public, storage uses management network + + + 1 NIC for private, public, and storage + All NIC bonding is optional. - XenServer expects all nodes in a cluster will have the same network cabling and same bonds implemented. In an installation the master will be the first host that was added to the cluster and the slave hosts will be all subsequent hosts added to the cluster. The bonds present on the master set the expectation for hosts added to the cluster later. The procedure to set up bonds on the master and slaves are different, and are described below. There are several important implications of this: + XenServer expects all nodes in a cluster will have the same network cabling and same + bonds implemented. In an installation the master will be the first host that was added to + the cluster and the slave hosts will be all subsequent hosts added to the cluster. The bonds + present on the master set the expectation for hosts added to the cluster later. The + procedure to set up bonds on the master and slaves are different, and are described below. + There are several important implications of this: - You must set bonds on the first host added to a cluster. Then you must use xe commands as below to establish the same bonds in the second and subsequent hosts added to a cluster. - Slave hosts in a cluster must be cabled exactly the same as the master. For example, if eth0 is in the private bond on the master, it must be in the management network for added slave hosts. + + You must set bonds on the first host added to a cluster. Then you must use xe + commands as below to establish the same bonds in the second and subsequent hosts added + to a cluster. + + + Slave hosts in a cluster must be cabled exactly the same as the master. For example, + if eth0 is in the private bond on the master, it must be in the management network for + added slave hosts. +
- Management Network Bonding - The administrator must bond the management network NICs prior to adding the host to &PRODUCT;. + Management Network Bonding + The administrator must bond the management network NICs prior to adding the host to + &PRODUCT;.
- Creating a Private Bond on the First Host in the Cluster - Use the following steps to create a bond in XenServer. These steps should be run on only the first host in a cluster. This example creates the cloud-private network with two physical NICs (eth0 and eth1) bonded into it. - - - Find the physical NICs that you want to bond together. - -# xe pif-list host-name-label='hostname' device=eth0 + Creating a Private Bond on the First Host in the Cluster + Use the following steps to create a bond in XenServer. These steps should be run on + only the first host in a cluster. This example creates the cloud-private network with two + physical NICs (eth0 and eth1) bonded into it. + + + Find the physical NICs that you want to bond together. + # xe pif-list host-name-label='hostname' device=eth0 # xe pif-list host-name-label='hostname' device=eth1 - These command shows the eth0 and eth1 NICs and their UUIDs. Substitute the ethX devices of your choice. Call the UUID's returned by the above command slave1-UUID and slave2-UUID. - - - Create a new network for the bond. For example, a new network with name "cloud-private". - This label is important. &PRODUCT; looks for a network by a name you configure. You must use the same name-label for all hosts in the cloud for the management network. - -# xe network-create name-label=cloud-private + These command shows the eth0 and eth1 NICs and their UUIDs. Substitute the ethX + devices of your choice. Call the UUID's returned by the above command slave1-UUID + and slave2-UUID. + + + Create a new network for the bond. For example, a new network with name + "cloud-private". + This label is important. &PRODUCT; looks for a network by a + name you configure. You must use the same name-label for all hosts in the cloud for + the management network. + # xe network-create name-label=cloud-private # xe bond-create network-uuid=[uuid of cloud-private created above] pif-uuids=[slave1-uuid],[slave2-uuid] - - - Now you have a bonded pair that can be recognized by &PRODUCT; as the management network. + + + Now you have a bonded pair that can be recognized by &PRODUCT; as the management + network.
- Public Network Bonding - Bonding can be implemented on a separate, public network. The administrator is responsible for creating a bond for the public network if that network will be bonded and will be separate from the management network. + Public Network Bonding + Bonding can be implemented on a separate, public network. The administrator is + responsible for creating a bond for the public network if that network will be bonded and + will be separate from the management network.
- Creating a Public Bond on the First Host in the Cluster - These steps should be run on only the first host in a cluster. This example creates the cloud-public network with two physical NICs (eth2 and eth3) bonded into it. - - - Find the physical NICs that you want to bond together. - -#xe pif-list host-name-label='hostname' device=eth2 + Creating a Public Bond on the First Host in the Cluster + These steps should be run on only the first host in a cluster. This example creates + the cloud-public network with two physical NICs (eth2 and eth3) bonded into it. + + + Find the physical NICs that you want to bond together. + #xe pif-list host-name-label='hostname' device=eth2 # xe pif-list host-name-label='hostname' device=eth3 - These command shows the eth2 and eth3 NICs and their UUIDs. Substitute the ethX devices of your choice. Call the UUID's returned by the above command slave1-UUID and slave2-UUID. - - - Create a new network for the bond. For example, a new network with name "cloud-public". - This label is important. &PRODUCT; looks for a network by a name you configure. You must use the same name-label for all hosts in the cloud for the public network. - -# xe network-create name-label=cloud-public + These command shows the eth2 and eth3 NICs and their UUIDs. Substitute the ethX + devices of your choice. Call the UUID's returned by the above command slave1-UUID + and slave2-UUID. + + + Create a new network for the bond. For example, a new network with name + "cloud-public". + This label is important. &PRODUCT; looks for a network by a + name you configure. You must use the same name-label for all hosts in the cloud for + the public network. + # xe network-create name-label=cloud-public # xe bond-create network-uuid=[uuid of cloud-public created above] pif-uuids=[slave1-uuid],[slave2-uuid] - - - Now you have a bonded pair that can be recognized by &PRODUCT; as the public network. + + + Now you have a bonded pair that can be recognized by &PRODUCT; as the public + network.
- Adding More Hosts to the Cluster - With the bonds (if any) established on the master, you should add additional, slave hosts. Run the following command for all additional hosts to be added to the cluster. This will cause the host to join the master in a single XenServer pool. - -# xe pool-join master-address=[master IP] master-username=root + Adding More Hosts to the Cluster + With the bonds (if any) established on the master, you should add additional, slave + hosts. Run the following command for all additional hosts to be added to the cluster. This + will cause the host to join the master in a single XenServer pool. + # xe pool-join master-address=[master IP] master-username=root master-password=[your password]
- Complete the Bonding Setup Across the Cluster - With all hosts added to the pool, run the cloud-setup-bond script. This script will complete the configuration and set up of the bonds across all hosts in the cluster. - - Copy the script from the Management Server in /usr/lib64/cloud/agent/scripts/vm/hypervisor/xenserver/cloud-setup-bonding.sh to the master host and ensure it is executable. - - Run the script: - # ./cloud-setup-bonding.sh - - - Now the bonds are set up and configured properly across the cluster. + Complete the Bonding Setup Across the Cluster + With all hosts added to the pool, run the cloud-setup-bond script. This script will + complete the configuration and set up of the bonds across all hosts in the cluster. + + + Copy the script from the Management Server in + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/cloud-setup-bonding.sh to the + master host and ensure it is executable. + + + Run the script: + # ./cloud-setup-bonding.sh + + + Now the bonds are set up and configured properly across the cluster.
-
-
- Upgrading XenServer Versions - This section tells how to upgrade XenServer software on &PRODUCT; hosts. The actual upgrade is described in XenServer documentation, but there are some additional steps you must perform before and after the upgrade. - Be sure the hardware is certified compatible with the new version of XenServer. - To upgrade XenServer: - +
+
+ Upgrading XenServer Versions + This section tells how to upgrade XenServer software on &PRODUCT; hosts. The actual + upgrade is described in XenServer documentation, but there are some additional steps you must + perform before and after the upgrade. + + Be sure the hardware is certified compatible with the new version of XenServer. + + To upgrade XenServer: + - Upgrade the database. On the Management Server node: - - - Back up the database: - -# mysqldump --user=root --databases cloud > cloud.backup.sql + Upgrade the database. On the Management Server node: + + + Back up the database: + # mysqldump --user=root --databases cloud > cloud.backup.sql # mysqldump --user=root --databases cloud_usage > cloud_usage.backup.sql - - - You might need to change the OS type settings for VMs running on the upgraded hosts. - - If you upgraded from XenServer 5.6 GA to XenServer 5.6 SP2, change any VMs that have the OS type CentOS 5.5 (32-bit), Oracle Enterprise Linux 5.5 (32-bit), or Red Hat Enterprise Linux 5.5 (32-bit) to Other Linux (32-bit). Change any VMs that have the 64-bit versions of these same OS types to Other Linux (64-bit). - If you upgraded from XenServer 5.6 SP2 to XenServer 6.0.2, change any VMs that have the OS type CentOS 5.6 (32-bit), CentOS 5.7 (32-bit), Oracle Enterprise Linux 5.6 (32-bit), Oracle Enterprise Linux 5.7 (32-bit), Red Hat Enterprise Linux 5.6 (32-bit) , or Red Hat Enterprise Linux 5.7 (32-bit) to Other Linux (32-bit). Change any VMs that have the 64-bit versions of these same OS types to Other Linux (64-bit). - If you upgraded from XenServer 5.6 to XenServer 6.0.2, do all of the above. - - - - Restart the Management Server and Usage Server. You only need to do this once for all clusters. - -# service cloud-management start + + + You might need to change the OS type settings for VMs running on the upgraded + hosts. + + + If you upgraded from XenServer 5.6 GA to XenServer 5.6 SP2, change any VMs + that have the OS type CentOS 5.5 (32-bit), Oracle Enterprise Linux 5.5 (32-bit), + or Red Hat Enterprise Linux 5.5 (32-bit) to Other Linux (32-bit). Change any VMs + that have the 64-bit versions of these same OS types to Other Linux + (64-bit). + + + If you upgraded from XenServer 5.6 SP2 to XenServer 6.0.2, change any VMs that + have the OS type CentOS 5.6 (32-bit), CentOS 5.7 (32-bit), Oracle Enterprise Linux + 5.6 (32-bit), Oracle Enterprise Linux 5.7 (32-bit), Red Hat Enterprise Linux 5.6 + (32-bit) , or Red Hat Enterprise Linux 5.7 (32-bit) to Other Linux (32-bit). + Change any VMs that have the 64-bit versions of these same OS types to Other Linux + (64-bit). + + + If you upgraded from XenServer 5.6 to XenServer 6.0.2, do all of the + above. + + + + + Restart the Management Server and Usage Server. You only need to do this once for + all clusters. + # service cloud-management start # service cloud-usage start - - + + - Disconnect the XenServer cluster from &PRODUCT;. - - Log in to the &PRODUCT; UI as root. - Navigate to the XenServer cluster, and click Actions – Unmanage. - Watch the cluster status until it shows Unmanaged. - + Disconnect the XenServer cluster from &PRODUCT;. + + + Log in to the &PRODUCT; UI as root. + + + Navigate to the XenServer cluster, and click Actions – Unmanage. + + + Watch the cluster status until it shows Unmanaged. + + - Log in to one of the hosts in the cluster, and run this command to clean up the VLAN: - # . /opt/xensource/bin/cloud-clean-vlan.sh + Log in to one of the hosts in the cluster, and run this command to clean up the + VLAN: + # . /opt/xensource/bin/cloud-clean-vlan.sh - Still logged in to the host, run the upgrade preparation script: - # /opt/xensource/bin/cloud-prepare-upgrade.sh - Troubleshooting: If you see the error "can't eject CD," log in to the VM and umount the CD, then run the script again. + Still logged in to the host, run the upgrade preparation script: + # /opt/xensource/bin/cloud-prepare-upgrade.sh + Troubleshooting: If you see the error "can't eject CD," log in to the + VM and umount the CD, then run the script again. - Upgrade the XenServer software on all hosts in the cluster. Upgrade the master first. - - - Live migrate all VMs on this host to other hosts. See the instructions for live migration in the Administrator's Guide. - Troubleshooting: You might see the following error when you migrate a VM: - -[root@xenserver-qa-2-49-4 ~]# xe vm-migrate live=true host=xenserver-qa-2-49-5 vm=i-2-8-VM + Upgrade the XenServer software on all hosts in the cluster. Upgrade the master + first. + + + Live migrate all VMs on this host to other hosts. See the instructions for live + migration in the Administrator's Guide. + Troubleshooting: You might see the following error when you migrate a VM: + [root@xenserver-qa-2-49-4 ~]# xe vm-migrate live=true host=xenserver-qa-2-49-5 vm=i-2-8-VM You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected. vm: b6cf79c8-02ee-050b-922f-49583d9f1a14 (i-2-8-VM) - To solve this issue, run the following: - # /opt/xensource/bin/make_migratable.sh b6cf79c8-02ee-050b-922f-49583d9f1a14 - - Reboot the host. - Upgrade to the newer version of XenServer. Use the steps in XenServer documentation. - - After the upgrade is complete, copy the following files from the management server to this host, in the directory locations shown below: - - - - - - - Copy this Management Server file... - ...to this location on the XenServer host - - - - - /usr/lib64/cloud/agent/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py - /opt/xensource/sm/NFSSR.py - - - /usr/lib64/cloud/agent/scripts/vm/hypervisor/xenserver/setupxenserver.sh - /opt/xensource/bin/setupxenserver.sh - - - /usr/lib64/cloud/agent/scripts/vm/hypervisor/xenserver/make_migratable.sh - /opt/xensource/bin/make_migratable.sh - - - /usr/lib64/cloud/agent/scripts/vm/hypervisor/xenserver/cloud-clean-vlan.sh - /opt/xensource/bin/cloud-clean-vlan.sh - - - - - - - Run the following script: - # /opt/xensource/bin/setupxenserver.sh - Troubleshooting: If you see the following error message, you can safely ignore it. - mv: cannot stat `/etc/cron.daily/logrotate': No such file or directory - - - Plug in the storage repositories (physical block devices) to the XenServer host: - # for pbd in `xe pbd-list currently-attached=false| grep ^uuid | awk '{print $NF}'`; do xe pbd-plug uuid=$pbd ; done - Note: If you add a host to this XenServer pool, you need to migrate all VMs on this host to other hosts, and eject this host from XenServer pool. - + To solve this issue, run the following: + # /opt/xensource/bin/make_migratable.sh b6cf79c8-02ee-050b-922f-49583d9f1a14 + + + Reboot the host. + + + Upgrade to the newer version of XenServer. Use the steps in XenServer + documentation. + + + After the upgrade is complete, copy the following files from the management server + to this host, in the directory locations shown below: + + + + + + + Copy this Management Server file... + ...to this location on the XenServer host + + + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py + /opt/xensource/sm/NFSSR.py + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/setupxenserver.sh + /opt/xensource/bin/setupxenserver.sh + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/make_migratable.sh + /opt/xensource/bin/make_migratable.sh + + + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/cloud-clean-vlan.sh + /opt/xensource/bin/cloud-clean-vlan.sh + + + + + + + Run the following script: + # /opt/xensource/bin/setupxenserver.sh + Troubleshooting: If you see the following error message, you can safely ignore + it. + mv: cannot stat `/etc/cron.daily/logrotate': No such file or directory + + + Plug in the storage repositories (physical block devices) to the XenServer + host: + # for pbd in `xe pbd-list currently-attached=false| grep ^uuid | awk '{print $NF}'`; do xe pbd-plug uuid=$pbd ; done + Note: If you add a host to this XenServer pool, you need to migrate all VMs on + this host to other hosts, and eject this host from XenServer pool. + + + + + Repeat these steps to upgrade every host in the cluster to the same version of + XenServer. + + + Run the following command on one host in the XenServer cluster to clean up the host + tags: + # for host in $(xe host-list | grep ^uuid | awk '{print $NF}') ; do xe host-param-clear uuid=$host param-name=tags; done; + + When copying and pasting a command, be sure the command has pasted as a single line + before executing. Some document viewers may introduce unwanted line breaks in copied + text. + + + + Reconnect the XenServer cluster to &PRODUCT;. + + + Log in to the &PRODUCT; UI as root. + + + Navigate to the XenServer cluster, and click Actions – Manage. + + + Watch the status to see that all the hosts come up. + + + + + After all hosts are up, run the following on one host in the cluster: + # /opt/xensource/bin/cloud-clean-vlan.sh + - - Repeat these steps to upgrade every host in the cluster to the same version of XenServer. - - Run the following command on one host in the XenServer cluster to clean up the host tags: - # for host in $(xe host-list | grep ^uuid | awk '{print $NF}') ; do xe host-param-clear uuid=$host param-name=tags; done; - When copying and pasting a command, be sure the command has pasted as a single line before executing. Some document viewers may introduce unwanted line breaks in copied text. - - - Reconnect the XenServer cluster to &PRODUCT;. - - Log in to the &PRODUCT; UI as root. - Navigate to the XenServer cluster, and click Actions – Manage. - Watch the status to see that all the hosts come up. - - - - After all hosts are up, run the following on one host in the cluster: - # /opt/xensource/bin/cloud-clean-vlan.sh - - -
+
diff --git a/docs/en-US/cloud-infrastructure-concepts.xml b/docs/en-US/cloud-infrastructure-concepts.xml index 58f8844c826..1e1865e04f4 100644 --- a/docs/en-US/cloud-infrastructure-concepts.xml +++ b/docs/en-US/cloud-infrastructure-concepts.xml @@ -22,7 +22,7 @@ under the License. --> -
+ Cloud Infrastructure Concepts @@ -31,4 +31,4 @@ -
+ diff --git a/docs/en-US/cloud-infrastructure-overview.xml b/docs/en-US/cloud-infrastructure-overview.xml index 5b467a33d4c..49a413871a5 100644 --- a/docs/en-US/cloud-infrastructure-overview.xml +++ b/docs/en-US/cloud-infrastructure-overview.xml @@ -25,15 +25,48 @@
Cloud Infrastructure Overview - The Management Server manages one or more zones (typically, datacenters) containing host computers where guest virtual machines will run. The cloud infrastructure is organized as follows: + The Management Server manages one or more zones (typically, + datacenters) containing host computers where guest virtual + machines will run. The cloud infrastructure is organized as follows: - Zone: Typically, a zone is equivalent to a single datacenter. A zone consists of one or more pods and secondary storage. - Pod: A pod is usually one rack of hardware that includes a layer-2 switch and one or more clusters. - Cluster: A cluster consists of one or more hosts and primary storage. - Host: A single compute node within a cluster. The hosts are where the actual cloud services run in the form of guest virtual machines. - Primary storage is associated with a cluster, and it stores the disk volumes for all the VMs running on hosts in that cluster. - Secondary storage is associated with a zone, and it stores templates, ISO images, and disk volume snapshots. + + + Zone: Typically, a zone is equivalent to a single + datacenter. A zone consists of one or more pods and secondary + storage. + + + + + Pod: A pod is usually one rack of hardware that includes a + layer-2 switch and one or more clusters. + + + + + Cluster: A cluster consists of one or more hosts and primary + storage. + + + + + Host: A single compute node within a cluster. The hosts are + where the actual cloud services run in the form of guest + virtual machines. + + + + + Primary storage is associated with a cluster, and it stores + the disk volumes for all the VMs running on hosts in that cluster. + + + + Secondary storage is associated with a zone, and it stores + templates, ISO images, and disk volume snapshots. + + @@ -42,5 +75,5 @@ infrastructure_overview.png: Nested organization of a zone More Information - For more information, see . + For more information, see documentation on cloud infrastructure concepts.
diff --git a/docs/en-US/cloudstack.xml b/docs/en-US/cloudstack.xml index c18bc194cfe..c745bc95fe7 100644 --- a/docs/en-US/cloudstack.xml +++ b/docs/en-US/cloudstack.xml @@ -1,33 +1,79 @@ - %BOOK_ENTITIES; ]> - + + &PRODUCT; Complete Documentation + Apache CloudStack + 4.0.0-incubating + 1 + + + + Complete documentation for &PRODUCT;. + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/en-US/cloudstack_features.xml b/docs/en-US/cloudstack_features.xml deleted file mode 100644 index 95825aa2758..00000000000 --- a/docs/en-US/cloudstack_features.xml +++ /dev/null @@ -1,66 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - -
- What Can &PRODUCT; Do? - - - Multiple Hypervisor Support - - - &PRODUCT; works with a variety of hypervisors. A single cloud deployment can contain multiple hypervisor implementations. You have the complete freedom to choose the right hypervisor for your workload. &PRODUCT; is designed to work with open source Xen and KVM hypervisors as well as enterprise-grade hypervisors such as Citrix XenServer, VMware vSphere, and Oracle VM (OVM). You can also provision “bare metal” hosts with no hypervisor (Beta feature. Untested in &PRODUCT; 3.0.x0.) - - - Massively Scalable Infrastructure Management - - - &PRODUCT; can manage tens of thousands of servers installed in multiple geographically distributed datacenters. The centralized management server scales linearly, eliminating the need for intermediate cluster-level management servers. No single component failure can cause cloud-wide outage. Periodic maintenance of the management server can be performed without affecting the functioning of virtual machines running in the cloud. - - - Automatic Configuration Management - - &PRODUCT; automatically configures each guest virtual machine’s networking and storage settings. - - &PRODUCT; internally manages a pool of virtual appliances to support the cloud itself. These appliances offer services such as firewalling, routing, DHCP, VPN access, console proxy, storage access, and storage replication. The extensive use of virtual appliances simplifies the installation, configuration, and ongoing management of a cloud deployment. - - - Graphical User Interface - - &PRODUCT; offers an administrator's Web interface, used for provisioning and managing the cloud, as well as an end-user's Web interface, used for running VMs and managing VM templates. The UI can be customized to reflect the desired service provider or enterprise look and feel. - - - API and Extensibility - - - &PRODUCT; provides an API that gives programmatic access to all the management features available in the UI. The API is maintained and documented. This API enables the creation of command line tools and new user interfaces to suit particular needs. See the Developer’s Guide and API Reference, both available at http://docs.cloud.com/CloudStack_Documentation. - - - The &PRODUCT; platform pluggable allocation architecture allows the creation of new types of allocators for the selection of storage and Hosts. See the Allocator Implementation Guide (http://docs.cloud.com/CloudStack_Documentation/Allocator_Implementation_Guide). - - - High Availability - - The &PRODUCT; platform has a number of features to increase the availability of the system. The Management Server itself may be deployed in a multi-node installation where the servers are load balanced. MySQL may be configured to use replication to provide for a manual failover in the event of database loss. For the Hosts, the &PRODUCT; platform supports NIC bonding and the use of separate networks for storage as well as iSCSI Multipath. - -
diff --git a/docs/en-US/cloudstack_system_requirements.xml b/docs/en-US/cloudstack_system_requirements.xml deleted file mode 100644 index 8b5d709c441..00000000000 --- a/docs/en-US/cloudstack_system_requirements.xml +++ /dev/null @@ -1,68 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - -
- Minimum System Requirements - - The machines that will run the Management Server and MySQL database must meet the following requirements. The same machines can also be used to provide primary and secondary storage, such as via localdisk or NFS. The Management Server may be placed on a virtual machine. - - - Operating system: - - Commercial users: Preferred: RHEL 6.2+ 64-bit (https://access.redhat.com/downloads) or CentOS 6.2+ 64-bit (http://isoredirect.centos.org/centos/6/isos/x86_64/). Also supported (v3.0.3 and greater): RHEL and CentOS 5.4-5.x 64-bit - Open-source community users: RHEL 5.4-5.x 64-bit or 6.2+ 64-bit; CentOS 5.4-5.x 64-bit or 6.2+ 64-bit; Ubuntu 10.04 LTS - - - 64-bit x86 CPU (more cores results in better performance) - 4 GB of memory - 250 GB of local disk (more results in better capability; 500 GB recommended) - At least 1 NIC - Statically allocated IP address - Fully qualified domain name as returned by the hostname command - - The host is where the cloud services run in the form of guest virtual machines. Each host is one machine that meets the following requirements: - - Must be 64-bit and must support HVM (Intel-VT or AMD-V enabled). - 64-bit x86 CPU (more cores results in better performance) - Hardware virtualization support required - 4 GB of memory - 36 GB of local disk - At least 1 NIC - Statically allocated IP Address - Latest hotfixes applied to hypervisor software - When you deploy &PRODUCT;, the hypervisor host must not have any VMs already running - - Hosts have additional requirements depending on the hypervisor. See the requirements listed at the top of the Installation section for your chosen hypervisor: - - Citrix XenServer Installation for &PRODUCT; - VMware vSphere Installation and Configuration - KVM Installation and Configuration - Oracle VM (OVM) Installation and Configuration - - - - Be sure you fulfill the additional hypervisor requirements and installation steps provided in this Guide. Hypervisor hosts must be properly prepared to work with &PRODUCT;. For example, the requirements for XenServer are listed under Citrix XenServer Installation for &PRODUCT;. - - -
diff --git a/docs/en-US/cloudstack_whatis.xml b/docs/en-US/cloudstack_whatis.xml deleted file mode 100644 index 5fea7d40199..00000000000 --- a/docs/en-US/cloudstack_whatis.xml +++ /dev/null @@ -1,39 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - - -
- What Is &PRODUCT;? - Who Should Read This - If you are new to &PRODUCT; or you want to learn more about concepts before installing and running &PRODUCT;, read this overview. If you just want to get started, you can skip to Overview of Installation Steps. - &PRODUCT; is an open source software platform that pools computing resources to build public, private, and hybrid Infrastructure as a Service (IaaS) clouds. &PRODUCT; manages the network, storage, and compute nodes that make up a cloud infrastructure. Use &PRODUCT; to deploy, manage, and configure cloud computing environments. Typical users are service providers and enterprises. With &PRODUCT;, you can: - - - Set up an on-demand, elastic cloud computing service. Service providers can sell self service virtual machine instances, storage volumes, and networking configurations over the Internet. - - Set up an on-premise private cloud for use by employees. Rather than managing virtual machines in the same way as physical machines, with &PRODUCT; an enterprise can offer self-service virtual machines to users without involving IT departments. - - - -
diff --git a/docs/en-US/cluster-add.xml b/docs/en-US/cluster-add.xml index 5210bd8b84c..3046c5e0dfd 100644 --- a/docs/en-US/cluster-add.xml +++ b/docs/en-US/cluster-add.xml @@ -1,28 +1,31 @@ - %BOOK_ENTITIES; ]>
- Adding a Cluster - TODO + Adding a Cluster + You need to tell &PRODUCT; about the hosts that it will manage. Hosts exist inside clusters, so before you begin adding hosts to the cloud, you must add at least one cluster. + + +
diff --git a/docs/en-US/compute-disk-service-offerings.xml b/docs/en-US/compute-disk-service-offerings.xml index 2469dfe3a15..1fd2a91a38b 100644 --- a/docs/en-US/compute-disk-service-offerings.xml +++ b/docs/en-US/compute-disk-service-offerings.xml @@ -5,33 +5,32 @@ ]> -
Compute and Disk Service Offerings - A service offering is a set of virtual hardware features such as CPU core count and speed, memory, and disk size. The CloudPlatform administrator can set up various offerings, and then end users choose from the available offerings when they create a new VM. A service offering includes the following elements: + A service offering is a set of virtual hardware features such as CPU core count and speed, memory, and disk size. The &PRODUCT; administrator can set up various offerings, and then end users choose from the available offerings when they create a new VM. A service offering includes the following elements: CPU, memory, and network resource guarantees How resources are metered How the resource usage is charged How often the charges are generated - For example, one service offering might allow users to create a virtual machine instance that is equivalent to a 1 GHz Intel Core 2 CPU, with 1 GB memory at $0.20/hour, with network traffic metered at $0.10/GB. Based on the user’s selected offering, CloudPlatform emits usage records that can be integrated with billing systems. CloudPlatform separates service offerings into compute offerings and disk offerings. The computing service offering specifies: + For example, one service offering might allow users to create a virtual machine instance that is equivalent to a 1 GHz Intel® Core™ 2 CPU, with 1 GB memory at $0.20/hour, with network traffic metered at $0.10/GB. Based on the user’s selected offering, &PRODUCT; emits usage records that can be integrated with billing systems. &PRODUCT; separates service offerings into compute offerings and disk offerings. The computing service offering specifies: Guest CPU Guest RAM @@ -43,4 +42,9 @@ Disk size (optional). An offering without a disk size will allow users to pick their own Tags on the data disk + + +
+ + diff --git a/docs/en-US/configure-acl.xml b/docs/en-US/configure-acl.xml new file mode 100644 index 00000000000..299196c5502 --- /dev/null +++ b/docs/en-US/configure-acl.xml @@ -0,0 +1,139 @@ + + +%BOOK_ENTITIES; +]> + +
+ Configuring Access Control List + Define Network Access Control List (ACL) on the VPC virtual router to control incoming + (ingress) and outgoing (egress) traffic between the VPC tiers, and the tiers and Internet. By + default, all incoming and outgoing traffic to the guest networks is blocked. To open the ports, + you must create a new network ACL. The network ACLs can be created for the tiers only if the + NetworkACL service is supported. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Select Network ACLs. + The Network ACLs page is displayed. + + + Click Add Network ACLs. + To add an ACL rule, fill in the following fields to specify what kind of network traffic + is allowed in this tier. + + + CIDR: The CIDR acts as the Source CIDR for the + Ingress rules, and Destination CIDR for the Egress rules. To accept traffic only from or + to the IP addresses within a particular address block, enter a CIDR or a comma-separated + list of CIDRs. The CIDR is the base IP address of the incoming traffic. For example, + 192.168.0.0/22. To allow all CIDRs, set to 0.0.0.0/0. + + + Protocol: The networking protocol that sources use + to send traffic to the tier. The TCP and UDP protocols are typically used for data + exchange and end-user communications. The ICMP protocol is typically used to send error + messages or network monitoring data. + + + Start Port, End + Port (TCP, UDP only): A range of listening ports that are the destination + for the incoming traffic. If you are opening a single port, use the same number in both + fields. + + + Select Tier: Select the tier for which you want to + add this ACL rule. + + + ICMP Type, ICMP + Code (ICMP only): The type of message and error code that will be + sent. + + + Traffic Type: Select the traffic type you want to + apply. + + + Egress: To add an egress rule, select Egress + from the Traffic type drop-down box and click Add. This specifies what type of + traffic is allowed to be sent out of VM instances in this tier. If no egress rules + are specified, all traffic from the tier is allowed out at the VPC virtual router. + Once egress rules are specified, only the traffic specified in egress rules and the + responses to any traffic that has been allowed in through an ingress rule are + allowed out. No egress rule is required for the VMs in a tier to communicate with + each other. + + + Ingress: To add an ingress rule, select Ingress + from the Traffic type drop-down box and click Add. This specifies what network + traffic is allowed into the VM instances in this tier. If no ingress rules are + specified, then no traffic will be allowed in, except for responses to any traffic + that has been allowed out through an egress rule. + + + + By default, all incoming and outgoing traffic to the guest networks is blocked. To + open the ports, create a new network ACL. + + + + + + Click Add. The ACL rule is added. + To view the list of ACL rules you have added, click the desired tier from the Network + ACLs page, then select the Network ACL tab. + + + + + + network-acl.png: adding, editing, deleting an ACL rule. + + + You can edit the tags assigned to the ACL rules and delete the ACL rules you have + created. Click the appropriate button in the Actions column. + + +
diff --git a/docs/en-US/configure-guest-traffic-in-advanced-zone.xml b/docs/en-US/configure-guest-traffic-in-advanced-zone.xml index 95df4730985..fb6685091a5 100644 --- a/docs/en-US/configure-guest-traffic-in-advanced-zone.xml +++ b/docs/en-US/configure-guest-traffic-in-advanced-zone.xml @@ -3,48 +3,77 @@ %BOOK_ENTITIES; ]> - -
- Configure Guest Traffic in an Advanced Zone - These steps assume you have already logged in to the &PRODUCT; UI. To configure the base guest network: - - In the left navigation, choose Infrastructure. On Zones, click View More, then click the zone to which you want to add a network. - Click the Network tab. - Click Add network. - Provide the following information: - - Name. The name of the network. This will be user-visible - Description: The description of the network. This will be user-visible - VLAN ID: Enter an administrator-configured VLAN ID so you can create different networks for use by different VM users in the zone - Scope: Choose account-specific or domain-specific if you would like to make the network accessible to only a single account or domain. Choose zone-wide if all accounts with access to the zone should be able to access the network. - Domain/Account: If Scope is account-specific, enter the domain and account name for the account - Network offering: If the administrator has configured multiple network offerings, select the one you want to use for this network - Gateway: The gateway that the guests should use - Netmask: The netmask in use on the subnet the guests will use - Start IP/End IP: Enter the first and last IP addresses that define a range that &PRODUCT; can assign to guests. If one NIC is used, these IPs should be in the same CIDR as the pod CIDR. If multiple NICs are used, they may be in a different subnet. - Network Domain: (Optional) If you want to assign a special domain name to this network, specify the DNS suffix. - + Configure Guest Traffic in an Advanced Zone + These steps assume you have already logged in to the &PRODUCT; UI. To configure the base + guest network: + + + In the left navigation, choose Infrastructure. On Zones, click View More, then click the + zone to which you want to add a network. + + + Click the Network tab. + + + Click Add guest network. + The Add guest network window is displayed: + + + + + + networksetupzone.png: Depicts network setup in a single zone + + + + + Provide the following information: + + + Name. The name of the network. This will be + user-visible - Click OK. - - - -
+ + Display Text: The description of the network. This + will be user-visible + + + Zone: The zone in which you are configuring the + guest network. + + + Network offering: If the administrator has + configured multiple network offerings, select the one you want to use for this + network + + + Guest Gateway: The gateway that the guests should + use + + + Guest Netmask: The netmask in use on the subnet the + guests will use + + + + + Click OK. + +
+
\ No newline at end of file diff --git a/docs/en-US/configure-package-repository.xml b/docs/en-US/configure-package-repository.xml new file mode 100644 index 00000000000..7687fa392ff --- /dev/null +++ b/docs/en-US/configure-package-repository.xml @@ -0,0 +1,72 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Configure package repository + &PRODUCT; is only distributed from source from the official mirrors. + However, members of the CloudStack community may build convenience binaries + so that users can install Apache CloudStack without needing to build from + source. + + + If you didn't follow the steps to build your own packages from source + in the sections for or + you may find pre-built + DEB and RPM packages for your convience linked from the + downloads + page. + + + These repositories contain both the Management Server and KVM Hypervisor packages. + +
+ DEB package repository + You can add a DEB package repository to your apt sources with the following commands. Please note that currently only packages for Ubuntu 12.04 LTS (precise) are being build. + Use your preferred editor and open (or create) /etc/apt/sources.list.d/cloudstack. Add the community provided repository to the file: +deb http://cloudstack.apt-get.eu/ubuntu precise 4.0 + We now have to add the public key to the trusted keys. + $ wget -O - http://cloudstack.apt-get.eu/release.asc|apt-key add - + Now update your local apt cache. + $ apt-get update + Your DEB package repository should now be configured and ready for use. +
+
+ RPM package repository + If you're using an RPM-based system, you'll want to add the Yum repository so that you can install CloudStack with Yum. + Yum repository information is found under /etc/yum.repos.d. You'll see several .repo files in this directory, each one denoting a specific repository. + To add the CloudStack repository, visit the downloads page for the repository information. It will look something like this: + +[cloudstack] +name=cloudstack +baseurl=http://server.url/downloads/rpm/stable/ +enabled=1 +gpgcheck=1 + + Next you'll want to add the GPG key: + +$ rpm --import http://server.url/downloads/RPM-GPG-KEY.txt + + Now you should be able to install CloudStack using Yum. +
+
diff --git a/docs/en-US/configure-public-traffic-in-an-advanced-zone.xml b/docs/en-US/configure-public-traffic-in-an-advanced-zone.xml index 960a1a3308b..7a61cd380af 100644 --- a/docs/en-US/configure-public-traffic-in-an-advanced-zone.xml +++ b/docs/en-US/configure-public-traffic-in-an-advanced-zone.xml @@ -3,7 +3,6 @@ %BOOK_ENTITIES; ]> - -
- Configure Public Traffic in an Advanced Zone - In a zone that uses advanced networking, you need to configure at least one range of IP addresses for Internet traffic. -
+ Configure Public Traffic in an Advanced Zone + In a zone that uses advanced networking, you need to configure at least one range of IP + addresses for Internet traffic. +
\ No newline at end of file diff --git a/docs/en-US/configure-usage-server.xml b/docs/en-US/configure-usage-server.xml index d167a497b16..af7bd4522f6 100644 --- a/docs/en-US/configure-usage-server.xml +++ b/docs/en-US/configure-usage-server.xml @@ -58,13 +58,13 @@ usage.execution.timezone = PST usage.aggregation.timezone = GMT - Valid values for the time zone are specified in + Valid values for the time zone are specified in Default: GMT usage.execution.timezone - The time zone of usage.stats.job.exec.time. Valid values for the time zone are specified in + The time zone of usage.stats.job.exec.time. Valid values for the time zone are specified in Default: The time zone of the management server. diff --git a/docs/en-US/configure-vpc.xml b/docs/en-US/configure-vpc.xml new file mode 100644 index 00000000000..45237d21cbb --- /dev/null +++ b/docs/en-US/configure-vpc.xml @@ -0,0 +1,36 @@ + + +%BOOK_ENTITIES; +]> + +
+ Configuring a Virtual Private Cloud + + + + + + + + + + + + + +
diff --git a/docs/en-US/configuring-projects.xml b/docs/en-US/configuring-projects.xml index e18843d15d6..0f84dd81454 100644 --- a/docs/en-US/configuring-projects.xml +++ b/docs/en-US/configuring-projects.xml @@ -1,9 +1,4 @@ - -%BOOK_ENTITIES; -]> - - + +%BOOK_ENTITIES; +]>
Configuring Projects - Before &PRODUCT; users start using projects, the &PRODUCT; administrator must set up various systems to support them, including membership invitations, limits on project resources, and controls on who can create projects + Before CloudPlatform users start using projects, the CloudPlatform administrator must set + up various systems to support them, including membership invitations, limits on project + resources, and controls on who can create projects. + + +
diff --git a/docs/en-US/create-template-from-snapshot.xml b/docs/en-US/create-template-from-snapshot.xml index 30750326c9f..80e660fe7c1 100644 --- a/docs/en-US/create-template-from-snapshot.xml +++ b/docs/en-US/create-template-from-snapshot.xml @@ -24,6 +24,6 @@
Creating a Template from a Snapshot - Not supported by Oracle VM + If you do not want to stop the VM in order to use the Create Template menu item (as described in ), you can create a template directly from any snapshot through the &PRODUCT; UI.
diff --git a/docs/en-US/create-vpn-connection-vpc.xml b/docs/en-US/create-vpn-connection-vpc.xml new file mode 100644 index 00000000000..1fba09e18fb --- /dev/null +++ b/docs/en-US/create-vpn-connection-vpc.xml @@ -0,0 +1,103 @@ + + +%BOOK_ENTITIES; +]> + +
+ Creating a VPN Connection + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you create for the account are listed in the page. + + + Click the Configure button of the VPC to which you want to deploy the VMs. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ASLs + + + + + Select Site-to-Site VPN. + The Site-to-Site VPN page is displayed. + + + From the Select View drop-down, ensure that VPN Connection is selected. + + + Click Create VPN Connection. + The Create VPN Connection dialog is displayed: + + + + + + createvpnconnection.png: creating a vpn connection to the customer + gateway. + + + + + Select the desired customer gateway, then click OK to confirm. + Within a few moments, the VPN Connection is displayed. + The following information on the VPN connection is displayed: + + + IP Address + + + Gateway + + + State + + + IPSec Preshared Key + + + IKE Policy + + + ESP Policy + + + + +
\ No newline at end of file diff --git a/docs/en-US/create-vpn-customer-gateway.xml b/docs/en-US/create-vpn-customer-gateway.xml new file mode 100644 index 00000000000..8bcd488160c --- /dev/null +++ b/docs/en-US/create-vpn-customer-gateway.xml @@ -0,0 +1,191 @@ + + +%BOOK_ENTITIES; +]> + +
+ Creating and Updating a VPN Customer Gateway + + A VPN customer gateway can be connected to only one VPN gateway at a time. + + To add a VPN Customer Gateway: + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPN Customer Gateway. + + + Click Add site-to-site VPN. + + + + + + addvpncustomergateway.png: adding a customer gateway. + + + Provide the following information: + + + Name: A unique name for the VPN customer gateway + you create. + + + Gateway: The IP address for the remote + gateway. + + + CIDR list: The guest CIDR list of the remote + subnets. Enter a CIDR or a comma-separated list of CIDRs. Ensure that a guest CIDR list + is not overlapped with the VPC’s CIDR, or another guest CIDR. The CIDR must be + RFC1918-compliant. + + + IPsec Preshared Key: Preshared keying is a method + where the endpoints of the VPN share a secret key. This key value is used to + authenticate the customer gateway and the VPC VPN gateway to each other. + + The IKE peers (VPN end points) authenticate each other by computing and sending a + keyed hash of data that includes the Preshared key. If the receiving peer is able to + create the same hash independently by using its Preshared key, it knows that both + peers must share the same secret, thus authenticating the customer gateway. + + + + IKE Encryption: The Internet Key Exchange (IKE) + policy for phase-1. The supported encryption algorithms are AES128, AES192, AES256, and + 3DES. Authentication is accomplished through the Preshared Keys. + + The phase-1 is the first phase in the IKE process. In this initial negotiation + phase, the two VPN endpoints agree on the methods to be used to provide security for + the underlying IP traffic. The phase-1 authenticates the two VPN gateways to each + other, by confirming that the remote gateway has a matching Preshared Key. + + + + IKE Hash: The IKE hash for phase-1. The supported + hash algorithms are SHA1 and MD5. + + + IKE DH: A public-key cryptography protocol which + allows two parties to establish a shared secret over an insecure communications channel. + The 1536-bit Diffie-Hellman group is used within IKE to establish session keys. The + supported options are None, Group-5 (1536-bit) and Group-2 (1024-bit). + + + ESP Encryption: Encapsulating Security Payload + (ESP) algorithm within phase-2. The supported encryption algorithms are AES128, AES192, + AES256, and 3DES. + + The phase-2 is the second phase in the IKE process. The purpose of IKE phase-2 is + to negotiate IPSec security associations (SA) to set up the IPSec tunnel. In phase-2, + new keying material is extracted from the Diffie-Hellman key exchange in phase-1, to + provide session keys to use in protecting the VPN data flow. + + + + ESP Hash: Encapsulating Security Payload (ESP) hash + for phase-2. Supported hash algorithms are SHA1 and MD5. + + + Perfect Forward Secrecy: Perfect Forward Secrecy + (or PFS) is the property that ensures that a session key derived from a set of long-term + public and private keys will not be compromised. This property enforces a new + Diffie-Hellman key exchange. It provides the keying material that has greater key + material life and thereby greater resistance to cryptographic attacks. The available + options are None, Group-5 (1536-bit) and Group-2 (1024-bit). The security of the key + exchanges increase as the DH groups grow larger, as does the time of the + exchanges. + + When PFS is turned on, for every negotiation of a new phase-2 SA the two gateways + must generate a new set of phase-1 keys. This adds an extra layer of protection that + PFS adds, which ensures if the phase-2 SA’s have expired, the keys used for new + phase-2 SA’s have not been generated from the current phase-1 keying material. + + + + IKE Lifetime (seconds): The phase-1 lifetime of the + security association in seconds. Default is 86400 seconds (1 day). Whenever the time + expires, a new phase-1 exchange is performed. + + + ESP Lifetime (seconds): The phase-2 lifetime of the + security association in seconds. Default is 3600 seconds (1 hour). Whenever the value is + exceeded, a re-key is initiated to provide a new IPsec encryption and authentication + session keys. + + + Dead Peer Detection: A method to detect an + unavailable Internet Key Exchange (IKE) peer. Select this option if you want the virtual + router to query the liveliness of its IKE peer at regular intervals. It’s recommended to + have the same configuration of DPD on both side of VPN connection. + + + + + Click OK. + + + + Updating and Removing a VPN Customer Gateway + You can update a customer gateway either with no VPN connection, or related VPN connection + is in error state. + + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPN Customer Gateway. + + + Select the VPN customer gateway you want to work with. + + + To modify the required parameters, click the Edit VPN Customer Gateway button + + + + + edit.png: button to edit a VPN customer gateway + + + + + To remove the VPN customer gateway, click the Delete VPN Customer Gateway button + + + + + delete.png: button to remove a VPN customer gateway + + + + + Click OK. + + +
diff --git a/docs/en-US/create-vpn-gateway-for-vpc.xml b/docs/en-US/create-vpn-gateway-for-vpc.xml new file mode 100644 index 00000000000..396a7d9d174 --- /dev/null +++ b/docs/en-US/create-vpn-gateway-for-vpc.xml @@ -0,0 +1,80 @@ + + +%BOOK_ENTITIES; +]> + +
+ Creating a VPN gateway for the VPC + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to deploy the VMs. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Select Site-to-Site VPN. + If you are creating the VPN gateway for the first time, selecting Site-to-Site VPN + prompts you to create a VPN gateway. + + + In the confirmation dialog, click Yes to confirm. + Within a few moments, the VPN gateway is created. You will be prompted to view the + details of the VPN gateway you have created. Click Yes to confirm. + The following details are displayed in the VPN Gateway page: + + + IP Address + + + Account + + + Domain + + + + +
\ No newline at end of file diff --git a/docs/en-US/create-vr-network-offering.xml b/docs/en-US/create-vr-network-offering.xml new file mode 100644 index 00000000000..317e3c200a1 --- /dev/null +++ b/docs/en-US/create-vr-network-offering.xml @@ -0,0 +1,108 @@ + + +%BOOK_ENTITIES; +]> + +
+ Creating and Changing a Virtual Router Network Offering + To create the network offering in association with a virtual router system service + offering: + + + Log in to the &PRODUCT; UI as a user or admin. + + + First, create a system service offering, for example: VRsystemofferingHA. + For more information on creating a system service offering, see . + + + From the Select Offering drop-down, choose Network Offering. + + + Click Add Network Offering. + + + In the dialog, make the following choices: + + + Name. Any desired name for the network + offering. + + + Description. A short description of the offering + that can be displayed to users. + + + Network Rate. Allowed data transfer rate in MB per + second. + + + Traffic Type. The type of network traffic that will + be carried on the network. + + + Guest Type. Choose whether the guest network is + isolated or shared. For a description of these terms, see . + + + Specify VLAN. (Isolated guest networks only) + Indicate whether a VLAN should be specified when this offering is used. + + + Supported Services. Select one or more of the + possible network services. For some services, you must also choose the service provider; + for example, if you select Load Balancer, you can choose the &PRODUCT; virtual router or + any other load balancers that have been configured in the cloud. Depending on which + services you choose, additional fields may appear in the rest of the dialog box. For + more information, see + + + System Offering. Choose the system service offering + that you want virtual routers to use in this network. In this case, the default “System + Offering For Software Router” and the custom “VRsystemofferingHA” are available and + displayed. + + + + + Click OK and the network offering is created. + + + To change the network offering of a guest network to the virtual router service + offering: + + + Select Network from the left navigation pane. + + + Select the guest network that you want to offer this network service to. + + + Click the Edit button. + + + From the Network Offering drop-down, select the virtual router network offering you have + just created. + + + Click OK. + + +
diff --git a/docs/en-US/creating-compute-offerings.xml b/docs/en-US/creating-compute-offerings.xml index 56679a422f4..31f974196fb 100644 --- a/docs/en-US/creating-compute-offerings.xml +++ b/docs/en-US/creating-compute-offerings.xml @@ -5,23 +5,22 @@ ]> - + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +-->
Creating a New Compute Offering To create a new compute offering: @@ -32,19 +31,36 @@ Click Add Compute Offering. In the dialog, make the following choices: - Name. Any desired name for the service offering. - Description. A short description of the offering that can be displayed to users - Storage type. The type of disk that should be allocated. Local allocates from storage attached directly to the host where the system VM is running. Shared allocates from storage accessible via NFS. - # of CPU cores. The number of cores which should be allocated to a system VM with this offering - CPU (in MHz). The CPU speed of the cores that the system VM is allocated. For example, "2000" would provide for a 2 GHz clock. - Memory (in MB). The amount of memory in megabytes that the system VM should be allocated. For example, "2048" would provide for a 2 GB RAM allocation. - Network Rate. Allowed data transfer rate in MB per second. - Offer HA. If yes, the administrator can choose to have the system VM be monitored and as highly available as possible. - Storage Tags. The tags that should be associated with the primary storage used by the system VM. - Host Tags. (Optional) Any tags that you use to organize your hosts - CPU cap. Whether to limit the level of CPU usage even if spare capacity is available. - Public. Indicate whether the service offering should be available all domains or only some domains. Choose Yes to make it available to all domains. Choose No to limit the scope to a subdomain; &PRODUCT; will then prompt for the subdomain's name. + Name: Any desired name for the service offering. + Description: A short description of the offering that can be + displayed to users + Storage type: The type of disk that should be allocated. + Local allocates from storage attached directly to the host where the system + VM is running. Shared allocates from storage accessible via NFS. + # of CPU cores: The number of cores which should be allocated + to a system VM with this offering + CPU (in MHz): The CPU speed of the cores that the system VM + is allocated. For example, “2000” would provide for a 2 GHz clock. + Memory (in MB): The amount of memory in megabytes that the + system VM should be allocated. For example, “2048” would provide for a 2 GB + RAM allocation. + Network Rate: Allowed data transfer rate in MB per + second. + Offer HA: If yes, the administrator can choose to have the + system VM be monitored and as highly available as possible. + Storage Tags: The tags that should be associated with the + primary storage used by the system VM. + Host Tags: (Optional) Any tags that you use to organize your + hosts + CPU cap: Whether to limit the level of CPU usage even if + spare capacity is available. + Public: Indicate whether the service offering should be + available all domains or only some domains. Choose Yes to make it available + to all domains. Choose No to limit the scope to a subdomain; &PRODUCT; + will then prompt for the subdomain's name. Click Add. + +
diff --git a/docs/en-US/creating-vms.xml b/docs/en-US/creating-vms.xml index dc37dbb38c3..9da4aea94ea 100644 --- a/docs/en-US/creating-vms.xml +++ b/docs/en-US/creating-vms.xml @@ -44,6 +44,6 @@ Click Add Instance. Select ISO Boot, and follow the steps in the wizard. Click Submit and your VM will be created and started. - (Oracle VM only) After ISO installation, the installer reboots into the operating system. Due to a known issue in OVM, the reboot will place the VM in the Stopped state. In the &PRODUCT; UI, detach the ISO from the VM (so that the VM will not boot from the ISO again), then click the Start button to restart the VM. +
diff --git a/docs/en-US/delete-reset-vpn.xml b/docs/en-US/delete-reset-vpn.xml new file mode 100644 index 00000000000..318e5fe321e --- /dev/null +++ b/docs/en-US/delete-reset-vpn.xml @@ -0,0 +1,89 @@ + + +%BOOK_ENTITIES; +]> + +
+ Restarting and Removing a VPN Connection + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to deploy the VMs. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ASLs + + + + + Select Site-to-Site VPN. + The Site-to-Site VPN page is displayed. + + + From the Select View drop-down, ensure that VPN Connection is selected. + All the VPN connections you created are displayed. + + + Select the VPN connection you want to work with. + The Details tab is displayed. + + + To remove a VPN connection, click the Delete VPN connection button + + + + + remove-vpn.png: button to remove a VPN connection + + + To restart a VPN connection, click the Reset VPN connection button present in the + Details tab. + + + + + reset-vpn.png: button to reset a VPN connection + + + + +
diff --git a/docs/en-US/deployment-architecture-overview.xml b/docs/en-US/deployment-architecture-overview.xml index 6a67a2ce589..2c5f30ec06b 100644 --- a/docs/en-US/deployment-architecture-overview.xml +++ b/docs/en-US/deployment-architecture-overview.xml @@ -25,10 +25,19 @@
Deployment Architecture Overview - A &PRODUCT; installation consists of two parts: the Management Server and the cloud infrastructure that it manages. When you set up and manage a &PRODUCT; cloud, you provision resources such as hosts, storage devices, and IP addresses into the Management Server, and the Management Server manages those resources. + A &PRODUCT; installation consists of two parts: the Management Server + and the cloud infrastructure that it manages. When you set up and + manage a &PRODUCT; cloud, you provision resources such as hosts, + storage devices, and IP addresses into the Management Server, and + the Management Server manages those resources. - The minimum production installation consists of one machine running the &PRODUCT; Management Server and another machine to act as the cloud infrastructure (in this case, a very simple infrastructure consisting of one host running hypervisor software). In a trial installation, a single machine can act as both the Management Server and the hypervisor host (using the KVM hypervisor). + The minimum production installation consists of one machine running + the &PRODUCT; Management Server and another machine to act as the + cloud infrastructure (in this case, a very simple infrastructure + consisting of one host running hypervisor software). In its smallest + deployment, a single machine can act as both the Management Server + and the hypervisor host (using the KVM hypervisor). @@ -36,7 +45,11 @@ basic-deployment.png: Basic two-machine deployment - A more full-featured installation consists of a highly-available multi-node Management Server installation and up to thousands of hosts using any of several advanced networking setups. For information about deployment options, see Choosing a Deployment Architecture. + + A more full-featured installation consists of a highly-available + multi-node Management Server installation and up to tens of thousands of + hosts using any of several advanced networking setups. For + information about deployment options, see Choosing a Deployment Architecture. diff --git a/docs/en-US/detach-move-volumes.xml b/docs/en-US/detach-move-volumes.xml index a00e15f6cee..25323c928ee 100644 --- a/docs/en-US/detach-move-volumes.xml +++ b/docs/en-US/detach-move-volumes.xml @@ -27,7 +27,7 @@ This procedure is different from moving disk volumes from one storage pool to another. See VM Storage Migration A volume can be detached from a guest VM and attached to another guest. Both &PRODUCT; administrators and users can detach volumes from VMs and move them to other VMs. If the two VMs are in different clusters, and the volume is large, it may take several minutes for the volume to be moved to the new VM. - If the destination VM is running in the OVM hypervisor, the VM must be stopped before a new volume can be attached to it. + Log in to the &PRODUCT; UI as a user or admin. In the left navigation bar, click Storage, and choose Volumes in Select View. Alternatively, if you know which VM the volume is attached to, you can click Instances, click the VM name, and click View Volumes. diff --git a/docs/en-US/developer-introduction.xml b/docs/en-US/developer-introduction.xml index 5b9964e5380..bb5251b4f26 100644 --- a/docs/en-US/developer-introduction.xml +++ b/docs/en-US/developer-introduction.xml @@ -22,9 +22,9 @@ under the License. --> -
+ Introduction for Developers -
+ diff --git a/docs/en-US/developer_guide.xml b/docs/en-US/developer_guide.xml deleted file mode 100644 index 18ef88a4c68..00000000000 --- a/docs/en-US/developer_guide.xml +++ /dev/null @@ -1,39 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - - - Developer Guide - - - - - - - - - - - - - diff --git a/docs/en-US/enable-disable-static-nat-vpc.xml b/docs/en-US/enable-disable-static-nat-vpc.xml new file mode 100644 index 00000000000..17f0c10540f --- /dev/null +++ b/docs/en-US/enable-disable-static-nat-vpc.xml @@ -0,0 +1,97 @@ + + +%BOOK_ENTITIES; +]> + +
+ Enabling or Disabling Static NAT on a VPC + A static NAT rule maps a public IP address to the private IP address of a VM in a VPC to + allow Internet traffic to it. This section tells how to enable or disable static NAT for a + particular IP address in a VPC. + If port forwarding rules are already in effect for an IP address, you cannot enable static + NAT to that IP. + If a guest VM is part of more than one network, static NAT rules will function only if they + are defined on the default network. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC to which you want to deploy the VMs. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Select IP Addresses. + The IP Addresses page is displayed. + + + Click the IP you want to work with. + + + In the Details tab,click the Static NAT button. + + + + + enable-disable.png: button to enable Statid NAT. + + The button toggles between Enable and Disable, depending on whether + static NAT is currently enabled for the IP address. + + + If you are enabling static NAT, a dialog appears as follows: + + + + + + select-vmstatic-nat.png: selecting a tier to apply staticNAT. + + + + + Select the tier and the destination VM, then click Apply. + + +
diff --git a/docs/en-US/event-types.xml b/docs/en-US/event-types.xml index 9a710559b15..2ccd55335df 100644 --- a/docs/en-US/event-types.xml +++ b/docs/en-US/event-types.xml @@ -22,199 +22,199 @@ under the License. --> -
- Event Types - - - - - - - VM.CREATE - TEMPLATE.EXTRACT - SG.REVOKE.INGRESS - - - VM.DESTROY - TEMPLATE.UPLOAD - HOST.RECONNECT - - - VM.START - TEMPLATE.CLEANUP - MAINT.CANCEL - - - VM.STOP - VOLUME.CREATE - MAINT.CANCEL.PS - - - VM.REBOOT - VOLUME.DELETE - MAINT.PREPARE - - - VM.UPGRADE - VOLUME.ATTACH - MAINT.PREPARE.PS - - - VM.RESETPASSWORD - VOLUME.DETACH - VPN.REMOTE.ACCESS.CREATE - - - ROUTER.CREATE - VOLUME.UPLOAD - VPN.USER.ADD - - - ROUTER.DESTROY - SERVICEOFFERING.CREATE - VPN.USER.REMOVE - - - ROUTER.START - SERVICEOFFERING.UPDATE - NETWORK.RESTART - - - ROUTER.STOP - SERVICEOFFERING.DELETE - UPLOAD.CUSTOM.CERTIFICATE - - - ROUTER.REBOOT - DOMAIN.CREATE - UPLOAD.CUSTOM.CERTIFICATE - - - ROUTER.HA - DOMAIN.DELETE - STATICNAT.DISABLE - - - PROXY.CREATE - DOMAIN.UPDATE - SSVM.CREATE - - - PROXY.DESTROY - SNAPSHOT.CREATE - SSVM.DESTROY - - - PROXY.START - SNAPSHOT.DELETE - SSVM.START - - - PROXY.STOP - SNAPSHOTPOLICY.CREATE - SSVM.STOP - - - PROXY.REBOOT - SNAPSHOTPOLICY.UPDATE - SSVM.REBOOT - - - PROXY.HA - SNAPSHOTPOLICY.DELETE - SSVM.H - - - VNC.CONNECT - VNC.DISCONNECT - NET.IPASSIGN - - - NET.IPRELEASE - NET.RULEADD - NET.RULEDELETE - - - NET.RULEMODIFY - NETWORK.CREATE - NETWORK.DELETE - - - LB.ASSIGN.TO.RULE - LB.REMOVE.FROM.RULE - LB.CREATE - - - LB.DELETE - LB.UPDATE - USER.LOGIN - - - USER.LOGOUT - USER.CREATE - USER.DELETE - - - USER.UPDATE - USER.DISABLE - TEMPLATE.CREATE - - - TEMPLATE.DELETE - TEMPLATE.UPDATE - TEMPLATE.COPY - - - TEMPLATE.DOWNLOAD.START - TEMPLATE.DOWNLOAD.SUCCESS - TEMPLATE.DOWNLOAD.FAILED - - - ISO.CREATE - ISO.DELETE - ISO.COPY - - - ISO.ATTACH - ISO.DETACH - ISO.EXTRACT - - - ISO.UPLOAD - SERVICE.OFFERING.CREATE - SERVICE.OFFERING.EDIT - - - SERVICE.OFFERING.DELETE - DISK.OFFERING.CREATE - DISK.OFFERING.EDIT - - - DISK.OFFERING.DELETE - NETWORK.OFFERING.CREATE - NETWORK.OFFERING.EDIT - - - NETWORK.OFFERING.DELETE - POD.CREATE - POD.EDIT - - - POD.DELETE - ZONE.CREATE - ZONE.EDIT - - - ZONE.DELETE - VLAN.IP.RANGE.CREATE - VLAN.IP.RANGE.DELETE - - - CONFIGURATION.VALUE.EDIT - SG.AUTH.INGRESS - - - - - -
+ + Event Types + + + + + + + VM.CREATE + TEMPLATE.EXTRACT + SG.REVOKE.INGRESS + + + VM.DESTROY + TEMPLATE.UPLOAD + HOST.RECONNECT + + + VM.START + TEMPLATE.CLEANUP + MAINT.CANCEL + + + VM.STOP + VOLUME.CREATE + MAINT.CANCEL.PS + + + VM.REBOOT + VOLUME.DELETE + MAINT.PREPARE + + + VM.UPGRADE + VOLUME.ATTACH + MAINT.PREPARE.PS + + + VM.RESETPASSWORD + VOLUME.DETACH + VPN.REMOTE.ACCESS.CREATE + + + ROUTER.CREATE + VOLUME.UPLOAD + VPN.USER.ADD + + + ROUTER.DESTROY + SERVICEOFFERING.CREATE + VPN.USER.REMOVE + + + ROUTER.START + SERVICEOFFERING.UPDATE + NETWORK.RESTART + + + ROUTER.STOP + SERVICEOFFERING.DELETE + UPLOAD.CUSTOM.CERTIFICATE + + + ROUTER.REBOOT + DOMAIN.CREATE + UPLOAD.CUSTOM.CERTIFICATE + + + ROUTER.HA + DOMAIN.DELETE + STATICNAT.DISABLE + + + PROXY.CREATE + DOMAIN.UPDATE + SSVM.CREATE + + + PROXY.DESTROY + SNAPSHOT.CREATE + SSVM.DESTROY + + + PROXY.START + SNAPSHOT.DELETE + SSVM.START + + + PROXY.STOP + SNAPSHOTPOLICY.CREATE + SSVM.STOP + + + PROXY.REBOOT + SNAPSHOTPOLICY.UPDATE + SSVM.REBOOT + + + PROXY.HA + SNAPSHOTPOLICY.DELETE + SSVM.H + + + VNC.CONNECT + VNC.DISCONNECT + NET.IPASSIGN + + + NET.IPRELEASE + NET.RULEADD + NET.RULEDELETE + + + NET.RULEMODIFY + NETWORK.CREATE + NETWORK.DELETE + + + LB.ASSIGN.TO.RULE + LB.REMOVE.FROM.RULE + LB.CREATE + + + LB.DELETE + LB.UPDATE + USER.LOGIN + + + USER.LOGOUT + USER.CREATE + USER.DELETE + + + USER.UPDATE + USER.DISABLE + TEMPLATE.CREATE + + + TEMPLATE.DELETE + TEMPLATE.UPDATE + TEMPLATE.COPY + + + TEMPLATE.DOWNLOAD.START + TEMPLATE.DOWNLOAD.SUCCESS + TEMPLATE.DOWNLOAD.FAILED + + + ISO.CREATE + ISO.DELETE + ISO.COPY + + + ISO.ATTACH + ISO.DETACH + ISO.EXTRACT + + + ISO.UPLOAD + SERVICE.OFFERING.CREATE + SERVICE.OFFERING.EDIT + + + SERVICE.OFFERING.DELETE + DISK.OFFERING.CREATE + DISK.OFFERING.EDIT + + + DISK.OFFERING.DELETE + NETWORK.OFFERING.CREATE + NETWORK.OFFERING.EDIT + + + NETWORK.OFFERING.DELETE + POD.CREATE + POD.EDIT + + + POD.DELETE + ZONE.CREATE + ZONE.EDIT + + + ZONE.DELETE + VLAN.IP.RANGE.CREATE + VLAN.IP.RANGE.DELETE + + + CONFIGURATION.VALUE.EDIT + SG.AUTH.INGRESS + + + + + + diff --git a/docs/en-US/events.xml b/docs/en-US/events.xml index cbefc544b60..9b6d75cfbba 100644 --- a/docs/en-US/events.xml +++ b/docs/en-US/events.xml @@ -23,6 +23,7 @@ -->
+ Events diff --git a/docs/en-US/extracting-source.xml b/docs/en-US/extracting-source.xml new file mode 100644 index 00000000000..97a40b66213 --- /dev/null +++ b/docs/en-US/extracting-source.xml @@ -0,0 +1,36 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Extracting source + + Extracting the &PRODUCT; release is relatively simple and can be done + with a single command as follows: + $ tar -jxvf apache-cloudstack-4.0.0-incubating-src.tar.bz2 + + + You can now move into the directory: + $ cd ./apache-cloudstack-4.0.0-incubating-src + +
diff --git a/docs/en-US/feature-overview.xml b/docs/en-US/feature-overview.xml index 236d78b026b..501bca88c2f 100644 --- a/docs/en-US/feature-overview.xml +++ b/docs/en-US/feature-overview.xml @@ -28,10 +28,7 @@ Multiple Hypervisor Support - &PRODUCT; works with a variety of hypervisors. A single cloud deployment can contain multiple hypervisor implementations. You have the complete freedom to choose the right hypervisor for your workload. - - - &PRODUCT; is designed to work with open source Xen and KVM hypervisors as well as enterprise-grade hypervisors such as Citrix XenServer, VMware vSphere, and Oracle VM (OVM). You can also provision “bare metal” hosts with no hypervisor (Beta feature. Untested in &PRODUCT; 3.0.x.) + &PRODUCT; works with a variety of hypervisors, and a single cloud deployment can contain multiple hypervisor implementations. The current release of &PRODUCT; supports pre-packaged enterprise solutions like Citrix XenServer and VMware vSphere, as well as KVM or Xen running on Ubuntu or CentOS. Massively Scalable Infrastructure Management @@ -55,14 +52,31 @@ API and Extensibility - &PRODUCT; provides an API that gives programmatic access to all the management features available in the UI. The API is maintained and documented. This API enables the creation of command line tools and new user interfaces to suit particular needs. See the Developer’s Guide and API Reference, both available at http://docs.cloudstack.org/Apache_CloudStack_Documentation. + &PRODUCT; provides an API that gives programmatic access to all the + management features available in the UI. The API is maintained and + documented. This API enables the creation of command line tools and + new user interfaces to suit particular needs. See the Developer’s + Guide and API Reference, both available at + Apache CloudStack Guides + and + Apache CloudStack API Reference + respectively. - The &PRODUCT; pluggable allocation architecture allows the creation of new types of allocators for the selection of storage and Hosts. See the Allocator Implementation Guide (http://docs.cloudstack.org/CloudStack_Documentation/Allocator_Implementation_Guide). + The &PRODUCT; pluggable allocation architecture allows the creation + of new types of allocators for the selection of storage and Hosts. + See the Allocator Implementation Guide + (http://docs.cloudstack.org/CloudStack_Documentation/Allocator_Implementation_Guide). High Availability - &PRODUCT; has a number of features to increase the availability of the system. The Management Server itself may be deployed in a multi-node installation where the servers are load balanced. MySQL may be configured to use replication to provide for a manual failover in the event of database loss. For the hosts, &PRODUCT; supports NIC bonding and the use of separate networks for storage as well as iSCSI Multipath. + + &PRODUCT; has a number of features to increase the availability of the + system. The Management Server itself may be deployed in a multi-node + installation where the servers are load balanced. MySQL may be configured + to use replication to provide for a manual failover in the event of + database loss. For the hosts, &PRODUCT; supports NIC bonding and the use + of separate networks for storage as well as iSCSI Multipath.
diff --git a/docs/en-US/first_ms_node_install.xml b/docs/en-US/first_ms_node_install.xml index fcb4a864875..3c3e51acca1 100644 --- a/docs/en-US/first_ms_node_install.xml +++ b/docs/en-US/first_ms_node_install.xml @@ -25,34 +25,33 @@
Install the First Management Server - Download the &PRODUCT; Management Server onto the host where it will run from one of the following links. If your operating system is CentOS, use the download file for RHEL. - - Open-source community: http://sourceforge.net/projects/cloudstack/files/CloudStack Acton/ - Commercial customers: https://www.citrix.com/English/ss/downloads/. - Commercial customers will need a MyCitrix account. - - - - Install the &PRODUCT; packages. You should have a file in the form of “CloudStack-VERSION-N-OSVERSION.tar.gz”. Untar the file and then run the install.sh script inside it. Replace the file and directory names below with those you are using: - # tar xzf CloudStack-VERSION-N-OSVERSION.tar.gz -# cd CloudStack-VERSION-N-OSVERSION -# ./install.sh - - You should see a few messages as the installer prepares, followed by a list of choices. - - Choose M to install the Management Server software. - > M - - Wait for a message like “Complete! Done,” which indicates that the software was installed successfully. - - (RHEL or CentOS) When the installation is finished, run the following commands to start essential services (the commands might be different depending on your OS): - # service rpcbind start -# service nfs start -# chkconfig nfs on -# chkconfig rpcbind on - - - Continue to Install and Configure the Database. + + + Ensure you have configured your machine according to + + or + + as appropriate for your platform. + + + + + Install the &PRODUCT; management server packages by + issuing one of the following commands as appropriate: + # yum install cloud-client + # apt-get install cloud-client + + + + + (RPM-based distributions) When the installation is + finished, run the following commands to start essential + services: + # service rpcbind start +# service nfs start +# chkconfig nfs on +# chkconfig rpcbind on +
diff --git a/docs/en-US/getting-release.xml b/docs/en-US/getting-release.xml new file mode 100644 index 00000000000..09f0a7b08fe --- /dev/null +++ b/docs/en-US/getting-release.xml @@ -0,0 +1,63 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Getting the release + + You can download the latest &PRODUCT; release from the + + Apache CloudStack project download page. + + + You'll notice several links under the 'Latest release' section. + + + + + + apache-cloudstack-4.0.0-incubating-src.tar.bz2 + - This is the link to the release itself. + + + + + PGP + - This is a detached cryptographic signature that can be used to help + verify the authenticity of the release. + + + + + MD5 + - An MD5 hash of the release to aid in verify the validity of the release download. + + + + + SHA512 + - A SHA512 hash of the release to aid in verify the validity of the release download. + + + +
diff --git a/docs/en-US/global-config.xml b/docs/en-US/global-config.xml new file mode 100644 index 00000000000..2f6ad105c0d --- /dev/null +++ b/docs/en-US/global-config.xml @@ -0,0 +1,54 @@ + + +%BOOK_ENTITIES; +]> + + + Setting Global Configuration Parameters + &PRODUCT; provides parameters that you can set to control many aspects of the cloud. When + &PRODUCT; is first installed, and periodically thereafter, you might need to modify these + settings. + + + Log in to the UI as administrator. + + + In the left navigation bar, click Global Settings. + + + In Select View, choose one of the following: + + + Global Settings. This displays a list of the parameters with brief descriptions and + current values. + + + Hypervisor Capabilities. This displays a list of hypervisor versions with the + maximum number of guests supported for each. + + + + + Use the search box to narrow down the list to those you are interested in. + + + Click the Edit icon to modify a value. If you are viewing Hypervisor Capabilities, you + must click the name of the hypervisor first to display the editing screen. + + + diff --git a/docs/en-US/globally-configured-limit.xml b/docs/en-US/globally-configured-limit.xml deleted file mode 100644 index ac71112b310..00000000000 --- a/docs/en-US/globally-configured-limit.xml +++ /dev/null @@ -1,100 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - -
- Globally Configured Limits - In a zone, the guest virtual network has a 24 bit CIDR by default. This limits the guest virtual network to 254 running instances. It can be adjusted as needed, but this must be done before any instances are created in the zone. For example, 10.1.1.0/22 would provide for ~1000 addresses. - The following table lists limits set in the Global Configuration: - - - - - Parameter Name - Definition - - - - - - max.account.public.ips - Number of public IP addresses that can be owned by an account - - - - max.account.snapshots - Number of snapshots that can exist for an account - - - - - max.account.templates - Number of templates that can exist for an account - - - - max.account.user.vms - Number of virtual machine instances that can exist for an account - - - - max.account.volumes - Number of disk volumes that can exist for an account - - - - max.template.iso.size - Maximum size for a downloaded template or ISO in GB - - - - max.volume.size.gb - Maximum size for a volume in GB - - - network.throttling.rate - Default data transfer rate in megabits per second allowed per user (supported on XenServer) - - - snapshot.max.hourly - Maximum recurring hourly snapshots to be retained for a volume. If the limit is reached, early snapshots from the start of the hour are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring hourly snapshots can not be scheduled - - - - snapshot.max.daily - Maximum recurring daily snapshots to be retained for a volume. If the limit is reached, snapshots from the start of the day are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring daily snapshots can not be scheduled - - - snapshot.max.weekly - Maximum recurring weekly snapshots to be retained for a volume. If the limit is reached, snapshots from the beginning of the week are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring weekly snapshots can not be scheduled - - - - snapshot.max.monthly - Maximum recurring monthly snapshots to be retained for a volume. If the limit is reached, snapshots from the beginning of the month are deleted so that newer ones can be saved. This limit does not apply to manual snapshots. If set to 0, recurring monthly snapshots can not be scheduled. - - - - - To modify global configuration parameters, use the global configuration screen in the &PRODUCT; UI. See Setting Global Configuration Parameters -
diff --git a/docs/en-US/globally-configured-limits.xml b/docs/en-US/globally-configured-limits.xml index ac71112b310..48a91f1b01e 100644 --- a/docs/en-US/globally-configured-limits.xml +++ b/docs/en-US/globally-configured-limits.xml @@ -22,7 +22,7 @@ under the License. --> -
+
Globally Configured Limits In a zone, the guest virtual network has a 24 bit CIDR by default. This limits the guest virtual network to 254 running instances. It can be adjusted as needed, but this must be done before any instances are created in the zone. For example, 10.1.1.0/22 would provide for ~1000 addresses. The following table lists limits set in the Global Configuration: diff --git a/docs/en-US/host-add-vsphere.xml b/docs/en-US/host-add-vsphere.xml new file mode 100644 index 00000000000..b47846448d7 --- /dev/null +++ b/docs/en-US/host-add-vsphere.xml @@ -0,0 +1,28 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Adding a Host (vSphere) + For vSphere servers, we recommend creating the cluster of hosts in vCenter and then adding the entire cluster to &PRODUCT;. See Add Cluster: vSphere. +
diff --git a/docs/en-US/host-add-xenserver-kvm-ovm.xml b/docs/en-US/host-add-xenserver-kvm-ovm.xml new file mode 100644 index 00000000000..4bbeefcbed4 --- /dev/null +++ b/docs/en-US/host-add-xenserver-kvm-ovm.xml @@ -0,0 +1,152 @@ + + +%BOOK_ENTITIES; +]> + + +
+ Adding a Host (XenServer or KVM) + XenServer and KVM hosts can be added to a cluster at any time. +
+ Requirements for XenServer and KVM Hosts + + Make sure the hypervisor host does not have any VMs already running before you add it to + &PRODUCT;. + + Configuration requirements: + + + Each cluster must contain only hosts with the identical hypervisor. + + + For XenServer, do not put more than 8 hosts in a cluster. + + + For KVM, do not put more than 16 hosts in a cluster. + + + For hardware requirements, see the installation section for your hypervisor in the + &PRODUCT; Installation Guide. +
+ XenServer Host Additional Requirements + If network bonding is in use, the administrator must cable the new host identically to + other hosts in the cluster. + For all additional hosts to be added to the cluster, run the following command. This + will cause the host to join the master in a XenServer pool. + # xe pool-join master-address=[master IP] master-username=root master-password=[your password] + + When copying and pasting a command, be sure the command has pasted as a single line + before executing. Some document viewers may introduce unwanted line breaks in copied + text. + + With all hosts added to the XenServer pool, run the cloud-setup-bond script. This script + will complete the configuration and setup of the bonds on the new hosts in the + cluster. + + + Copy the script from the Management Server in + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/cloud-setup-bonding.sh to the + master host and ensure it is executable. + + + Run the script: + # ./cloud-setup-bonding.sh + + +
+
+ KVM Host Additional Requirements + + + If shared mountpoint storage is in use, the administrator should ensure that the new + host has all the same mountpoints (with storage mounted) as the other hosts in the + cluster. + + + Make sure the new host has the same network configuration (guest, private, and + public network) as other hosts in the cluster. + + +
+ +
+
+ Adding a XenServer or KVM Host + + + If you have not already done so, install the hypervisor software on the host. You will + need to know which version of the hypervisor software version is supported by &PRODUCT; + and what additional configuration is required to ensure the host will work with &PRODUCT;. + To find these installation details, see the appropriate section for your hypervisor in the + &PRODUCT; Installation Guide. + + + Log in to the &PRODUCT; UI as administrator. + + + In the left navigation, choose Infrastructure. In Zones, click View More, then click + the zone in which you want to add the host. + + + Click the Compute tab. In the Clusters node, click View All. + + + Click the cluster where you want to add the host. + + + Click View Hosts. + + + Click Add Host. + + + Provide the following information. + + + Host Name. The DNS name or IP address of the host. + + + Username. Usually root. + + + Password. This is the password for the user from your XenServer or KVM + install). + + + Host Tags (Optional). Any labels that you use to categorize hosts for ease of + maintenance. For example, you can set to the cloud's HA tag (set in the ha.tag global + configuration parameter) if you want this host to be used only for VMs with the "high + availability" feature enabled. For more information, see HA-Enabled Virtual Machines + as well as HA for Hosts. + + + There may be a slight delay while the host is provisioned. It should automatically + display in the UI. + + + Repeat for additional hosts. + + +
+
diff --git a/docs/en-US/host-add.xml b/docs/en-US/host-add.xml index 2a984fd02ba..74509d69be7 100644 --- a/docs/en-US/host-add.xml +++ b/docs/en-US/host-add.xml @@ -5,24 +5,38 @@ ]>
- Adding a Host - TODO + Adding a Host + + Before adding a host to the &PRODUCT; configuration, you must first install your chosen hypervisor on the host. &PRODUCT; can manage hosts running VMs under a variety of hypervisors. + The &PRODUCT; Installation Guide provides instructions on how to install each supported hypervisor + and configure it for use with &PRODUCT;. See the appropriate section in the Installation Guide for information about which version of your chosen hypervisor is supported, as well as crucial additional steps to configure the hypervisor hosts for use with &PRODUCT;. + Be sure you have performed the additional &PRODUCT;-specific configuration steps described in the hypervisor installation section for your particular hypervisor. + + Now add the hypervisor host to &PRODUCT;. The technique to use varies depending on the hypervisor. + + + + + + + +
diff --git a/docs/en-US/hypervisor-host-install-agent.xml b/docs/en-US/hypervisor-host-install-agent.xml index d1b774a7a30..e5bfa37fb6d 100644 --- a/docs/en-US/hypervisor-host-install-agent.xml +++ b/docs/en-US/hypervisor-host-install-agent.xml @@ -27,8 +27,8 @@ To manage KVM instances on the host &PRODUCT; uses a Agent. This Agent communicates with the Management server and controls all the instances on the host. First we start by installing the agent: In RHEL or CentOS: - yum install cloud-agent + $ yum install cloud-agent In Ubuntu: - apt-get install cloud-agent + $ apt-get install cloud-agent The host is now ready to be added to a cluster. This is covered in a later section, see . It is recommended that you continue to read the documentation before adding the host!
\ No newline at end of file diff --git a/docs/en-US/cloudstack_admin.xml b/docs/en-US/hypervisor-host-install-finish.xml similarity index 65% rename from docs/en-US/cloudstack_admin.xml rename to docs/en-US/hypervisor-host-install-finish.xml index c80c94f5ff5..ff530c79038 100644 --- a/docs/en-US/cloudstack_admin.xml +++ b/docs/en-US/hypervisor-host-install-finish.xml @@ -1,5 +1,5 @@ - %BOOK_ENTITIES; ]> @@ -11,9 +11,9 @@ to you 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 @@ -22,10 +22,7 @@ under the License. --> - - - - - - - +
+ Add the host to CloudStack + The host is now ready to be added to a cluster. This is covered in a later section, see . It is recommended that you continue to read the documentation before adding the host! +
diff --git a/docs/en-US/hypervisor-host-install-firewall.xml b/docs/en-US/hypervisor-host-install-firewall.xml index e99c88e4882..ae82fc47afa 100644 --- a/docs/en-US/hypervisor-host-install-firewall.xml +++ b/docs/en-US/hypervisor-host-install-firewall.xml @@ -37,23 +37,23 @@
Open ports in RHEL/CentOS RHEL and CentOS use iptables for firewalling the system, you can open extra ports by executing the following iptable commands: - iptables -I INPUT -p tcp -m tcp --dport 22 -j ACCEPT - iptables -I INPUT -p tcp -m tcp --dport 1798 -j ACCEPT - iptables -I INPUT -p tcp -m tcp --dport 16509 -j ACCEPT - iptables -I INPUT -p tcp -m tcp --dport 5900:6100 -j ACCEPT - iptables -I INPUT -p tcp -m tcp --dport 49152:492160 -j ACCEPT + $ iptables -I INPUT -p tcp -m tcp --dport 22 -j ACCEPT + $ iptables -I INPUT -p tcp -m tcp --dport 1798 -j ACCEPT + $ iptables -I INPUT -p tcp -m tcp --dport 16509 -j ACCEPT + $ iptables -I INPUT -p tcp -m tcp --dport 5900:6100 -j ACCEPT + $ iptables -I INPUT -p tcp -m tcp --dport 49152:49216 -j ACCEPT These iptable settings are not persistent accross reboots, we have to save them first. - iptables-save > /etc/sysconfig/iptables + $ iptables-save > /etc/sysconfig/iptables
Open ports in Ubuntu The default firewall under Ubuntu is UFW (Uncomplicated FireWall), which is a Python wrapper around iptables. To open the required ports, execute the following commands: - ufw allow proto tcp from any to any port 22 - ufw allow proto tcp from any to any port 1798 - ufw allow proto tcp from any to any port 16509 - ufw allow proto tcp from any to any port 5900:6100 - ufw allow proto tcp from any to any port 49152:492160 + $ ufw allow proto tcp from any to any port 22 + $ ufw allow proto tcp from any to any port 1798 + $ ufw allow proto tcp from any to any port 16509 + $ ufw allow proto tcp from any to any port 5900:6100 + $ ufw allow proto tcp from any to any port 49152:49216 By default UFW is not enabled on Ubuntu. Executing these commands with the firewall disabled does not enable the firewall.
-
\ No newline at end of file +
diff --git a/docs/en-US/hypervisor-host-install-libvirt.xml b/docs/en-US/hypervisor-host-install-libvirt.xml index 15cfde2efa7..34e66783600 100644 --- a/docs/en-US/hypervisor-host-install-libvirt.xml +++ b/docs/en-US/hypervisor-host-install-libvirt.xml @@ -24,32 +24,23 @@
Install and Configure libvirt - &PRODUCT; uses libvirt for managing virtual machines. Therefor it is vital that libvirt is configured correctly. + &PRODUCT; uses libvirt for managing virtual machines. Therefore it is vital that libvirt is configured correctly. Libvirt is a dependency of cloud-agent and should already be installed. - Install libvirt - On RHEL or CentOS: - yum install libvirt - On Ubuntu: - apt-get install libvirt-bin - - - In order to have live migration working libvirt has to listen for unsecured TCP connections. - vi /etc/libvirt/libvirtd.conf + In order to have live migration working libvirt has to listen for unsecured TCP connections. We also need to turn off libvirts attempt to use Multicast DNS advertising. Both of these settings are in /etc/libvirt/libvirtd.conf Set the following paramaters: listen_tls = 0 listen_tcp = 1 tcp_port = 16059 auth_tcp = "none" + mdns_adv = 0 Turning on "listen_tcp" in libvirtd.conf is not enough, we have to change the parameters as well: - On RHEL or CentOS: - vi /etc/sysconfig/libvirtd + On RHEL or CentOS modify /etc/sysconfig/libvirtd: Uncomment the following line: #LIBVIRTD_ARGS="--listen" - On Ubuntu: - vi /etc/init/libvirt-bin.conf + On Ubuntu: modify /etc/init/libvirt-bin.conf Change the following line (at the end of the file): exec /usr/sbin/libvirtd -d to (just add -l) @@ -58,9 +49,9 @@ Restart libvirt In RHEL or CentOS: - service libvirtd restart + $ service libvirtd restart In Ubuntu: - service libvirt-bin restart + $ service libvirt-bin restart -
\ No newline at end of file + diff --git a/docs/en-US/hypervisor-host-install-overview.xml b/docs/en-US/hypervisor-host-install-overview.xml index 187abea8e4e..716b43ddf91 100644 --- a/docs/en-US/hypervisor-host-install-overview.xml +++ b/docs/en-US/hypervisor-host-install-overview.xml @@ -23,11 +23,11 @@ -->
- Hypervisor Host Installation Overview - This section describes installing a Hypervisor host. This is targeted towards hosts running Linux Kernel Virtual Machine (KVM) + KVM Installation Overview + If you want to use the Linux Kernel Virtual Machine (KVM) hypervisor to run guest virtual machines, install KVM on the host(s) in your cloud. The material in this section doesn't duplicate KVM installation docs. It provides the &PRODUCT;-specific steps that are needed to prepare a KVM host to work with &PRODUCT;. Before continuing, make sure that you have applied the latest updates to your host. It is NOT recommended to run services on this host not controlled by &PRODUCT;. - The procedure for installing the Hypervisor Host is: + The procedure for installing a KVM Hypervisor Host is: Prepare the Operating System Install and configure libvirt diff --git a/docs/en-US/hypervisor-host-install-prepare-os.xml b/docs/en-US/hypervisor-host-install-prepare-os.xml index e2e32e709ae..44852f21c2d 100644 --- a/docs/en-US/hypervisor-host-install-prepare-os.xml +++ b/docs/en-US/hypervisor-host-install-prepare-os.xml @@ -29,12 +29,12 @@ Log in to your OS as root. Check for a fully qualified hostname. - hostname --fqdn + $ hostname --fqdn This should return a fully qualified hostname such as "kvm1.lab.example.org". If it does not, edit /etc/hosts so that it does. Make sure that the machine can reach the Internet. - ping www.cloudstack.org + $ ping www.cloudstack.org Turn on NTP for time synchronization. @@ -42,9 +42,9 @@ Install NTP On RHEL or CentOS: - yum install ntp + $ yum install ntp On Ubuntu: - apt-get install openntpd + $ apt-get install openntpd diff --git a/docs/en-US/hypervisor-host-install-security-policies.xml b/docs/en-US/hypervisor-host-install-security-policies.xml index 5fd6925a8c0..03da04b6eb3 100644 --- a/docs/en-US/hypervisor-host-install-security-policies.xml +++ b/docs/en-US/hypervisor-host-install-security-policies.xml @@ -32,10 +32,10 @@ Check to see whether SELinux is installed on your machine. If not, you can skip this section. In RHEL or CentOS, SELinux is installed and enabled by default. You can verify this with: - rpm -qa | grep selinux + $ rpm -qa | grep selinux - Set the SELINUX variable in /etc/selinux/config to "permissive". This ensures that the permissive setting will be maintained after a system reboot. + Set the SELINUX variable in /etc/selinux/config to "permissive". This ensures that the permissive setting will be maintained after a system reboot. In RHEL or CentOS: vi /etc/selinux/config Change the following line @@ -45,7 +45,7 @@ Then set SELinux to permissive starting immediately, without requiring a system reboot. - setenforce permissive + $ setenforce permissive @@ -55,14 +55,14 @@ Check to see whether AppArmor is installed on your machine. If not, you can skip this section. In Ubuntu AppArmor is installed and enabled by default. You can verify this with: - dpkg --list 'apparmor' + $ dpkg --list 'apparmor' Disable the AppArmor profiles for libvirt - ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/ - ln -s /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper /etc/apparmor.d/disable/ - apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd - apparmor_parser -R /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper + $ ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/ + $ ln -s /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper /etc/apparmor.d/disable/ + $ apparmor_parser -R /etc/apparmor.d/usr.sbin.libvirtd + $ apparmor_parser -R /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper diff --git a/docs/en-US/installation_overview.xml b/docs/en-US/hypervisor-installation.xml similarity index 63% rename from docs/en-US/installation_overview.xml rename to docs/en-US/hypervisor-installation.xml index eee444e571e..b0fc9f46ddb 100644 --- a/docs/en-US/installation_overview.xml +++ b/docs/en-US/hypervisor-installation.xml @@ -22,12 +22,10 @@ under the License. --> - - Installation Overview - - - - - - + + Hypervisor Installation + + + + diff --git a/docs/en-US/hypervisor-host-install-flow.xml b/docs/en-US/hypervisor-kvm-install-flow.xml similarity index 84% rename from docs/en-US/hypervisor-host-install-flow.xml rename to docs/en-US/hypervisor-kvm-install-flow.xml index 74668c8f423..76e03ef7919 100644 --- a/docs/en-US/hypervisor-host-install-flow.xml +++ b/docs/en-US/hypervisor-kvm-install-flow.xml @@ -22,13 +22,15 @@ under the License. --> -
- Hypervisor Host installation +
+ KVM Hypervisor Host Installation + + - -
\ No newline at end of file + +
diff --git a/docs/en-US/hypervisor-kvm-requirements.xml b/docs/en-US/hypervisor-kvm-requirements.xml new file mode 100644 index 00000000000..c42db86a2b8 --- /dev/null +++ b/docs/en-US/hypervisor-kvm-requirements.xml @@ -0,0 +1,48 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ System Requirements for KVM Hypervisor Hosts + KVM is included with a variety of Linux-based operating systems. Although you are not required to run these distributions, the following are recommended: + + CentOS / RHEL: 6.3 + Ubuntu: 12.04(.1) + + The main requirement for KVM hypervisors is the libvirt and Qemu version. No matter what + Linux distribution you are using, make sure the following requirements are met: + + libvirt: 0.9.4 or higher + Qemu/KVM: 1.0 or higher + + In addition, the following hardware requirements apply: + + Within a single cluster, the hosts must be of the same distribution version. + All hosts within a cluster must be homogenous. The CPUs must be of the same type, count, and feature flags. + Must support HVM (Intel-VT or AMD-V enabled) + 64-bit x86 CPU (more cores results in better performance) + 4 GB of memory + At least 1 NIC + When you deploy &PRODUCT;, the hypervisor host must not have any VMs already running + +
diff --git a/docs/en-US/hypervisor-support-for-primarystorage.xml b/docs/en-US/hypervisor-support-for-primarystorage.xml index ca266a43013..055c1826169 100644 --- a/docs/en-US/hypervisor-support-for-primarystorage.xml +++ b/docs/en-US/hypervisor-support-for-primarystorage.xml @@ -40,7 +40,6 @@ VMware vSphere Citrix XenServer KVM - Oracle VM @@ -50,28 +49,24 @@ VMDK VHD QCOW2 - RAW iSCSI support VMFS Clustered LVM Yes, via Shared Mountpoint - Yes, via OCFS2M Fiber Channel support VMFS Yes, via Existing SR Yes, via Shared Mountpoint - No NFS support Y Y Y - Y @@ -79,7 +74,6 @@ Y Y Y - Y @@ -87,7 +81,6 @@ NFS and iSCSI NFS NFS - No @@ -95,8 +88,8 @@ XenServer uses a clustered LVM system to store VM images on iSCSI and Fiber Channel volumes and does not support over-provisioning in the hypervisor. The storage server itself, however, can support thin-provisioning. As a result the &PRODUCT; can still support storage over-provisioning by running on thin-provisioned storage volumes. KVM supports "Shared Mountpoint" storage. A shared mountpoint is a file system path local to each server in a given cluster. The path must be the same across all Hosts in the cluster, for example /mnt/primary1. This shared mountpoint is assumed to be a clustered filesystem such as OCFS2. In this case the &PRODUCT; does not attempt to mount or unmount the storage as is done with NFS. The &PRODUCT; requires that the administrator insure that the storage is available - Oracle VM supports both iSCSI and NFS storage. When iSCSI is used with OVM, the &PRODUCT; administrator is responsible for setting up iSCSI on the host, including re-mounting the storage after the host recovers from a failure such as a network outage. With other hypervisors, &PRODUCT; takes care of mounting the iSCSI target on the host whenever it discovers a connection with an iSCSI server and unmounting the target when it discovers the connection is down. + With NFS storage, &PRODUCT; manages the overprovisioning. In this case the global configuration parameter storage.overprovisioning.factor controls the degree of overprovisioning. This is independent of hypervisor type. - Local storage is an option for primary storage for vSphere, XenServer, Oracle VM, and KVM. When the local disk option is enabled, a local disk storage pool is automatically created on each host. To use local storage for the System Virtual Machines (such as the Virtual Router), set system.vm.use.local.storage to true in global configuration. + Local storage is an option for primary storage for vSphere, XenServer, and KVM. When the local disk option is enabled, a local disk storage pool is automatically created on each host. To use local storage for the System Virtual Machines (such as the Virtual Router), set system.vm.use.local.storage to true in global configuration. &PRODUCT; supports multiple primary storage pools in a Cluster. For example, you could provision 2 NFS servers in primary storage. Or you could provision 1 iSCSI LUN initially and then add a second iSCSI LUN when the first approaches capacity.
diff --git a/docs/en-US/images/NIC_bonding_and_multipath_IO.png b/docs/en-US/images/NIC_bonding_and_multipath_IO.png deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/en-US/images/example_of_a_multi_site_deployment.png b/docs/en-US/images/example_of_a_multi_site_deployment.png deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/en-US/images/large-scale-redundant-setup.png b/docs/en-US/images/large-scale-redundant-setup.png new file mode 100644 index 00000000000..5d2581afb43 Binary files /dev/null and b/docs/en-US/images/large-scale-redundant-setup.png differ diff --git a/docs/en-US/images/large_scale_redundant_setup.png b/docs/en-US/images/large_scale_redundant_setup.png deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/en-US/images/multi-node-management-server.png b/docs/en-US/images/multi-node-management-server.png new file mode 100644 index 00000000000..5cf5ed5456f Binary files /dev/null and b/docs/en-US/images/multi-node-management-server.png differ diff --git a/docs/en-US/images/multi-site-deployment.png b/docs/en-US/images/multi-site-deployment.png new file mode 100644 index 00000000000..f3ae5bb6b5c Binary files /dev/null and b/docs/en-US/images/multi-site-deployment.png differ diff --git a/docs/en-US/images/multi_node_management_server.png b/docs/en-US/images/multi_node_management_server.png deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/en-US/images/nic-bonding-and-multipath-io.png b/docs/en-US/images/nic-bonding-and-multipath-io.png new file mode 100644 index 00000000000..0fe60b66ed6 Binary files /dev/null and b/docs/en-US/images/nic-bonding-and-multipath-io.png differ diff --git a/docs/en-US/images/remove-vpc.png b/docs/en-US/images/remove-vpc.png new file mode 100644 index 00000000000..aa9846cfd9b Binary files /dev/null and b/docs/en-US/images/remove-vpc.png differ diff --git a/docs/en-US/images/remove-vpn.png b/docs/en-US/images/remove-vpn.png new file mode 100644 index 00000000000..27145cebbc7 Binary files /dev/null and b/docs/en-US/images/remove-vpn.png differ diff --git a/docs/en-US/images/reset-vpn.png b/docs/en-US/images/reset-vpn.png new file mode 100644 index 00000000000..04655dc37ad Binary files /dev/null and b/docs/en-US/images/reset-vpn.png differ diff --git a/docs/en-US/images/separate-storage-network.png b/docs/en-US/images/separate-storage-network.png new file mode 100644 index 00000000000..24dbbefc5b4 Binary files /dev/null and b/docs/en-US/images/separate-storage-network.png differ diff --git a/docs/en-US/images/separate_storage_network.png b/docs/en-US/images/separate_storage_network.png deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/en-US/images/small-scale-deployment.png b/docs/en-US/images/small-scale-deployment.png new file mode 100644 index 00000000000..1c88520e7b4 Binary files /dev/null and b/docs/en-US/images/small-scale-deployment.png differ diff --git a/docs/en-US/images/small_scale_deployment.png b/docs/en-US/images/small_scale_deployment.png deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/en-US/images/vmware-increase-ports.png b/docs/en-US/images/vmware-increase-ports.png new file mode 100644 index 00000000000..fe968153262 Binary files /dev/null and b/docs/en-US/images/vmware-increase-ports.png differ diff --git a/docs/en-US/images/vmware-iscsi-datastore.png b/docs/en-US/images/vmware-iscsi-datastore.png new file mode 100644 index 00000000000..9f6b33f01ed Binary files /dev/null and b/docs/en-US/images/vmware-iscsi-datastore.png differ diff --git a/docs/en-US/images/vmware-iscsi-general.png b/docs/en-US/images/vmware-iscsi-general.png new file mode 100644 index 00000000000..863602b9eb7 Binary files /dev/null and b/docs/en-US/images/vmware-iscsi-general.png differ diff --git a/docs/en-US/images/vmware-iscsi-initiator-properties.png b/docs/en-US/images/vmware-iscsi-initiator-properties.png new file mode 100644 index 00000000000..1fab03143b1 Binary files /dev/null and b/docs/en-US/images/vmware-iscsi-initiator-properties.png differ diff --git a/docs/en-US/images/vmware-iscsi-initiator.png b/docs/en-US/images/vmware-iscsi-initiator.png new file mode 100644 index 00000000000..a9a8301d74d Binary files /dev/null and b/docs/en-US/images/vmware-iscsi-initiator.png differ diff --git a/docs/en-US/images/vmware-iscsi-target-add.png b/docs/en-US/images/vmware-iscsi-target-add.png new file mode 100644 index 00000000000..f016da7956d Binary files /dev/null and b/docs/en-US/images/vmware-iscsi-target-add.png differ diff --git a/docs/en-US/images/vmware-mgt-network-properties.png b/docs/en-US/images/vmware-mgt-network-properties.png new file mode 100644 index 00000000000..9141af9c42f Binary files /dev/null and b/docs/en-US/images/vmware-mgt-network-properties.png differ diff --git a/docs/en-US/images/vmware-nexus-add-cluster.png b/docs/en-US/images/vmware-nexus-add-cluster.png new file mode 100644 index 00000000000..7c1dd73f775 Binary files /dev/null and b/docs/en-US/images/vmware-nexus-add-cluster.png differ diff --git a/docs/en-US/images/vmware-nexus-port-profile.png b/docs/en-US/images/vmware-nexus-port-profile.png new file mode 100644 index 00000000000..19b264f7a0a Binary files /dev/null and b/docs/en-US/images/vmware-nexus-port-profile.png differ diff --git a/docs/en-US/images/vmware-physical-network.png b/docs/en-US/images/vmware-physical-network.png new file mode 100644 index 00000000000..a7495c77b14 Binary files /dev/null and b/docs/en-US/images/vmware-physical-network.png differ diff --git a/docs/en-US/images/vmware-vswitch-properties.png b/docs/en-US/images/vmware-vswitch-properties.png new file mode 100644 index 00000000000..bc247d276d6 Binary files /dev/null and b/docs/en-US/images/vmware-vswitch-properties.png differ diff --git a/docs/en-US/installation-steps-overview.xml b/docs/en-US/installation-steps-overview.xml index ed2e3d1617d..ea00057bab3 100644 --- a/docs/en-US/installation-steps-overview.xml +++ b/docs/en-US/installation-steps-overview.xml @@ -34,49 +34,34 @@
- - Prepare - - Make sure you have the required hardware ready + Make sure you have the required hardware ready. See - (Optional) Fill out the preparation checklists + Install the Management Server (choose single-node or multi-node). See - Install the &PRODUCT; software + Log in to the UI. See - Install the Management Server (choose single-node or multi-node) + Add a zone. Includes the first pod, cluster, and host. See - Log in to the UI + Add more pods (optional). See - Provision your cloud infrastructure + Add more clusters (optional). See - Add a zone. Includes the first pod, cluster, and host + Add more hosts (optional). See - Add more pods + Add more primary storage (optional). See - Add more clusters + Add more secondary storage (optional). See - Add more hosts - - - Add more primary storage - - - Add more secondary storage - - - Try using the cloud - - - Initialization and testing + Try using the cloud. See diff --git a/docs/en-US/installation.xml b/docs/en-US/installation.xml index 948931e5768..5fc550edad6 100644 --- a/docs/en-US/installation.xml +++ b/docs/en-US/installation.xml @@ -27,6 +27,6 @@ + - diff --git a/docs/en-US/inter-vlan-routing.xml b/docs/en-US/inter-vlan-routing.xml new file mode 100644 index 00000000000..49a833cdb5d --- /dev/null +++ b/docs/en-US/inter-vlan-routing.xml @@ -0,0 +1,107 @@ + + +%BOOK_ENTITIES; +]> + +
+ About Inter-VLAN Routing + Inter-VLAN Routing is the capability to route network traffic between VLANs. This feature + enables you to build Virtual Private Clouds (VPC), an isolated segment of your cloud, that can + hold multi-tier applications. These tiers are deployed on different VLANs that can communicate + with each other. You provision VLANs to the tiers your create, and VMs can be deployed on + different tiers. The VLANs are connected to a virtual router, which facilitates communication + between the VMs. In effect, you can segment VMs by means of VLANs into different networks that + can host multi-tier applications, such as Web, Application, or Database. Such segmentation by + means of VLANs logically separate application VMs for higher security and lower broadcasts, + while remaining physically connected to the same device. + This feature is supported on XenServer and VMware hypervisors. + The major advantages are: + + + The administrator can deploy a set of VLANs and allow users to deploy VMs on these + VLANs. A guest VLAN is randomly alloted to an account from a pre-specified set of guest + VLANs. All the VMs of a certain tier of an account reside on the guest VLAN allotted to that + account. + + A VLAN allocated for an account cannot be shared between multiple accounts. + + + + The administrator can allow users create their own VPC and deploy the application. In + this scenario, the VMs that belong to the account are deployed on the VLANs allotted to that + account. + + + Both administrators and users can create multiple VPCs. The guest network NIC is plugged + to the VPC virtual router when the first VM is deployed in a tier. + + + The administrator can create the following gateways to send to or receive traffic from + the VMs: + + + VPN Gateway: For more information, see . + + + Public Gateway: The public gateway for a VPC is + added to the virtual router when the virtual router is created for VPC. The public + gateway is not exposed to the end users. You are not allowed to list it, nor allowed to + create any static routes. + + + Private Gateway: For more information, see . + + + + + Both administrators and users can create various possible destinations-gateway + combinations. However, only one gateway of each type can be used in a deployment. + For example: + + + VLANs and Public Gateway: For example, an + application is deployed in the cloud, and the Web application VMs communicate with the + Internet. + + + VLANs, VPN Gateway, and Public Gateway: For + example, an application is deployed in the cloud; the Web application VMs communicate + with the Internet; and the database VMs communicate with the on-premise devices. + + + + + The administrator can define Access Control List (ACL) on the virtual router to filter + the traffic among the VLANs or between the Internet and a VLAN. You can define ACL based on + CIDR, port range, protocol, type code (if ICMP protocol is selected) and Ingress/Egress + type. + + + The following figure shows the possible deployment scenarios of a Inter-VLAN setup: + + + + + + mutltier.png: a multi-tier setup. + + + To set up a multi-tier Inter-VLAN deployment, see . +
diff --git a/docs/en-US/large_scale_redundant_setup.xml b/docs/en-US/large_scale_redundant_setup.xml new file mode 100644 index 00000000000..427a42d9182 --- /dev/null +++ b/docs/en-US/large_scale_redundant_setup.xml @@ -0,0 +1,42 @@ + +%BOOK_ENTITIES; +]> + + +
+ Large-Scale Redundant Setup + + + + + Large-Scale Redundant Setup + + This diagram illustrates the network architecture of a large-scale &PRODUCT; deployment. + + A layer-3 switching layer is at the core of the data center. A router redundancy protocol like VRRP should be deployed. Typically high-end core switches also include firewall modules. Separate firewall appliances may also be used if the layer-3 switch does not have integrated firewall capabilities. The firewalls are configured in NAT mode. The firewalls provide the following functions: + + Forwards HTTP requests and API calls from the Internet to the Management Server. The Management Server resides on the management network. + When the cloud spans multiple zones, the firewalls should enable site-to-site VPN such that servers in different zones can directly reach each other. + + + A layer-2 access switch layer is established for each pod. Multiple switches can be stacked to increase port count. In either case, redundant pairs of layer-2 switches should be deployed. + The Management Server cluster (including front-end load balancers, Management Server nodes, and the MySQL database) is connected to the management network through a pair of load balancers. + Secondary storage servers are connected to the management network. + Each pod contains storage and computing servers. Each storage and computing server should have redundant NICs connected to separate layer-2 access switches. + +
diff --git a/docs/en-US/log-in.xml b/docs/en-US/log-in.xml index e72d27bf61b..84328ce4d45 100644 --- a/docs/en-US/log-in.xml +++ b/docs/en-US/log-in.xml @@ -5,27 +5,26 @@ ]> -
- Log In to the UI - &PRODUCT; provides a web-based UI that can be used by both administrators and end users. The appropriate version of the UI is displayed depending on the credentials used to log in. The UI is available in popular browsers including IE7, IE8, IE9, Firefox 3.5+, Firefox 4, Safari 4, and Safari 5. The URL is: (substitute your own management server IP address) - http://<management-server-ip-address>:8080/client + Log In to the UI + &PRODUCT; provides a web-based UI that can be used by both administrators and end users. The appropriate version of the UI is displayed depending on the credentials used to log in. The UI is available in popular browsers including IE7, IE8, IE9, Firefox 3.5+, Firefox 4, Safari 4, and Safari 5. The URL is: (substitute your own management server IP address) + http://<management-server-ip-address>:8080/client On a fresh Management Server installation, a guided tour splash screen appears. On later visits, you’ll see a login screen where you specify the following to proceed to your Dashboard: Username @@ -42,7 +41,8 @@ If you are a user in the sub-domains, enter the full path to the domain, excluding the root domain. For example, suppose multiple levels are created under the root domain, such as Comp1/hr. The users in the Comp1 domain should enter Comp1 in the Domain field, whereas the users in the Comp1/sales domain should enter Comp1/sales. For more guidance about the choices that appear when you log in to this UI, see Logging In as the Root Administrator. - - - + + + +
diff --git a/docs/en-US/manage-cloud.xml b/docs/en-US/manage-cloud.xml index c4c4d6be248..3e29d09cdc1 100644 --- a/docs/en-US/manage-cloud.xml +++ b/docs/en-US/manage-cloud.xml @@ -22,10 +22,11 @@ under the License. --> -
- Managing the Cloud - vCenter Maintenance Mode - XenServer and Maintenance Mode - vCenter Maintenance Mode - XenServer and Maintenance Mode -
+ + Managing the Cloud + + + + + + \ No newline at end of file diff --git a/docs/en-US/management-server-install-client.xml b/docs/en-US/management-server-install-client.xml index 93273ce3f34..7d219acc623 100644 --- a/docs/en-US/management-server-install-client.xml +++ b/docs/en-US/management-server-install-client.xml @@ -21,20 +21,32 @@ specific language governing permissions and limitations under the License. --> -
- Install the Management Server on the First Host - The first step in installation, whether you are installing the Management Server on one host or many, is to install the software on a single node. - - If you are planning to install the Management Server on multiple nodes for high availability, do not proceed to the additional nodes yet. That step will come later. - The &PRODUCT; Management server can be installed using either RPM or DEB packages. These packages will depend on everything you need to run the Management server. -
- Install on CentOS/RHEL - We start by installing the required packages: - yum install cloud-client -
-
- Install on Ubuntu - apt-get install cloud-client -
+ Install the Management Server on the First Host + The first step in installation, whether you are installing the Management Server on one host + or many, is to install the software on a single node. + + If you are planning to install the Management Server on multiple nodes for high + availability, do not proceed to the additional nodes yet. That step will come later. + + The &PRODUCT; Management server can be installed using either RPM or DEB packages. These + packages will depend on everything you need to run the Management server. +
+ Downloading vhd-util + Before setting up the Management Server, download vhd-util from vhd-util + If the Management Server is RHEL or CentOS, copy vhd-util to + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver. + If the Management Server is Ubuntu, copy vhd-util to + /usr/lib/cloud/common/scripts/vm/hypervisor/xenserver/vhd-util. +
+
+ Install on CentOS/RHEL + We start by installing the required packages: + yum install cloud-client +
+
+ Install on Ubuntu + apt-get install cloud-client +
diff --git a/docs/en-US/management-server-install-db-external.xml b/docs/en-US/management-server-install-db-external.xml index bc768290ce3..a749dc76c0d 100644 --- a/docs/en-US/management-server-install-db-external.xml +++ b/docs/en-US/management-server-install-db-external.xml @@ -22,71 +22,81 @@ under the License. --> -
+
Install the Database on a Separate Node This section describes how to install MySQL on a standalone machine, separate from the Management Server. This technique is intended for a deployment that includes several Management Server nodes. If you have a single-node Management Server deployment, you will typically use the same node for MySQL. - See . + See . + + The management server doesn't require a specific distribution for the MySQL node. + You can use a distribution or Operating System of your choice. + Using the same distribution as the management server is recommended, but not required. + See . + + - If you already have a version of MySQL installed on the Management Server node, make one of the following choices, depending on what version of MySQL it is. The most recent version tested is 5.1.58. - - If you already have installed MySQL version 5.1.58 or later, skip to step 3. - - If you have installed a version of MySQL earlier than 5.1.58, you can either skip to step 3 or uninstall MySQL and proceed to step 2 to install a more recent version. - - It is important that you choose the right database version. Never downgrade a MySQL installation. - - Log in as root to your Database Node and run the following commands. If you are going to install a replica database, then log in to the master. - -# yum install mysql-server -# chkconfig --level 35 mysqld on - + + Install MySQL from the package repository from your distribution: + On RHEL or CentOS: + yum install mysql-server + On Ubuntu: + apt-get install mysql-server Edit the MySQL configuration (/etc/my.cnf or /etc/mysql/my.cnf, depending on your OS) and insert the following lines in the [mysqld] section. You can put these lines below the datadir line. The max_connections parameter should be set to 350 multiplied by the number of Management Servers you are deploying. This example assumes two Management Servers. - -innodb_rollback_on_timeout=1 + + On Ubuntu, you can also create a file /etc/mysql/conf.d/cloudstack.cnf and add + these directives there. Don't forget to add [mysqld] on the first line of the + file. + + innodb_rollback_on_timeout=1 innodb_lock_wait_timeout=600 max_connections=700 log-bin=mysql-bin binlog-format = 'ROW' - - The binlog-format variable is supported in MySQL versions 5.1 and greater. It is not supported in MySQL 5.0. In some versions of MySQL, an underscore character is used in place of the hyphen in the variable name. For the exact syntax and spelling of each variable, consult the documentation for your version of MySQL. +bind-address = 0.0.0.0 - Restart the MySQL service, then invoke MySQL as the root user. - -# service mysqld restart -# mysql -u root - + + Start or restart MySQL to put the new configuration into effect. + On RHEL/CentOS, + MySQL doesn't automatically start after installation. Start it manually. + service mysqld start + On Ubuntu, restart MySQL. + service mysqld restart - Best Practice: On RHEL and CentOS, MySQL does not set a root password by default. It is very strongly recommended that you set a root password as a security precaution. Run the following commands, and substitute your own desired root password. - mysql> SET PASSWORD = PASSWORD('password'); - From now on, start MySQL with mysql -p so it will prompt you for the password. + + (CentOS and RHEL only; not required on Ubuntu) + + On RHEL and CentOS, MySQL does not set a root password by default. It is very + strongly recommended that you set a root password as a security precaution. + + Run the following command to secure your installation. You can answer "Y" to all + questions except "Disallow root login remotely?". Remote root login is required to + set up the databases. + mysql_secure_installation - To grant access privileges to remote users, perform the following steps. + If a firewall is present on the system, open TCP port 3306 so external MySQL connections can be established. + On Ubuntu, UFW is the default firewall. Open the port with this command: + ufw allow mysql + On RHEL/CentOS: - Run the following commands from the mysql prompt: - -mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; -mysql> exit - + + Edit the /etc/sysconfig/iptables file and add the following line at the beginning of the INPUT chain. + -A INPUT -p tcp --dport 3306 -j ACCEPT - Restart the MySQL service. - # service mysqld restart + + Now reload the iptables rules. + service iptables restart - Open the MySQL server port (3306) in the firewall to allow remote clients to connect. - # iptables -I INPUT -p tcp --dport 3306 -j ACCEPT - - Edit the /etc/sysconfig/iptables file and add the following line at the beginning of the INPUT chain. - -A INPUT -p tcp --dport 3306 -j ACCEPT - - + - Set up the database. The following command creates the cloud user on the database. + Return to the root shell on your first Management Server. + + Set up the database. The following command creates the cloud user on the database. In dbpassword, specify the password to be assigned to the cloud user. You can choose to provide no password. In deploy-as, specify the username and password of the user deploying the database. In the following command, it is assumed the root user is deploying the database and creating the cloud user. @@ -94,12 +104,12 @@ mysql> exit (Optional) For management_server_key, substitute the default key that is used to encrypt confidential parameters in the &PRODUCT; properties file. Default: password. It is highly recommended that you replace this with a more secure value. See About Password and Key Encryption. (Optional) For database_key, substitute the default key that is used to encrypt confidential parameters in the &PRODUCT; database. Default: password. It is highly recommended that you replace this with a more secure value. See About Password and Key Encryption. - # cloud-setup-databases cloud:<dbpassword>@localhost --deploy-as=root:<password> -e <encryption_type> -m <management_server_key> -k <database_key> + cloud-setup-databases cloud:<dbpassword>@<ip address mysql server> \ + --deploy-as=root:<password> \ + -e <encryption_type> \ + -m <management_server_key> \ + -k <database_key> When this script is finished, you should see a message like “Successfully initialized the database.” - Now that the database is set up, you can finish configuring the OS for the Management Server. This command will set up iptables, sudoers, and start the Management Server. - # cloud-setup-management - You should see the message “Management Server setup is done.” -
diff --git a/docs/en-US/management-server-install-db-local.xml b/docs/en-US/management-server-install-db-local.xml index 238f9dee629..9880c54571b 100644 --- a/docs/en-US/management-server-install-db-local.xml +++ b/docs/en-US/management-server-install-db-local.xml @@ -22,77 +22,68 @@ under the License. --> -
+
Install the Database on the Management Server Node - This section describes how to install MySQL on the same machine with the Management Server. This technique is intended for a simple deployment that has a single Management Server node. If you have a multi-node Management Server deployment, you will typically use a separate node for MySQL. See . - + This section describes how to install MySQL on the same machine with the Management Server. This technique is intended for a simple deployment that has a single Management Server node. If you have a multi-node Management Server deployment, you will typically use a separate node for MySQL. See . - If you already have a version of MySQL installed on the Management Server node, make one of the following choices, depending on what version of MySQL it is. The most recent version tested is 5.1.58. - - If you already have installed MySQL version 5.1.58 or later, skip to step 4. - - If you have installed a version of MySQL earlier than 5.1.58, you can either skip to step 4 or uninstall MySQL and proceed to step 2 to install a more recent version. - - It is important that you choose the right database version. Never downgrade a MySQL installation. + + Install MySQL from the package repository from your distribution: + On RHEL or CentOS: + yum install mysql-server + On Ubuntu: + apt-get install mysql-server - On the same computer where you installed the Management Server, re-run install.sh. - # ./install.sh - You should see a few messages as the installer prepares, followed by a list of choices. - - Choose D to install the MySQL server from the distribution’s repo. - > D - Troubleshooting: If you do not see the D option, you already have MySQL installed. Please go back to step 1. - - Edit the MySQL configuration (/etc/my.cnf or /etc/mysql/my.cnf, depending on your OS) and insert the following lines in the [mysqld] section. You can put these lines below the datadir line. The max_connections parameter should be set to 350 multiplied by the number of Management Servers you are deploying. This example assumes one Management Server. - -innodb_rollback_on_timeout=1 + + Edit the MySQL configuration (/etc/my.cnf or /etc/mysql/my.cnf, depending on your OS) and insert the following lines in the [mysqld] section. You can put these lines below the datadir line. The max_connections parameter should be set to 350 multiplied by the number of Management Servers you are deploying. This example assumes one Management Server. + + On Ubuntu, you can also create a file /etc/mysql/conf.d/cloudstack.cnf and add these directives there. Don't forget to add [mysqld] on the first line of the file. + + innodb_rollback_on_timeout=1 innodb_lock_wait_timeout=600 max_connections=350 log-bin=mysql-bin -binlog-format = 'ROW' - - The binlog-format variable is supported in MySQL versions 5.1 and greater. It is not supported in MySQL 5.0. In some versions of MySQL, an underscore character is used in place of the hyphen in the variable name. For the exact syntax and spelling of each variable, consult the documentation for your version of MySQL. +binlog-format = 'ROW' - Restart the MySQL service, then invoke MySQL as the root user. - -# service mysqld restart -# mysql -u root - + + Start or restart MySQL to put the new configuration into effect. + On RHEL/CentOS, + MySQL doesn't automatically start after installation. Start it manually. + service mysqld start + On Ubuntu, restart MySQL. + service mysqld restart - Best Practice: On RHEL and CentOS, MySQL does not set a root password by default. It is very strongly recommended that you set a root password as a security precaution. Run the following commands, and substitute your own desired root password. - mysql> SET PASSWORD = PASSWORD('password'); - From now on, start MySQL with mysql -p so it will prompt you for the password. + + (CentOS and RHEL only; not required on Ubuntu) + + On RHEL and CentOS, MySQL does not set a root password by default. It is very + strongly recommended that you set a root password as a security precaution. + + Run the following command to secure your installation. You can answer "Y" to all + questions. + mysql_secure_installation - To grant access privileges to remote users, perform the following steps. - - Run the following commands from the mysql prompt: - -mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; -mysql> exit - - - Restart the MySQL service. - # service mysqld restart - Open the MySQL server port (3306) in the firewall to allow remote clients to connect. - # iptables -I INPUT -p tcp --dport 3306 -j ACCEPT - Edit the /etc/sysconfig/iptables file and add the following line at the beginning of the INPUT chain. - -A INPUT -p tcp --dport 3306 -j ACCEPT - - - Set up the database. The following command creates the cloud user on the database. + Set up the database. The following command creates the "cloud" user on the database. - In dbpassword, specify the password to be assigned to the cloud user. You can choose to provide no password. - In deploy-as, specify the username and password of the user deploying the database. In the following command, it is assumed the root user is deploying the database and creating the cloud user. + In dbpassword, specify the password to be assigned to the "cloud" user. You can choose to provide no password although that is not recommended. + In deploy-as, specify the username and password of the user deploying the database. In the following command, it is assumed the root user is deploying the database and creating the "cloud" user. (Optional) For encryption_type, use file or web to indicate the technique used to pass in the database encryption password. Default: file. See About Password and Key Encryption. (Optional) For management_server_key, substitute the default key that is used to encrypt confidential parameters in the &PRODUCT; properties file. Default: password. It is highly recommended that you replace this with a more secure value. See About Password and Key Encryption. (Optional) For database_key, substitute the default key that is used to encrypt confidential parameters in the &PRODUCT; database. Default: password. It is highly recommended that you replace this with a more secure value. See About Password and Key Encryption. - # cloud-setup-databases cloud:<dbpassword>@localhost --deploy-as=root:<password> -e <encryption_type> -m <management_server_key> -k <database_key> + cloud-setup-databases cloud:<dbpassword>@localhost \ + --deploy-as=root:<password> \ + -e <encryption_type> \ + -m <management_server_key> \ + -k <database_key> When this script is finished, you should see a message like “Successfully initialized the database.” - Now that the database is set up, you can finish configuring the OS for the Management Server. This command will set up iptables, sudoers, and start the Management Server. - # cloud-setup-management - You should see the message “Management Server setup is done.” + If you are running the KVM hypervisor on the same machine with the Management Server, edit /etc/sudoers and add the following line: + Defaults:cloud !requiretty + This type of single-machine setup is recommended only for a trial installation. + Now that the database is set up, you can finish configuring the OS for the Management Server. This command will set up iptables, sudoers, and start the Management Server. + # cloud-setup-management + You should see the message “&PRODUCT; Management Server setup is done.” +
diff --git a/docs/en-US/management-server-install-db.xml b/docs/en-US/management-server-install-db.xml new file mode 100644 index 00000000000..9d41af2562b --- /dev/null +++ b/docs/en-US/management-server-install-db.xml @@ -0,0 +1,34 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Install the database server + The &PRODUCT; management server uses a MySQL database server to store its data. + When you are installing the management server on a single node, you can install the MySQL server locally. + For an installation that has multiple management server nodes, we assume the MySQL database also runs on a separate node. + + &PRODUCT; has been tested with MySQL 5.1 and 5.5. These versions are included in RHEL/CentOS and Ubuntu. + + +
diff --git a/docs/en-US/management-server-install-flow.xml b/docs/en-US/management-server-install-flow.xml index 112771bb500..33bcac9c85b 100644 --- a/docs/en-US/management-server-install-flow.xml +++ b/docs/en-US/management-server-install-flow.xml @@ -27,8 +27,7 @@ - - + diff --git a/docs/en-US/management-server-install-multi-node.xml b/docs/en-US/management-server-install-multi-node.xml index 17d0f868b3c..1764fa90092 100644 --- a/docs/en-US/management-server-install-multi-node.xml +++ b/docs/en-US/management-server-install-multi-node.xml @@ -21,54 +21,49 @@ specific language governing permissions and limitations under the License. --> -
- Prepare and Start Additional Management Servers - For your second and subsequent Management Servers, you will install the Management Server software, connect it to the database, and set up the OS for the Management Server. - - - Perform the steps in . - - Download the Management Server onto the additional host where it will run. Get the software from the following link. - https://www.citrix.com/English/ss/downloads/ -FIXME - You will need a MyCitrix account. - - Install the packages. You should have a file in the form of “&PRODUCT;-VERSION-N-OSVERSION.tar.gz”. Untar the file and then run the install.sh script inside it. Replace the file and directory names below with those you are using: - -# tar xzf &PRODUCT;-VERSION-N-OSVERSION.tar.gz -# cd &PRODUCT;-VERSION-N-OSVERSION -# ./install.sh - - You should see a few messages as the installer prepares, followed by a list of choices. - - Choose M to install the Management Server software. - > M - - Wait for a message like “Complete! Done,” which indicates that the software was installed successfully. - - (RHEL or CentOS) When the installation is finished, run the following commands to start essential services (the commands might be different depending on your OS): - -# service rpcbind start -# service nfs start -# chkconfig nfs on -# chkconfig rpcbind on - - - Configure the database client. Note the absence of the --deploy-as argument in this case. - (For more details about the arguments to this command, see .) - - # cloud-setup-databases cloud:<dbpassword>@<dbhost> -e <encryption_type> -m <management_server_key> -k <database_key> - - - (Trial installations only) If you are running the hypervisor on the same machine with the Management Server, edit /etc/sudoers and add the following line: - Defaults:cloud !requiretty - - Configure the OS and start the Management Server: - # cloud-setup-management - The Management Server on this node should now be running. - - Repeat these steps on each additional Management Server. - Be sure to configure a load balancer for the Management Servers. See Management Server Load Balancing. - + Prepare and Start Additional Management Servers + For your second and subsequent Management Servers, you will install the Management Server + software, connect it to the database, and set up the OS for the Management Server. + + + Perform the steps in and or as + appropriate. + + + Download vhd-util from vhd-util + If the Management Server is RHEL or CentOS, copy vhd-util to + /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver. + If the Management Server is Ubuntu, copy vhd-util to + /usr/lib/cloud/common/scripts/vm/hypervisor/xenserver/vhd-util. + + + Ensure that necessary services are started and set to start on boot. + # service rpcbind start +# service nfs start +# chkconfig nfs on +# chkconfig rpcbind on + + + + Configure the database client. Note the absence of the --deploy-as argument in this + case. (For more details about the arguments to this command, see .) + # cloud-setup-databases cloud:dbpassword@dbhost -e encryption_type -m management_server_key -k database_key + + + Configure the OS and start the Management Server: + # cloud-setup-management + The Management Server on this node should now be running. + + + Repeat these steps on each additional Management Server. + + + Be sure to configure a load balancer for the Management Servers. See Management Server + Load Balancing. + +
diff --git a/docs/en-US/management-server-install-overview.xml b/docs/en-US/management-server-install-overview.xml index 5bc6f1ba8f2..ba4c8f667ff 100644 --- a/docs/en-US/management-server-install-overview.xml +++ b/docs/en-US/management-server-install-overview.xml @@ -35,7 +35,12 @@ The procedure for installing the Management Server is: - Prepare the Operating System + + Prepare the Operating System + + + Download and install vhd-util. + Install the First Management Server Install and Configure the MySQL database Prepare NFS Shares diff --git a/docs/en-US/management-server-install-prepare-os.xml b/docs/en-US/management-server-install-prepare-os.xml index ee76a5f1566..ef78731e81a 100644 --- a/docs/en-US/management-server-install-prepare-os.xml +++ b/docs/en-US/management-server-install-prepare-os.xml @@ -34,7 +34,7 @@ Make sure that the machine can reach the Internet. - ping www.google.com + ping www.cloudstack.org Turn on NTP for time synchronization. diff --git a/docs/en-US/management-server-install-systemvm.xml b/docs/en-US/management-server-install-systemvm.xml index c2c12129ef6..6cd1ef7a0ff 100644 --- a/docs/en-US/management-server-install-systemvm.xml +++ b/docs/en-US/management-server-install-systemvm.xml @@ -1,5 +1,5 @@ - %BOOK_ENTITIES; ]> @@ -21,36 +21,51 @@ specific language governing permissions and limitations under the License. --> -
- Prepare the System VM Template - Secondary storage must be seeded with a template that is used for &PRODUCT; system VMs. - When copying and pasting a command, be sure the command has pasted as a single line before executing. Some document viewers may introduce unwanted line breaks in copied text. - - On the Management Server, run one or more of the following cloud-install-sys-tmplt commands to retrieve and decompress the system VM template. Run the command for each hypervisor type that you expect end users to run in this Zone. - If your secondary storage mount point is not named /mnt/secondary, substitute your own mount point name. - If you set the &PRODUCT; database encryption type to "web" when you set up the database, you must now add the parameter -s <management-server-secret-key>. See About Password and Key Encryption. - This process will require approximately 5 GB of free space on the local file system and up to 30 minutes each time it runs. - - For XenServer: - # /usr/lib64/cloud/agent/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.vhd.bz2 -h xenserver -s <optional-management-server-secret-key> -F - - For vSphere: - # /usr/lib64/cloud/agent/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/burbank/burbank-systemvm-08012012.ova -h vmware -s <optional-management-server-secret-key> -F - - For KVM: - # /usr/lib64/cloud/agent/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h kvm -s <optional-management-server-secret-key> -F - - + Prepare the System VM Template + Secondary storage must be seeded with a template that is used for &PRODUCT; system + VMs. + + When copying and pasting a command, be sure the command has pasted as a single line before + executing. Some document viewers may introduce unwanted line breaks in copied text. + + + + On the Management Server, run one or more of the following cloud-install-sys-tmplt + commands to retrieve and decompress the system VM template. Run the command for each + hypervisor type that you expect end users to run in this Zone. + If your secondary storage mount point is not named /mnt/secondary, substitute your own + mount point name. + If you set the &PRODUCT; database encryption type to "web" when you set up the database, + you must now add the parameter -s <management-server-secret-key>. See About Password + and Key Encryption. + This process will require approximately 5 GB of free space on the local file system and + up to 30 minutes each time it runs. + + + For XenServer: + # /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.vhd.bz2 -h xenserver -s <optional-management-server-secret-key> -F - If you are using a separate NFS server, perform this step. If you are using the Management Server as the NFS server, you MUST NOT perform this step. - When the script has finished, unmount secondary storage and remove the created directory. - -# umount /mnt/secondary -# rmdir /mnt/secondary - + + For vSphere: + # /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/burbank/burbank-systemvm-08012012.ova -h vmware -s <optional-management-server-secret-key> -F - Repeat these steps for each secondary storage server. + + For KVM: + # /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h kvm -s <optional-management-server-secret-key> -F - + + + + If you are using a separate NFS server, perform this step. If you are using the + Management Server as the NFS server, you MUST NOT perform this step. + When the script has finished, unmount secondary storage and remove the created + directory. + # umount /mnt/secondary +# rmdir /mnt/secondary + + + Repeat these steps for each secondary storage server. + +
diff --git a/docs/en-US/management-server-overview.xml b/docs/en-US/management-server-overview.xml index ed301424651..b8e2d53f052 100644 --- a/docs/en-US/management-server-overview.xml +++ b/docs/en-US/management-server-overview.xml @@ -23,36 +23,54 @@ -->
- Management Server Overview - The Management Server is the &PRODUCT; software that manages cloud resources. By interacting with the Management Server through its UI or API, you can configure and manage your cloud infrastructure. - - The Management Server runs on a dedicated server or VM. It controls allocation of virtual machines to hosts and assigns storage and IP addresses to the virtual machine instances. The Management Server runs in a Tomcat container and requires a MySQL database for persistence. - - The machine must meet the system requirements described in System Requirements. - - The Management Server: - - - - Provides the web user interface for the administrator and a reference user interface for end users. - - - Provides the APIs for &PRODUCT;. - - - Manages the assignment of guest VMs to particular hosts. - - - Manages the assignment of public and private IP addresses to particular accounts. - - - Manages the allocation of storage to guests as virtual disks. - - - Manages snapshots, templates, and ISO images, possibly replicating them across data centers. - - - Provides a single point of configuration for the cloud. - - + Management Server Overview + + The Management Server is the &PRODUCT; software that manages cloud + resources. By interacting with the Management Server through its UI or + API, you can configure and manage your cloud infrastructure. + + + The Management Server runs on a dedicated server or VM. It controls + allocation of virtual machines to hosts and assigns storage and IP + addresses to the virtual machine instances. The Management Server + runs in a Tomcat container and requires a MySQL database for persistence. + + + The machine must meet the system requirements described in System + Requirements. + + The Management Server: + + + + + Provides the web user interface for the administrator and a + reference user interface for end users. + + + + Provides the APIs for &PRODUCT;. + + + Manages the assignment of guest VMs to particular hosts. + + + + Manages the assignment of public and private IP addresses to + particular accounts. + + + + Manages the allocation of storage to guests as virtual disks. + + + + Manages snapshots, templates, and ISO images, possibly + replicating them across data centers. + + + + Provides a single point of configuration for the cloud. + +
diff --git a/docs/en-US/manual-live-migration.xml b/docs/en-US/manual-live-migration.xml index 390b41768c8..30a5c11a07f 100644 --- a/docs/en-US/manual-live-migration.xml +++ b/docs/en-US/manual-live-migration.xml @@ -31,7 +31,7 @@ The destination host must be in the same cluster as the original host. The VM must not be using local disk storage. The destination host must have enough available capacity. If not, the VM will remain in the "migrating" state until memory becomes available. - (OVM) If the VM is running on the OVM hypervisor, it must not have an ISO attached. Live migration of a VM with attached ISO is not supported in OVM. + To manually live migrate a virtual machine diff --git a/docs/en-US/minimum-system-requirements.xml b/docs/en-US/minimum-system-requirements.xml index 0043a26dba8..dcab0398dc7 100644 --- a/docs/en-US/minimum-system-requirements.xml +++ b/docs/en-US/minimum-system-requirements.xml @@ -30,8 +30,7 @@ Operating system: - Preferred: CentOS/RHEL 6.2+ or Ubuntu 12.04(.1) - Also supported: CentOS/RHEL 5.5 or Ubuntu 10.04 + Preferred: CentOS/RHEL 6.3+ or Ubuntu 12.04(.1) 64-bit x86 CPU (more cores results in better performance) @@ -46,45 +45,26 @@ Host/Hypervisor System Requirements The host is where the cloud services run in the form of guest virtual machines. Each host is one machine that meets the following requirements: - Must be 64-bit and must support HVM (Intel-VT or AMD-V enabled). + Must support HVM (Intel-VT or AMD-V enabled). 64-bit x86 CPU (more cores results in better performance) Hardware virtualization support required 4 GB of memory 36 GB of local disk At least 1 NIC - Statically allocated IP Address + If DHCP is used for hosts, ensure that no conflict occurs between DHCP server used for these hosts and the DHCP router created by &PRODUCT;. Latest hotfixes applied to hypervisor software When you deploy &PRODUCT;, the hypervisor host must not have any VMs already running + All hosts within a cluster must be homogenous. The CPUs must be of the same type, count, and feature flags. Hosts have additional requirements depending on the hypervisor. See the requirements listed at the top of the Installation section for your chosen hypervisor: Be sure you fulfill the additional hypervisor requirements and installation steps provided in this Guide. Hypervisor hosts must be properly prepared to work with CloudStack. For example, the requirements for XenServer are listed under Citrix XenServer Installation. -
- Citrix XenServer requirements - To be determined -
-
- VMware vSphere requirements - To be determined -
-
- KVM requirements - For running a KVM hypervisor the main requirement is the Linux distribution it is running. Although you are not required to run these distributions, it is recommended. - Recommended distributions: - - CentOS / RHEL: 6.2 and 6.3 - Ubuntu: 12.04(.1) - - The main requirement for KVM hypervisors is the libvirt and Qemu version. If you whish to run on a different distribution, make sure you meet the following requirements: - - libvirt: 0.9.4 or higher - Qemu/KVM: 1.0 or higher - -
-
- Oracle VM (OVM) requirements - To be determined -
+ + + + + +
diff --git a/docs/en-US/multi_node_management_server.xml b/docs/en-US/multi_node_management_server.xml new file mode 100644 index 00000000000..1ff713dbd16 --- /dev/null +++ b/docs/en-US/multi_node_management_server.xml @@ -0,0 +1,36 @@ + +%BOOK_ENTITIES; +]> + + +
+ Multi-Node Management Server + The &PRODUCT; Management Server is deployed on one or more front-end servers connected to a single MySQL database. Optionally a pair of hardware load balancers distributes requests from the web. A backup management server set may be deployed using MySQL replication at a remote site to add DR capabilities. + + + + + Multi-Node Management Server + + The administrator must decide the following. + + Whether or not load balancers will be used. + How many Management Servers will be deployed. + Whether MySQL replication will be deployed to enable disaster recovery. + +
diff --git a/docs/en-US/multi_site_deployment.xml b/docs/en-US/multi_site_deployment.xml new file mode 100644 index 00000000000..8ad94aa2a70 --- /dev/null +++ b/docs/en-US/multi_site_deployment.xml @@ -0,0 +1,50 @@ + +%BOOK_ENTITIES; +]> + + +
+ Multi-Site Deployment + The &PRODUCT; platform scales well into multiple sites through the use of zones. The following diagram shows an example of a multi-site deployment. + + + + + Example Of A Multi-Site Deployment + + Data Center 1 houses the primary Management Server as well as zone 1. The MySQL database is replicated in real time to the secondary Management Server installation in Data Center 2. + + + + + Separate Storage Network + + This diagram illustrates a setup with a separate storage network. Each server has four NICs, two connected to pod-level network switches and two connected to storage network switches. + There are two ways to configure the storage network: + + Bonded NIC and redundant switches can be deployed for NFS. In NFS deployments, redundant switches and bonded NICs still result in one network (one CIDR block+ default gateway address). + iSCSI can take advantage of two separate storage networks (two CIDR blocks each with its own default gateway). Multipath iSCSI client can failover and load balance between separate storage networks. + + + + + + NIC Bonding And Multipath I/O + + This diagram illustrates the differences between NIC bonding and Multipath I/O (MPIO). NIC bonding configuration involves only one network. MPIO involves two separate networks. +
diff --git a/docs/en-US/networks-for-users-overview.xml b/docs/en-US/networks-for-users-overview.xml new file mode 100644 index 00000000000..19602c48b2a --- /dev/null +++ b/docs/en-US/networks-for-users-overview.xml @@ -0,0 +1,35 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Overview of Setting Up Networking for Users + People using cloud infrastructure have a variety of needs and preferences when it comes to the networking services provided by the cloud. As a &PRODUCT; administrator, you can do the following things to set up networking for your users: + + Set up physical networks in zones + Set up several different providers for the same service on a single physical network (for example, both Cisco and Juniper firewalls) + Bundle different types of network services into network offerings, so users can choose the desired network services for any given virtual machine + Add new network offerings as time goes on so end users can upgrade to a better class of service on their network + Provide more ways for a network to be accessed by a user, such as through a project of which the user is a member + +
diff --git a/docs/en-US/networks.xml b/docs/en-US/networks.xml new file mode 100644 index 00000000000..a7b9ea12466 --- /dev/null +++ b/docs/en-US/networks.xml @@ -0,0 +1,48 @@ + + +%BOOK_ENTITIES; +]> + + + Managing Networks and Traffic + In a &PRODUCT;, guest VMs can communicate with each other using shared infrastructure with + the security and user perception that the guests have a private LAN. The &PRODUCT; virtual + router is the main component providing networking features for guest traffic. + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/en-US/offerings.xml b/docs/en-US/offerings.xml new file mode 100644 index 00000000000..10252fd8af4 --- /dev/null +++ b/docs/en-US/offerings.xml @@ -0,0 +1,31 @@ + + +%BOOK_ENTITIES; +]> + + + + + Service Offerings + In this chapter we discuss compute, disk, and system service offerings. Network offerings + are discussed in the section on setting up networking for users. + + + diff --git a/docs/en-US/provisioning.xml b/docs/en-US/ovm-install.xml similarity index 77% rename from docs/en-US/provisioning.xml rename to docs/en-US/ovm-install.xml index 8a5b44af8e5..fa4a86b0776 100644 --- a/docs/en-US/provisioning.xml +++ b/docs/en-US/ovm-install.xml @@ -22,8 +22,8 @@ under the License. --> - - Provisioning Your Cloud Infrastructure - - - +
+ Installing OVM for &PRODUCT; + TODO + +
diff --git a/docs/en-US/trial-installation.xml b/docs/en-US/ovm-requirements.xml similarity index 85% rename from docs/en-US/trial-installation.xml rename to docs/en-US/ovm-requirements.xml index 8270e579b17..70a8920a8ac 100644 --- a/docs/en-US/trial-installation.xml +++ b/docs/en-US/ovm-requirements.xml @@ -1,5 +1,5 @@ - %BOOK_ENTITIES; ]> @@ -22,7 +22,7 @@ under the License. --> -
- Trial Installation - Coming soon. +
+ System Requirements for OVM + TODO
diff --git a/docs/en-US/plugin-niciranvp-about.xml b/docs/en-US/plugin-niciranvp-about.xml new file mode 100644 index 00000000000..8d2e20e7756 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-about.xml @@ -0,0 +1,28 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + The Nicira NVP Plugin + + + + diff --git a/docs/en-US/plugin-niciranvp-devicemanagement.xml b/docs/en-US/plugin-niciranvp-devicemanagement.xml new file mode 100644 index 00000000000..2423ce3925d --- /dev/null +++ b/docs/en-US/plugin-niciranvp-devicemanagement.xml @@ -0,0 +1,47 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
+ Device-management + In CloudStack 4.0.x each Nicira NVP setup is considered a "device" that can be added and removed from a physical network. To complete the configuration of the Nicira NVP plugin a device needs to be added to the physical network using the "addNiciraNVPDevice" API call. The plugin is now enabled on the physical network and any guest networks created on that network will be provisioned using the Nicra NVP Controller. + The plugin introduces a set of new API calls to manage the devices, see below or refer to the API reference. + + addNiciraNvpDevice + + + physicalnetworkid: the UUID of the physical network on which the device is configured + hostname: the IP address of the NVP controller + username: the username for access to the NVP API + password: the password for access to the NVP API + transportzoneuuid: the UUID of the transportzone + + + deleteNiciraNVPDevice + + + nvpdeviceid: the UUID of the device + + + listNiciraNVPDevices + + +
\ No newline at end of file diff --git a/docs/en-US/plugin-niciranvp-features.xml b/docs/en-US/plugin-niciranvp-features.xml new file mode 100644 index 00000000000..b67323d56d2 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-features.xml @@ -0,0 +1,29 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
+ Features of the Nicira NVP Plugin + In CloudStack release 4.0.0-incubating this plugin supports the Connectivity service. This service is responsible for creating Layer 2 networks supporting the networks created by Guests. In other words when an tennant creates a new network, instead of the traditional VLAN a logical network will be created by sending the appropriate calls to the Nicira NVP Controller. + The plugin has been tested with Nicira NVP versions 2.1.0, 2.2.0 and 2.2.1 + In CloudStack 4.0.0-incubating only the XenServer hypervisor is supported for use in combination with Nicira NVP + In CloudStack 4.0.0-incubating the UI components for this plugin are not complete, configuration is done by sending commands to the API +
diff --git a/docs/en-US/plugin-niciranvp-guide.xml b/docs/en-US/plugin-niciranvp-guide.xml new file mode 100644 index 00000000000..89c9871021d --- /dev/null +++ b/docs/en-US/plugin-niciranvp-guide.xml @@ -0,0 +1,31 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + + Plugin Guide for the Nicira NVP Plugin + + + + diff --git a/docs/en-US/cloudstack_installation.xml b/docs/en-US/plugin-niciranvp-introduction.xml similarity index 58% rename from docs/en-US/cloudstack_installation.xml rename to docs/en-US/plugin-niciranvp-introduction.xml index f6ef3cf7c4d..9c1d42df32d 100644 --- a/docs/en-US/cloudstack_installation.xml +++ b/docs/en-US/plugin-niciranvp-introduction.xml @@ -1,9 +1,10 @@ - - + %BOOK_ENTITIES; + +%xinclude; ]> - - - - - - - - +
+ Introduction to the Nicira NVP Plugin + The Nicira NVP plugin allows CloudStack to use the Nicira solution for virtualized network as a provider for CloudStack networks and services. +
diff --git a/docs/en-US/plugin-niciranvp-preparations.xml b/docs/en-US/plugin-niciranvp-preparations.xml new file mode 100644 index 00000000000..95a25bdca26 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-preparations.xml @@ -0,0 +1,36 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
+ Prerequisites + Before enabling the Nicira NVP plugin the NVP Controller needs to be configured. Please review the NVP User Guide on how to do that. + CloudStack needs to have at least one physical network with the isolation method set to "STT". This network should be enabled for the Guest traffic type. + The Guest traffic type should be configured with the traffic label that matches the name of the Integration Bridge on XenServer. See the Nicira NVP User Guide for more details on how to set this up in XenServer. + Make sure you have the following information ready: + + The IP address of the NVP Controller + The username to access the API + The password to access the API + The UUID of the Transport Zone that contains the hypervisors in this Zone + The UUID of the Physical Network that will used for the Guest networks + +
\ No newline at end of file diff --git a/docs/en-US/plugin-niciranvp-provider.xml b/docs/en-US/plugin-niciranvp-provider.xml new file mode 100644 index 00000000000..d81db99d9c0 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-provider.xml @@ -0,0 +1,42 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
+ Enabling the service provider + To allow CloudStack to use the Nicira NVP Plugin the network service provider needs to be enabled on the physical network. The following sequence of API calls will enable the network service provider + + addNetworkServiceProvider + + + name = "NiciraNVP" + physicalnetworkid = <the uuid of the physical network> + + + updateNetworkServiceProvider + + + id = <the provider uuid returned by the previous call> + state = "Enabled" + + + +
\ No newline at end of file diff --git a/docs/en-US/plugin-niciranvp-revisions.xml b/docs/en-US/plugin-niciranvp-revisions.xml new file mode 100644 index 00000000000..b8e6935c5d1 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-revisions.xml @@ -0,0 +1,45 @@ + + +%BOOK_ENTITIES; +]> + + + + + Revision History + + + + 0-0 + Wed Oct 03 2012 + + Hugo + Trippaers + hugo@apache.org + + + + Documentation created for 4.0.0-incubating version of the NVP Plugin + + + + + + diff --git a/docs/en-US/plugin-niciranvp-tables.xml b/docs/en-US/plugin-niciranvp-tables.xml new file mode 100644 index 00000000000..4f816550b30 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-tables.xml @@ -0,0 +1,51 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
+ Database tables + The following tables are added to the cloud database for the Nicira NVP Plugin + + nicira_nvp_nic_map, contains a mapping from nic to logical switch port + + + id + logicalswitch, uuid of the logical switch this port is connected to + logicalswitchport, uuid of the logical switch port for this nic + nic, the CloudStack uuid for this nic, reference to the nics table + + + + + external_nicira_nvp_devices, contains all configured devices + + + id + uuid + physical_network_id, the physical network this device is configured on + provider_name, set to "NiciraNvp" + device_name, display name for this device + host_id, reference to the host table with the device configuration + + + + +
\ No newline at end of file diff --git a/docs/en-US/plugin-niciranvp-troubleshooting.xml b/docs/en-US/plugin-niciranvp-troubleshooting.xml new file mode 100644 index 00000000000..02b06555914 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-troubleshooting.xml @@ -0,0 +1,28 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + Troubleshooting the Nicira NVP Plugin + + + + diff --git a/docs/en-US/plugin-niciranvp-usage.xml b/docs/en-US/plugin-niciranvp-usage.xml new file mode 100644 index 00000000000..17413387ea4 --- /dev/null +++ b/docs/en-US/plugin-niciranvp-usage.xml @@ -0,0 +1,29 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + + + Using the Nicira NVP Plugin + + + + + diff --git a/docs/en-US/plugin-niciranvp-uuidreferences.xml b/docs/en-US/plugin-niciranvp-uuidreferences.xml new file mode 100644 index 00000000000..c912971736b --- /dev/null +++ b/docs/en-US/plugin-niciranvp-uuidreferences.xml @@ -0,0 +1,30 @@ + + +%BOOK_ENTITIES; + +%xinclude; +]> + +
+ UUID References + The plugin maintains several references in the CloudStack database to items created on the NVP Controller. + Every guest network this is created will have its broadcast type set to Lswitch and if the network is in state "Implemented", the broadcast URI will have the UUID of the Logical Switch that was created for this network on the NVP Controller. + The Nics that are connected to one of the Logical Switches will have their Logical Switch Port UUID listed in the nicira_nvp_nic_map table + All devices created on the NVP Controller will have a tag set to domain-account of the owner of the network, this string can be used to search for items in the NVP Controller. + +
\ No newline at end of file diff --git a/docs/en-US/pod-add.xml b/docs/en-US/pod-add.xml index 419e333272e..2a2b08753a9 100644 --- a/docs/en-US/pod-add.xml +++ b/docs/en-US/pod-add.xml @@ -1,28 +1,43 @@ - %BOOK_ENTITIES; ]>
- Adding a Pod - TODO + Adding a Pod + When you created a new zone, &PRODUCT; adds the first pod for you. You can add more pods at any time using the procedure in this section. + + Log in to the &PRODUCT; UI. See . + In the left navigation, choose Infrastructure. In Zones, click View More, then click the zone to which you want to add a pod. + Click the Compute and Storage tab. In the Pods node of the diagram, click View All. + Click Add Pod. + Enter the following details in the dialog. + + Name. The name of the pod. + Gateway. The gateway for the hosts in that pod. + Netmask. The network prefix that defines the pod's subnet. Use CIDR notation. + Start/End Reserved System IP. The IP range in the management network that &PRODUCT; uses to manage various system VMs, such as Secondary Storage VMs, Console Proxy VMs, and DHCP. For more information, see System Reserved IP Addresses. + + + Click OK. +
diff --git a/docs/en-US/prepare-system-vm-template.xml b/docs/en-US/prepare-system-vm-template.xml index 160cea426ed..5ed78f7d5a3 100644 --- a/docs/en-US/prepare-system-vm-template.xml +++ b/docs/en-US/prepare-system-vm-template.xml @@ -1,5 +1,5 @@ - %BOOK_ENTITIES; ]> @@ -21,37 +21,51 @@ specific language governing permissions and limitations under the License. --> -
- Prepare the System VM Template - Secondary storage must be seeded with a template that is used for &PRODUCT; system VMs. - When copying and pasting a command, be sure the command has pasted as a single line before executing. Some document viewers may introduce unwanted line breaks in copied text. - - On the Management Server, run one or more of the following cloud-install-sys-tmplt commands to retrieve and decompress the system VM template. Run the command for each hypervisor type that you expect end users to run in this Zone. - If your secondary storage mount point is not named /mnt/secondary, substitute your own mount point name. - If you set the &PRODUCT; database encryption type to "web" when you set up the database, you must now add the parameter -s <management-server-secret-key>. See About Password and Key Encryption. - This process will require approximately 5 GB of free space on the local file system and up to 30 minutes each time it runs. - - For XenServer: - # /usr/lib64/cloud/agent/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.vhd.bz2 -h xenserver -s <optional-management-server-secret-key> -F - - For vSphere: - # /usr/lib64/cloud/agent/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.ova -h vmware -s <optional-management-server-secret-key> -F - - For KVM: - # /usr/lib64/cloud/agent/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h kvm -s <optional-management-server-secret-key> -F - - - - If you are using a separate NFS server, perform this step. If you are using the Management - Server as the NFS server, you MUST NOT perform this step. - When the script has finished, unmount secondary storage and remove the created directory. - -# umount /mnt/secondary -# rmdir /mnt/secondary - - - Repeat these steps for each secondary storage server. - - + Prepare the System VM Template + Secondary storage must be seeded with a template that is used for &PRODUCT; system + VMs. + + When copying and pasting a command, be sure the command has pasted as a single line before + executing. Some document viewers may introduce unwanted line breaks in copied text. + + + + On the Management Server, run one or more of the following cloud-install-sys-tmplt + commands to retrieve and decompress the system VM template. Run the command for each + hypervisor type that you expect end users to run in this Zone. + If your secondary storage mount point is not named /mnt/secondary, substitute your own + mount point name. + If you set the &PRODUCT; database encryption type to "web" when you set up the database, + you must now add the parameter -s <management-server-secret-key>. See About Password + and Key Encryption. + This process will require approximately 5 GB of free space on the local file system and + up to 30 minutes each time it runs. + + + For XenServer: + # /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.vhd.bz2 -h xenserver -s <optional-management-server-secret-key> -F + + + For vSphere: + # /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.ova -h vmware -s <optional-management-server-secret-key> -F + + + For KVM: + # /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h kvm -s <optional-management-server-secret-key> -F + + + + + If you are using a separate NFS server, perform this step. If you are using the + Management Server as the NFS server, you MUST NOT perform this step. + When the script has finished, unmount secondary storage and remove the created + directory. + # umount /mnt/secondary +# rmdir /mnt/secondary + + + Repeat these steps for each secondary storage server. + +
diff --git a/docs/en-US/prepare_os.xml b/docs/en-US/prepare_os.xml deleted file mode 100644 index f0fc201cde7..00000000000 --- a/docs/en-US/prepare_os.xml +++ /dev/null @@ -1,106 +0,0 @@ - - -%BOOK_ENTITIES; -]> - - - -
- Prepare the Operating System - The OS must be prepared to host the Management Server using the following steps. These steps must be performed on each Management Server node. - - Log in to your OS as root. - Check for a fully qualified hostname. - # hostname --fqdn - This should return a fully qualified hostname such as "kvm1.lab.example.org". If it does not, edit /etc/hosts so that it does. - - Set SELinux to be permissive by default. - - Check to see whether SELinux is installed on your machine. If not, you can skip to step 4. - In RHEL or CentOS, SELinux are installed and enabled by default. You can verify this with: - # rpm -qa | grep selinux - In Ubuntu, SELinux is not installed by default. You can verify this with: - # dpkg --list 'selinux' - - Set the SELINUX variable in /etc/selinux/config to “permissive”. This ensures that the permissive setting will be maintained after a system reboot. - In RHEL or CentOS: - # vi /etc/selinux/config - In Ubuntu (do this step only if SELinux was found on the machine in the previous step): - # selinux-config-enforcing permissive - - Then set SELinux to permissive starting immediately, without requiring a system reboot. - In CentOS: - # setenforce permissive - In RHEL: - # setenforce 0 - In Ubuntu (do this step only if SELinux was found on the machine): - # setenforce permissive - - - - Make sure that the Management Server can reach the Internet. - # ping www.google.com - - (RHEL 6.2) If you do not have a Red Hat Network account, you need to prepare a local Yum repository. - - If you are working with a physical host, insert the RHEL 6.2 installation CD. If you are using a VM, attach the RHEL6 ISO. - Mount the CDROM to /media. - Create a repo file at /etc/yum.repos.d/rhel6.repo. In the file, insert the following lines: - -[rhel] -name=rhel6 -baseurl=file:///media -enabled=1 -gpgcheck=0 - - - - - Turn on NTP for time synchronization. - NTP is required to synchronize the clocks of the servers in your cloud. - - Install NTP. - On RHEL or CentOS: - # yum install ntp - On Ubuntu: - # apt-get install ntp - - Edit the NTP configuration file to point to your NTP server. - # vi /etc/ntp.conf - For example, you can use one of the following: - 0.xenserver.pool.ntp.org -1.xenserver.pool.ntp.org -2.xenserver.pool.ntp.org -3.xenserver.pool.ntp.org - - - Restart the NTP client. - # service ntpd restart - - Make sure NTP will start again upon reboot. - On RHEL or CentOS: - # chkconfig ntpd on - On Ubuntu: - # chkconfig ntp on - - - - -
diff --git a/docs/en-US/primary-storage-add.xml b/docs/en-US/primary-storage-add.xml index 588d491a07a..5581e9e79b1 100644 --- a/docs/en-US/primary-storage-add.xml +++ b/docs/en-US/primary-storage-add.xml @@ -23,6 +23,52 @@ -->
- Adding Primary Storage - TODO + Add Primary Storage +
+ System Requirements for Primary Storage + Hardware requirements: + + Any standards-compliant iSCSI or NFS server that is supported by the underlying hypervisor. + The storage server should be a machine with a large number of disks. The disks should ideally be managed by a hardware RAID controller. + Minimum required capacity depends on your needs. + + When setting up primary storage, follow these restrictions: + + Primary storage cannot be added until a host has been added to the cluster. + If you do not provision shared primary storage, you must set the global configuration parameter system.vm.local.storage.required to true, or else you will not be able to start VMs. + +
+
+ Adding Primary Stroage + When you create a new zone, the first primary storage is added as part of that procedure. You can add primary storage servers at any time, such as when adding a new cluster or adding more servers to an existing cluster. + Be sure there is nothing stored on the server. Adding the server to &PRODUCT; will destroy any existing data. + + Log in to the &PRODUCT; UI (see ). + In the left navigation, choose Infrastructure. In Zones, click View More, then click the zone in which you want to add the primary storage. + Click the Compute tab. + In the Primary Storage node of the diagram, click View All. + Click Add Primary Storage. + + Provide the following information in the dialog. The information required varies depending on your choice in Protocol. + + Pod. The pod for the storage device. + Cluster. The cluster for the storage device. + Name. The name of the storage device. + Protocol. For XenServer, choose either NFS, iSCSI, or PreSetup. For KVM, choose NFS or SharedMountPoint. For vSphere choose either VMFS (iSCSI or FiberChannel) or NFS. + Server (for NFS, iSCSI, or PreSetup). The IP address or DNS name of the storage device. + Server (for VMFS). The IP address or DNS name of the vCenter server. + Path (for NFS). In NFS this is the exported path from the server. + Path (for VMFS). In vSphere this is a combination of the datacenter name and the datastore name. The format is "/" datacenter name "/" datastore name. For example, "/cloud.dc.VM/cluster1datastore". + Path (for SharedMountPoint). With KVM this is the path on each host that is where this primary storage is mounted. For example, "/mnt/primary". + SR Name-Label (for PreSetup). Enter the name-label of the SR that has been set up outside &PRODUCT;. + Target IQN (for iSCSI). In iSCSI this is the IQN of the target. For example, iqn.1986-03.com.sun:02:01ec9bb549-1271378984. + Lun # (for iSCSI). In iSCSI this is the LUN number. For example, 3. + Tags (optional). The comma-separated list of tags for this storage device. It should be an equivalent set or superset of the tags on your disk offerings.. + + The tag sets on primary storage across clusters in a Zone must be identical. For example, if cluster A provides primary storage that has tags T1 and T2, all other clusters in the Zone must also provide primary storage that has tags T1 and T2. + + Click OK. + + +
diff --git a/docs/en-US/primary-storage.xml b/docs/en-US/primary-storage.xml index 4860488fb29..4cefa83c190 100644 --- a/docs/en-US/primary-storage.xml +++ b/docs/en-US/primary-storage.xml @@ -23,6 +23,11 @@ -->
- Primary Storage - This section gives concepts and technical details about CloudPlatform primary storage. For information about how to install and configure primary storage through the CloudPlatform UI, see the Advanced Installation Guide. -
+ Primary Storage + This section gives concepts and technical details about CloudPlatform primary storage. For information about how to install and configure primary storage through the CloudPlatform UI, see the Advanced Installation Guide. + + + + + +
diff --git a/docs/en-US/projects-overview.xml b/docs/en-US/projects-overview.xml new file mode 100644 index 00000000000..4f9a833b5ed --- /dev/null +++ b/docs/en-US/projects-overview.xml @@ -0,0 +1,31 @@ + + +%BOOK_ENTITIES; +]> + + +
+ Overview of Projects + Projects are used to organize people and resources. &PRODUCT; users within a single domain can group themselves into project teams so they can collaborate and share virtual resources such as VMs, snapshots, templates, data disks, and IP addresses. &PRODUCT; tracks resource usage per project as well as per user, so the usage can be billed to either a user account or a project. For example, a private cloud within a software company might have all members of the QA department assigned to one project, so the company can track the resources used in testing while the project members can more easily isolate their efforts from other users of the same cloud + You can configure &PRODUCT; to allow any user to create a new project, or you can restrict that ability to just &PRODUCT; administrators. Once you have created a project, you become that project’s administrator, and you can add others within your domain to the project. &PRODUCT; can be set up either so that you can add people directly to a project, or so that you have to send an invitation which the recipient must accept. Project members can view and manage all virtual resources created by anyone in the project (for example, share VMs). A user can be a member of any number of projects and can switch views in the &PRODUCT; UI to show only project-related information, such as project VMs, fellow project members, project-related alerts, and so on. + The project administrator can pass on the role to another project member. The project administrator can also add more members, remove members from the project, set new resource limits (as long as they are below the global defaults set by the &PRODUCT; administrator), and delete the project. When the administrator removes a member from the project, resources created by that user, such as VM instances, remain with the project. This brings us to the subject of resource ownership and which resources can be used by a project. + Resources created within a project are owned by the project, not by any particular &PRODUCT; account, and they can be used only within the project. A user who belongs to one or more projects can still create resources outside of those projects, and those resources belong to the user’s account; they will not be counted against the project’s usage or resource limits. You can create project-level networks to isolate traffic within the project and provide network services such as port forwarding, load balancing, VPN, and static NAT. A project can also make use of certain types of resources from outside the project, if those resources are shared. For example, a shared network or public template is available to any project in the domain. A project can get access to a private template if the template’s owner will grant permission. A project can use any service offering or disk offering available in its domain; however, you can not create private service and disk offerings at the project level.. +
+ diff --git a/docs/en-US/projects.xml b/docs/en-US/projects.xml index 0390f528f3f..39ce96bd3bc 100644 --- a/docs/en-US/projects.xml +++ b/docs/en-US/projects.xml @@ -5,27 +5,31 @@ ]> -
- Projects - Projects are used to organize people and resources. &PRODUCT; users within a single domain can group themselves into project teams so they can collaborate and share virtual resources such as VMs, snapshots, templates, data disks, and IP addresses. &PRODUCT; tracks resource usage per project as well as per user, so the usage can be billed to either a user account or a project. For example, a private cloud within a software company might have all members of the QA department assigned to one project, so the company can track the resources used in testing while the project members can more easily isolate their efforts from other users of the same cloud - You can configure &PRODUCT; to allow any user to create a new project, or you can restrict that ability to just &PRODUCT; administrators. Once you have created a project, you become that project’s administrator, and you can add others within your domain to the project. &PRODUCT; can be set up either so that you can add people directly to a project, or so that you have to send an invitation which the recipient must accept. Project members can view and manage all virtual resources created by anyone in the project (for example, share VMs). A user can be a member of any number of projects and can switch views in the &PRODUCT; UI to show only project-related information, such as project VMs, fellow project members, project-related alerts, and so on. - The project administrator can pass on the role to another project member. The project administrator can also add more members, remove members from the project, set new resource limits (as long as they are below the global defaults set by the &PRODUCT; administrator), and delete the project. When the administrator removes a member from the project, resources created by that user, such as VM instances, remain with the project. This brings us to the subject of resource ownership and which resources can be used by a project. - Resources created within a project are owned by the project, not by any particular &PRODUCT; account, and they can be used only within the project. A user who belongs to one or more projects can still create resources outside of those projects, and those resources belong to the user’s account; they will not be counted against the project’s usage or resource limits. You can create project-level networks to isolate traffic within the project and provide network services such as port forwarding, load balancing, VPN, and static NAT. A project can also make use of certain types of resources from outside the project, if those resources are shared. For example, a shared network or public template is available to any project in the domain. A project can get access to a private template if the template’s owner will grant permission. A project can use any service offering or disk offering available in its domain; however, you can not create private service and disk offerings at the project level.. -
+ + Using Projects to Organize Users and Resources + + + + + + + + + diff --git a/docs/en-US/provisioning-steps.xml b/docs/en-US/provisioning-steps.xml index e553d3c5f54..98717435c62 100644 --- a/docs/en-US/provisioning-steps.xml +++ b/docs/en-US/provisioning-steps.xml @@ -22,11 +22,10 @@ under the License. --> -
+ Steps to Provisioning Your Cloud Infrastructure This section tells how to add zones, pods, clusters, hosts, storage, and networks to your cloud. If you are unfamiliar with these entities, please begin by looking through . - @@ -34,5 +33,4 @@ - -
+ diff --git a/docs/en-US/provisioning-steps.xml.orig b/docs/en-US/provisioning-steps.xml.orig new file mode 100644 index 00000000000..b532783b2d2 --- /dev/null +++ b/docs/en-US/provisioning-steps.xml.orig @@ -0,0 +1,42 @@ + + +%BOOK_ENTITIES; +]> + + + + + Steps to Provisioning Your Cloud Infrastructure + This section tells how to add zones, pods, clusters, hosts, storage, and networks to your cloud. If you are unfamiliar with these entities, please begin by looking through . + + + + + + + + + +<<<<<<< HEAD + + +======= + +>>>>>>> Promote sections to chapters: Cloud Infrastructure Concepts and Provisioning Steps. diff --git a/docs/en-US/re-install-hosts.xml b/docs/en-US/re-install-hosts.xml new file mode 100644 index 00000000000..b8092adb44a --- /dev/null +++ b/docs/en-US/re-install-hosts.xml @@ -0,0 +1,26 @@ + + +%BOOK_ENTITIES; +]> + +
+ Re-Installing Hosts + You can re-install a host after placing it in maintenance mode and then removing it. If a + host is down and cannot be placed in maintenance mode, it should still be removed before the + re-install. +
diff --git a/docs/en-US/release-ip-for-vpc.xml b/docs/en-US/release-ip-for-vpc.xml new file mode 100644 index 00000000000..466ec663a17 --- /dev/null +++ b/docs/en-US/release-ip-for-vpc.xml @@ -0,0 +1,80 @@ + + +%BOOK_ENTITIES; +]> + +
+ Releasing an IP Address Alloted to a VPC + The IP address is a limited resource. If you no longer need a particular IP, you can + disassociate it from its VPC and return it to the pool of available addresses. An IP address can + be released from its tier, only when all the networking ( port forwarding, load balancing, or + StaticNAT ) rules are removed for this IP address. The released IP address will still belongs to + the same VPC. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Click the Configure button of the VPC whose IP you want to release. + The VPC page is displayed where all the tiers you created are listed in a + diagram. + + + Click the Settings icon. + The following options are displayed. + + + IP Addresses + + + Gateways + + + Site-to-Site VPN + + + Network ACLs + + + + + Select IP Addresses. + The IP Addresses page is displayed. + + + Click the IP you want to release. + + + In the Details tab, click the Release IP button + + + + + release-ip-icon.png: button to release an IP. + + + + +
diff --git a/docs/en-US/remove-tier.xml b/docs/en-US/remove-tier.xml new file mode 100644 index 00000000000..b5996eb2de3 --- /dev/null +++ b/docs/en-US/remove-tier.xml @@ -0,0 +1,55 @@ + + +%BOOK_ENTITIES; +]> + +
+ Removing Tiers + You can remove a tier from a VPC. A removed tier cannot be revoked. When a tier is removed, + only the resources of the tier are expunged. All the network rules (port forwarding, load + balancing and staticNAT) and the IP addresses associated to the tier are removed. The IP address + still be belonging to the same VPC. + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPC that you have created for the account is listed in the page. + + + Click the Configure button of the VPC for which you want to set up tiers. + The Configure VPC page is displayed. Locate the tier you want to work with. + + + Click the Remove VPC button: + + + + + + remove-tier.png: removing a tier from a vpc. + + + Wait for some time for the tier to be removed. + + +
diff --git a/docs/en-US/remove-vpc.xml b/docs/en-US/remove-vpc.xml new file mode 100644 index 00000000000..c5eff850fd3 --- /dev/null +++ b/docs/en-US/remove-vpc.xml @@ -0,0 +1,68 @@ + + +%BOOK_ENTITIES; +]> + +
+ Editing, Restarting, and Removing a Virtual Private Cloud + + Ensure that all the tiers are removed before you remove a VPC. + + + + Log in to the &PRODUCT; UI as an administrator or end user. + + + In the left navigation, choose Network. + + + In the Select view, select VPC. + All the VPCs that you have created for the account is listed in the page. + + + Select the VPC you want to work with. + + + To remove, click the Remove VPC button + + + + + remove-vpc.png: button to remove a VPC + + + You can edit the name and description of a VPC. To do that, select the VPC, then click + the Edit button. + + + + + edit-icon.png: button to edit a VPC + + + To restart a VPC, select the VPC, then click the Restart button. + + + + + restart-vpc.png: button to restart a VPC + + + + +
diff --git a/docs/en-US/removing-hosts.xml b/docs/en-US/removing-hosts.xml new file mode 100644 index 00000000000..468f36ecd3f --- /dev/null +++ b/docs/en-US/removing-hosts.xml @@ -0,0 +1,30 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Removing Hosts + Hosts can be removed from the cloud as needed. The procedure to remove a host depends on the hypervisor type. + + +
diff --git a/docs/en-US/runtime-behavior-of-primary-storage.xml b/docs/en-US/runtime-behavior-of-primary-storage.xml index c6563907131..479ebce1ce1 100644 --- a/docs/en-US/runtime-behavior-of-primary-storage.xml +++ b/docs/en-US/runtime-behavior-of-primary-storage.xml @@ -24,7 +24,7 @@
Runtime Behavior of Primary Storage - Root volumes are created automatically when a virtual machine is created. Root volumes are deleted when the VM is destroyed. Data volumes can be created and dynamically attached to VMs (although, when the Oracle VM hypervisor is used, the VM must be stopped before an additional volume can be attached). Data volumes are not deleted when VMs are destroyed. + Root volumes are created automatically when a virtual machine is created. Root volumes are deleted when the VM is destroyed. Data volumes can be created and dynamically attached to VMs. Data volumes are not deleted when VMs are destroyed. Administrators should monitor the capacity of primary storage devices and add additional primary storage as needed. See the Advanced Installation Guide. Administrators add primary storage to the system by creating a &PRODUCT; storage pool. Each storage pool is associated with a cluster.
diff --git a/docs/en-US/secondary-storage-add.xml b/docs/en-US/secondary-storage-add.xml index 15e8c742657..e1f45cdec66 100644 --- a/docs/en-US/secondary-storage-add.xml +++ b/docs/en-US/secondary-storage-add.xml @@ -23,6 +23,26 @@ -->
+ Add Secondary Storage +
+ System Requirements for Secondary Storage + + NFS storage appliance or Linux NFS server + (Optional) OpenStack Object Storage (Swift) (see http://swift.openstack.org) + 100GB minimum capacity + A secondary storage device must be located in the same zone as the guest VMs it serves. + Each Secondary Storage server must be available to all hosts in the zone. + +
+
Adding Secondary Storage - TODO + When you create a new zone, the first secondary storage is added as part of that procedure. You can add secondary storage servers at any time to add more servers to an existing zone. + Be sure there is nothing stored on the server. Adding the server to &PRODUCT; will destroy any existing data. + + If you are going to use Swift for cloud-wide secondary storage, you must add the Swift storage to &PRODUCT; before you add the local zone secondary storage servers. See . + To prepare for local zone secondary storage, you should have created and mounted an NFS share during Management Server installation. See .See Preparing NFS Shares in the Installation Guide. + Make sure you prepared the system VM template during Management Server installation. See .See Prepare the System VM Template in the Installation Guide. + Now that the secondary storage server for per-zone storage is prepared, add it to &PRODUCT;. Secondary storage is added as part of the procedure for adding a new zone. See . + +
diff --git a/docs/en-US/security-groups.xml b/docs/en-US/security-groups.xml index fdb4ee90a09..3c08965c8d3 100644 --- a/docs/en-US/security-groups.xml +++ b/docs/en-US/security-groups.xml @@ -23,6 +23,8 @@ -->
+ Security Groups + diff --git a/docs/en-US/separate_storage_network.xml b/docs/en-US/separate_storage_network.xml new file mode 100644 index 00000000000..c3f6330cb14 --- /dev/null +++ b/docs/en-US/separate_storage_network.xml @@ -0,0 +1,24 @@ + +%BOOK_ENTITIES; +]> + + +
+ Separate Storage Network + In the large-scale redundant setup described in the previous section, storage traffic can overload the management network. A separate storage network is optional for deployments. Storage protocols such as iSCSI are sensitive to network delays. A separate storage network ensures guest network traffic contention does not impact storage performance. +
\ No newline at end of file diff --git a/docs/en-US/set-global-project-resource-limits.xml b/docs/en-US/set-global-project-resource-limits.xml new file mode 100644 index 00000000000..d91942ad8db --- /dev/null +++ b/docs/en-US/set-global-project-resource-limits.xml @@ -0,0 +1,82 @@ + + +%BOOK_ENTITIES; +]> + +
+ Setting the Global Project Resource Limits + + + Log in as administrator to the &PRODUCT; UI. + + + In the left navigation, click Global Settings. + + + In the search box, type max.projects and click the search button. + + + In the search results, you will see the parameters you can use to set per-project + maximum resource amounts that apply to all projects in the cloud. No project can have more + resources, but an individual project can have lower limits. Click the edit button to set + each parameter. + + + + + editbutton.png: Edits parameters + + + + + + + max.project.public.ips + Maximum number of public IP addresses that can be owned by any project in + the cloud. See About Public IP Addresses. + + + max.project.snapshots + Maximum number of snapshots that can be owned by any project in the + cloud. See Working with Snapshots. + + + max.project.templates + Maximum number of templates that can be owned by any project in the + cloud. See Working with Templates. + + + max.project.uservms + Maximum number of guest virtual machines that can be owned by any project + in the cloud. See Working With Virtual Machines. + + + max.project.volumes + Maximum number of data volumes that can be owned by any project in the + cloud. See Working with Volumes. + + + + + + + Restart the Management Server. + # service cloud-management restart + + +
diff --git a/docs/en-US/set-per-project-resource-limits.xml b/docs/en-US/set-per-project-resource-limits.xml new file mode 100644 index 00000000000..a0f64ea5a38 --- /dev/null +++ b/docs/en-US/set-per-project-resource-limits.xml @@ -0,0 +1,55 @@ + + +%BOOK_ENTITIES; +]> + +
+ Setting Per-Project Resource Limits + The &PRODUCT; root administrator or the domain administrator of the domain where the project + resides can set new resource limits for an individual project. The project owner can set + resource limits only if the owner is also a domain or root administrator. + The new limits must be below the global default limits set by the &PRODUCT; administrator + (as described in ). If the project already + owns more of a given type of resource than the new maximum, the resources are not affected; + however, the project can not add any new resources of that type until the total drops below the + new limit. + + + Log in as administrator to the &PRODUCT; UI. + + + In the left navigation, click Projects. + + + In Select View, choose Projects. + + + Click the name of the project you want to work with. + + + Click the Resources tab. This tab lists the current maximum amount that the project is + allowed to own for each type of resource. + + + Type new values for one or more resources. + + + Click Apply. + + +
diff --git a/docs/en-US/set-projects-creator-permissions.xml b/docs/en-US/set-projects-creator-permissions.xml index 1d9309f8837..9b272f6bc7e 100644 --- a/docs/en-US/set-projects-creator-permissions.xml +++ b/docs/en-US/set-projects-creator-permissions.xml @@ -3,45 +3,60 @@ %BOOK_ENTITIES; ]> - -
- Setting Project Creator Permissions - You can configure &PRODUCT; to allow any user to create a new project, or you can restrict that ability to just &PRODUCT; administrators. - - Log in as administrator to the &PRODUCT; UI. - In the left navigation, click Global Settings. - In the search box, type allow.user.create.projects. - Click the edit button to set the parameter. - - - - editbutton.png: Edits parameters - - - - - allow.user.create.projects - Set to true to allow end users to create projects. Set to false if you want only the &PRODUCT; root administrator and domain administrators to create projects. - - - Restart the Management Server.# service cloud-management restart - + Setting Project Creator Permissions + You can configure &PRODUCT; to allow any user to create a new project, or you can restrict + that ability to just &PRODUCT; administrators. + + + Log in as administrator to the &PRODUCT; UI. + + + In the left navigation, click Global Settings. + + + In the search box, type allow.user.create.projects. + + + Click the edit button to set the parameter. + + + + + editbutton.png: Edits parameters + + + + + + + allow.user.create.projects + Set to true to allow end users to create projects. Set to false if you + want only the &PRODUCT; root administrator and domain administrators to create + projects. + + + + + + + Restart the Management Server. + # service cloud-management restart + +
diff --git a/docs/en-US/set-resource-limits-for-projects.xml b/docs/en-US/set-resource-limits-for-projects.xml index 2c331acde51..669ca259372 100644 --- a/docs/en-US/set-resource-limits-for-projects.xml +++ b/docs/en-US/set-resource-limits-for-projects.xml @@ -3,26 +3,30 @@ %BOOK_ENTITIES; ]> - -
- Setting Resource Limits for Projects - The &PRODUCT; administrator can set global default limits to control the amount of resources that can be owned by each project in the cloud. This serves to prevent uncontrolled usage of resources such as snapshots, IP addresses, and virtual machine instances. Domain administrators can override these resource limits for individual projects with their domains, as long as the new limits are below the global defaults set by the &PRODUCT; root administrator. The root administrator can also set lower resource limits for any project in the cloud + Setting Resource Limits for Projects + The &PRODUCT; administrator can set global default limits to control the amount of resources + that can be owned by each project in the cloud. This serves to prevent uncontrolled usage of + resources such as snapshots, IP addresses, and virtual machine instances. Domain administrators + can override these resource limits for individual projects with their domains, as long as the + new limits are below the global defaults set by the &PRODUCT; root administrator. The root + administrator can also set lower resource limits for any project in the cloud + +
diff --git a/docs/en-US/set-up-network-for-users.xml b/docs/en-US/set-up-network-for-users.xml index 4e2be48e312..2b409232037 100644 --- a/docs/en-US/set-up-network-for-users.xml +++ b/docs/en-US/set-up-network-for-users.xml @@ -22,14 +22,10 @@ under the License. --> -
+ Setting Up Networking for Users - People using cloud infrastructure have a variety of needs and preferences when it comes to the networking services provided by the cloud. As a &PRODUCT; administrator, you can do the following things to set up networking for your users: - - Set up physical networks in zones - Set up several different providers for the same service on a single physical network (for example, both Cisco and Juniper firewalls) - Bundle different types of network services into network offerings, so users can choose the desired network services for any given virtual machine - Add new network offerings as time goes on so end users can upgrade to a better class of service on their network - Provide more ways for a network to be accessed by a user, such as through a project of which the user is a member - -
+ + + + + diff --git a/docs/en-US/small_scale_deployment.xml b/docs/en-US/small_scale_deployment.xml new file mode 100644 index 00000000000..bba2b9a7573 --- /dev/null +++ b/docs/en-US/small_scale_deployment.xml @@ -0,0 +1,37 @@ + +%BOOK_ENTITIES; +]> + + + +
+ Small-Scale Deployment + + + + + Small-Scale Deployment + + This diagram illustrates the network architecture of a small-scale &PRODUCT; deployment. + + A firewall provides a connection to the Internet. The firewall is configured in NAT mode. The firewall forwards HTTP requests and API calls from the Internet to the Management Server. The Management Server resides on the management network. + A layer-2 switch connects all physical servers and storage. + A single NFS server functions as both the primary and secondary storage. + The Management Server is connected to the management network. + +
diff --git a/docs/en-US/source-prereqs.xml b/docs/en-US/source-prereqs.xml new file mode 100644 index 00000000000..6c2bc2a3cb8 --- /dev/null +++ b/docs/en-US/source-prereqs.xml @@ -0,0 +1,42 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Prerequisites for building Apache CloudStack + + There are a number of prerequisites needed to build &PRODUCT;. This + document assumes compilation on a Linux system that uses RPMs or DEBs + for package management. + + + The minimum bootstrapped prerequisites for building &PRODUCT; includes + the following: + + ant + maven (version 3) + Java (Java 6/OpenJDK 1.6) + rpmbuild or dpkg-dev + + +
diff --git a/docs/en-US/source.xml b/docs/en-US/source.xml new file mode 100644 index 00000000000..3cb4af2321f --- /dev/null +++ b/docs/en-US/source.xml @@ -0,0 +1,47 @@ + + +%BOOK_ENTITIES; +]> + + + + + Building from Source + The official &PRODUCT; release is always in source code form. While there may + exist convenience binaries in various forms from a number of places, the + source is the canonical release will be source. In this document we'll cover + acquiring the source release, building that into binary, deployable packages. + + + While building and deploying directly from source is certainly possible, the reality + of Infrastructure-as-a-Service cloud computing implies a need to deploy packages on + a potentially large number of systems, which RPMs and DEBs fill nicely. + + + Building and deploying directly from source is thus outside the scope of this + document, but is documented in the INSTALL.md file in the release. + + + + + + + + diff --git a/docs/en-US/storage-overview.xml b/docs/en-US/storage-overview.xml new file mode 100644 index 00000000000..bebf441ab60 --- /dev/null +++ b/docs/en-US/storage-overview.xml @@ -0,0 +1,27 @@ + + +%BOOK_ENTITIES; +]> + +
+ Storage Overview + &PRODUCT; defines two types of storage: primary and secondary. Primary storage can be + accessed by either iSCSI or NFS. Additionally, direct attached storage may be used for primary + storage. Secondary storage is always accessed using NFS. + There is no ephemeral storage in &PRODUCT;. All volumes on all nodes are persistent. +
diff --git a/docs/en-US/storage.xml b/docs/en-US/storage.xml index c4df50f6a8f..86d3f53e766 100644 --- a/docs/en-US/storage.xml +++ b/docs/en-US/storage.xml @@ -22,9 +22,11 @@ under the License. --> -
- Deleting VMs - &PRODUCT; defines two types of storage: primary and secondary. Primary storage can be accessed by either iSCSI or NFS. Additionally, direct attached storage may be used for primary storage. Secondary storage is always accessed using NFS. - There is no ephemeral storage in &PRODUCT;. All volumes on all nodes are persistent -
- + + Working With Storage + + + + + + diff --git a/docs/en-US/suspend-project.xml b/docs/en-US/suspend-project.xml index bfaa12a03d9..b4f821b2c26 100644 --- a/docs/en-US/suspend-project.xml +++ b/docs/en-US/suspend-project.xml @@ -32,17 +32,21 @@ In the left navigation, click Projects. In Select View, choose Projects. Click the name of the project. - Click one of the buttons: + Click one of the buttons:To delete, use - deletebutton.png: Removes a member - - + + deletebutton.png: Removes a project + + + To suspend, use - deletebutton.png: Removes a member + + deletebutton.png: suspends a project +
diff --git a/docs/en-US/sys-reliability-and-ha.xml b/docs/en-US/sys-reliability-and-ha.xml index bdb36d0fa46..5c544af0e10 100644 --- a/docs/en-US/sys-reliability-and-ha.xml +++ b/docs/en-US/sys-reliability-and-ha.xml @@ -22,10 +22,11 @@ under the License. --> -
- System Reliability and High Availability - vCenter Maintenance Mode - XenServer and Maintenance Mode - vCenter Maintenance Mode - XenServer and Maintenance Mode -
+ + System Reliability and High Availability + + + + + + \ No newline at end of file diff --git a/docs/en-US/system-reserved-ip-addresses.xml b/docs/en-US/system-reserved-ip-addresses.xml index 2f4922553fa..1270378d38c 100644 --- a/docs/en-US/system-reserved-ip-addresses.xml +++ b/docs/en-US/system-reserved-ip-addresses.xml @@ -32,8 +32,11 @@ Provide private IPs for the system in each pod and provision them in &PRODUCT;. For KVM and XenServer, the recommended number of private IPs per pod is one per host. If you expect a pod to grow, add enough private IPs now to accommodate the growth. In a zone that uses advanced networking: - For vSphere with advanced networking, we recommend provisioning enough private IPs for your total number of customers, plus enough for the required &PRODUCT; System VMs. Typically, about 10 additional IPs are required for the System VMs. For more information about System VMs, see Working with System Virtual Machines in the Administrator's Guide. + For zones with advanced networking, we recommend provisioning enough private IPs for your total number of customers, plus enough for the required &PRODUCT; System VMs. Typically, about 10 additional IPs are required for the System VMs. For more information about System VMs, see Working with System Virtual Machines in the Administrator's Guide. When advanced networking is being used, the number of private IP addresses available in each pod varies depending on which hypervisor is running on the nodes in that pod. Citrix XenServer and KVM use link-local addresses, which in theory provide more than 65,000 private IP addresses within the address block. As the pod grows over time, this should be more than enough for any reasonable number of hosts as well as IP addresses for guest virtual routers. VMWare ESXi, by contrast uses any administrator-specified subnetting scheme, and the typical administrator provides only 255 IPs per pod. Since these are shared by physical machines, the guest virtual router, and other entities, it is possible to run out of private IPs when scaling up a pod whose nodes are running ESXi. - To ensure adequate headroom to scale private IP space in an ESXi pod that uses advanced networking, use one or more of the following techniques: - TODO + To ensure adequate headroom to scale private IP space in an ESXi pod that uses advanced networking, use one or both of the following techniques: + + Specify a larger CIDR block for the subnet. A subnet mask with a /20 suffix will provide more than 4,000 IP addresses. + Create multiple pods, each with its own subnet. For example, if you create 10 pods and each pod has 255 IPs, this will provide 2,550 IP addresses. + diff --git a/docs/en-US/system-service-offerings.xml b/docs/en-US/system-service-offerings.xml index 75aa128d4c8..c41aa2e293b 100644 --- a/docs/en-US/system-service-offerings.xml +++ b/docs/en-US/system-service-offerings.xml @@ -26,4 +26,4 @@ System Service Offerings System service offerings provide a choice of CPU speed, number of CPUs, tags, and RAM size, just as other service offerings do. But rather than being used for virtual machine instances and exposed to users, system service offerings are used to change the default properties of virtual routers, console proxies, and other system VMs. System service offerings are visible only to the &PRODUCT; root administrator. &PRODUCT; provides default system service offerings. The &PRODUCT; root administrator can create additional custom system service offerings. When &PRODUCT; creates a virtual router for a guest network, it uses default settings which are defined in the system service offering associated with the network offering. You can upgrade the capabilities of the virtual router by applying a new network offering that contains a different system service offering. All virtual routers in that network will begin using the settings from the new service offering. - + diff --git a/docs/en-US/tagging-resources.xml b/docs/en-US/tagging-resources.xml new file mode 100644 index 00000000000..31ee3825e4a --- /dev/null +++ b/docs/en-US/tagging-resources.xml @@ -0,0 +1,69 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Using Tags to Organize Resources in the Cloud + A tag is a key-value pair that stores metadata about a resource in the cloud. Tags are + useful for categorizing resources. For example, you can tag a user VM with a + value that indicates the user's city of residence. In this case, the key would + be "city" and the value might be "Toronto" or "Tokyo." You can then request + &PRODUCT; to find all resources that have a given tag; for example, VMs for + users in a given city. + You can tag a user virtual machine, volume, snapshot, guest network, template, + ISO, firewall rule, port forwarding rule, public IP address, security group, + load balancer rule, project, VPC, network ACL, or static route. You can not tag + a remote access VPN. + You can work with tags through the UI or through the API commands createTags, + deleteTags, and listTags. You can define multiple tags for each resource. There + is no limit on the number of tags you can define. Each tag can be up to 255 + characters long. Users can define tags on the resources they own, and + administrators can define tags on any resources in the cloud. + An optional input parameter, "tags," exists on many of the list* API commands. + The following example shows how to use this new parameter to find all the volumes + having tag region=canada OR tag city=Toronto: + command=listVolumes + &listAll=true + &tags[0].key=region + &tags[0].value=canada + &tags[1].key=city + &tags[1].value=Toronto + The following API commands have the "tags" input parameter: + + listVirtualMachines + listVolumes + listSnapshots + listNetworks + listTemplates + listIsos + listFirewallRules + listPortForwardingRules + listPublicIpAddresses + listSecurityGroups + listLoadBalancerRules + listProjects + listVPCs + listNetworkACLs + listStaticRoutes + +
diff --git a/docs/en-US/time-zones.xml b/docs/en-US/time-zones.xml index d6d4bc75df1..aa8eefb7c59 100644 --- a/docs/en-US/time-zones.xml +++ b/docs/en-US/time-zones.xml @@ -22,9 +22,9 @@ under the License. --> -
+ Time Zones - The following time zone identifiers are accepted by the &PRODUCT; API. There are several places that have a time zone as a required or optional parameter. These include scheduling recurring snapshots, creating a user, and specifying the usage time zone in the Configuration table. . + The following time zone identifiers are accepted by &PRODUCT;. There are several places that have a time zone as a required or optional parameter. These include scheduling recurring snapshots, creating a user, and specifying the usage time zone in the Configuration table. @@ -134,4 +134,4 @@ -
+ diff --git a/docs/en-US/troubleshooting.xml b/docs/en-US/troubleshooting.xml index f3dc7d37da3..dd736fe18e0 100644 --- a/docs/en-US/troubleshooting.xml +++ b/docs/en-US/troubleshooting.xml @@ -22,13 +22,14 @@ under the License. --> -
- Alert Type Numbers - Data Loss on Exported Primary Storage - Load balancer rules fail after changing network offering - Maintenance mode not working on vCenter - Recovering a Lost Virtual Router - Unable to deploy VMs from uploaded vSphere template - Unable to power on virtual machine on VMware - Working with Server Logs -
+ + Troubleshooting + + + + + + + + + \ No newline at end of file diff --git a/docs/en-US/tuning.xml b/docs/en-US/tuning.xml index bcaaaa1afbe..18d83ee40bc 100644 --- a/docs/en-US/tuning.xml +++ b/docs/en-US/tuning.xml @@ -22,7 +22,7 @@ under the License. --> -
+ Tuning This section provides tips on how to improve the performance of your cloud. @@ -30,4 +30,4 @@ -
+ \ No newline at end of file diff --git a/docs/en-US/ui.xml b/docs/en-US/ui.xml index 4f7f327d700..94ea4eaf95c 100644 --- a/docs/en-US/ui.xml +++ b/docs/en-US/ui.xml @@ -5,24 +5,25 @@ ]> - User Interface - + User Interface + + diff --git a/docs/en-US/upload-existing-volume-to-vm.xml b/docs/en-US/upload-existing-volume-to-vm.xml index 5966ce68de1..86dc8e54758 100644 --- a/docs/en-US/upload-existing-volume-to-vm.xml +++ b/docs/en-US/upload-existing-volume-to-vm.xml @@ -59,10 +59,10 @@ KVM QCOW2 - + diff --git a/docs/en-US/upload-template.xml b/docs/en-US/upload-template.xml index 51aeb5a63c9..40b64bbe8aa 100644 --- a/docs/en-US/upload-template.xml +++ b/docs/en-US/upload-template.xml @@ -24,7 +24,7 @@
Uploading Templates - If you are uploading a template that was created using vSphere Client, be sure the OVA file does not contain an ISO. If it does, the deployment of VMs from the template will fail. + vSphere Templates and ISOsIf you are uploading a template that was created using vSphere Client, be sure the OVA file does not contain an ISO. If it does, the deployment of VMs from the template will fail. Templates are uploaded based on a URL. HTTP is the supported access protocol. Templates are frequently large files. You can optionally gzip them to decrease upload times. To upload a template: @@ -39,7 +39,7 @@ If the operating system of the stopped VM is listed, choose it. If the OS type of the stopped VM is not listed, choose Other. - Generally you should not choose an older version of the OS than the version in the image. For example, choosing CentOS 5.4 to support a CentOS 6.2 image will in general not work. In those cases you should choose Other. + You should not choose an older version of the OS than the version in the image. For example, choosing CentOS 5.4 to support a CentOS 6.2 image will in general not work. In those cases you should choose Other. Hypervisor diff --git a/docs/en-US/user-services-overview.xml b/docs/en-US/user-services-overview.xml index f9e38c09209..12504e6ca4e 100644 --- a/docs/en-US/user-services-overview.xml +++ b/docs/en-US/user-services-overview.xml @@ -5,94 +5,68 @@ ]> -
+ User Services Overview - In addition to the physical and logical infrastructure of your cloud, and the &PRODUCT; software and servers, you also need a layer of user services so that people can actually make use of the cloud. This means not just a user UI, but a set of options and resources that users can choose from, such as templates for creating virtual machines, disk storage, and more. If you are running a commercial service, you will be keeping track of what services and resources users are consuming and charging them for that usage. Even if you do not charge anything for people to use your cloud – say, if the users are strictly internal to your organization, or just friends who are sharing your cloud – you can still keep track of what services they use and how much of them. -
- Service Offerings, Disk Offerings, Network Offerings, and Templates - A user creating a new instance can make a variety of choices about its characteristics and capabilities. &PRODUCT; provides several ways to present users with choices when creating a new instance: - - Service Offerings, defined by the &PRODUCT; administrator, provide a choice of CPU speed, number of CPUs, RAM size, tags on the root disk, and other choices. See Creating a New Compute Offering. - Disk Offerings, defined by the &PRODUCT; administrator, provide a choice of disk size for primary data storage. See Creating a New Disk Offering. - Network Offerings, defined by the &PRODUCT; administrator, describe the feature set that is available to end users from the virtual router or external networking devices on a given guest network. See Network Offerings. - Templates, defined by the &PRODUCT; administrator or by any &PRODUCT; user, are the base OS images that the user can choose from when creating a new instance. For example, &PRODUCT; includes CentOS as a template. See Working with Templates. - - In addition to these choices that are provided for users, there is another type of service offering which is available only to the &PRODUCT; root administrator, and is used for configuring virtual infrastructure resources. For more information, see Upgrading a Virtual Router with System Service Offerings. -
-
- Accounts, Users, and Domains - An account typically represents a customer of the service provider or a department in a large organization. Multiple users can exist in an account. Users are like aliases in the account. Users in the same account are not isolated from each other, but they are isolated from users in other accounts. Most installations need not surface the notion of users; they just have one user per account. - Accounts are grouped by domains. Domains usually contain accounts that have some logical relationship to each other and a set of delegated administrators with some authority over the domain and its subdomains. For example, a service provider with several resellers could create a domain for each reseller. - Administrators are accounts with special privileges in the system. There may be multiple administrators in the system. Administrators can create or delete other administrators, and change the password for any user in the system. Root administrators have complete access to the system, including managing templates, service offerings, customer care administrators, and domains. Domain administrators can perform administrative operations for users who belong to that domain. Domain administrators do not have visibility into physical servers or other domains. -
-
- Using an LDAP Server for User Authentication - You can use an external LDAP server such as Microsoft Active Directory or ApacheDS to authenticate &PRODUCT; end-users. Just map &PRODUCT; accounts to the corresponding LDAP accounts using a query filter. The query filter is written using the query syntax of the particular LDAP server, and can include special wildcard characters provided by &PRODUCT; for matching common values such as the user’s email address and name. &PRODUCT; will search the external LDAP directory tree starting at a specified base directory and return the distinguished name (DN) and password of the matching user. This information along with the given password is used to authenticate the user. - To set up LDAP authentication in &PRODUCT;, call the &PRODUCT; API command ldapConfig and provide the following: - - Hostname or IP address and listening port of the LDAP server - Base directory and query filter - Search user DN credentials, which give &PRODUCT; permission to search on the LDAP server - SSL keystore and password, if SSL is used - -
- Example LDAP Configuration Commands - To understand the examples in this section, you need to know the basic concepts behind calling the &PRODUCT; API, which are explained in the Developer’s Guide. - The following shows an example invocation of ldapConfig with an ApacheDS LDAP server. - http://127.0.0.1:8080/client/api?command=ldapConfig&hostname=127.0.0.1&searchbase=ou%3Dtesting%2Co%3Dproject&queryfilter=%28%26%28uid%3D%25u%29%29&binddn=cn%3DJohn+Singh%2Cou%3Dtesting%2Co%project&bindpass=secret&port=10389&ssl=true&truststore=C%3A%2Fcompany%2Finfo%2Ftrusted.ks&truststorepass=secret&response=json&apiKey=YourAPIKey&signature=YourSignatureHash - - The command must be URL-encoded. Here is the same example without the URL encoding: - -http://127.0.0.1:8080/client/api?command=ldapConfig -&hostname=127.0.0.1 -&searchbase=ou=testing,o=project -&queryfilter=(&(%uid=%u)) -&binddn=cn=John+Singh,ou=testing,o=project -&bindpass=secret -&port=10389 -&ssl=true -&truststore=C:/company/info/trusted.ks -&truststorepass=secret -&response=json -&apiKey=YourAPIKey -&signature=YourSignatureHash - - The following shows a similar command for Active Directory. Here, the search base is the testing group within a company, and the users are matched up based on email address. - http://10.147.29.101:8080/client/api?command=ldapConfig&hostname=10.147.28.250&searchbase=OU%3Dtesting%2CDC%3Dcompany&queryfilter=%28%26%28mail%3D%25e%29%29&binddn=CN%3DAdministrator%2COU%3Dtesting%2CDC%3Dcompany&bindpass=1111_aaaa&port=389&response=json&apiKey=YourAPIKey&signature=YourSignatureHash - The next few sections explain some of the concepts you will need to know when filling out the ldapConfig parameters. -
-
- Search Base - Coming soon: TODO -
-
- Query Filter - Coming soon: TODO -
-
- Search User Bind DN - Coming soon: TODO -
-
- SSL Keystore Path and Password - Coming soon: TODO -
-
-
+ In addition to the physical and logical infrastructure of your cloud, + and the &PRODUCT; software and servers, you also need a layer of user + services so that people can actually make use of the cloud. This means + not just a user UI, but a set of options and resources that users can + choose from, such as templates for creating virtual machines, disk + storage, and more. If you are running a commercial service, you will be + keeping track of what services and resources users are consuming and + charging them for that usage. Even if you do not charge anything for + people to use your cloud – say, if the users are strictly internal to your + organization, or just friends who are sharing your cloud – you can still + keep track of what services they use and how much of them. + +
+ Service Offerings, Disk Offerings, Network Offerings, and Templates + A user creating a new instance can make a variety of choices about + its characteristics and capabilities. &PRODUCT; provides several ways to + present users with choices when creating a new instance: + + + Service Offerings, defined by the &PRODUCT; administrator, + provide a choice of CPU speed, number of CPUs, RAM size, tags on the + root disk, and other choices. See Creating a New Compute Offering. + + Disk Offerings, defined by the &PRODUCT; administrator, + provide a choice of disk size for primary data storage. See Creating a + New Disk Offering. + + Network Offerings, defined by the &PRODUCT; administrator, + describe the feature set that is available to end users from the virtual + router or external networking devices on a given guest network. See + Network Offerings. + + Templates, defined by the &PRODUCT; administrator or by + any &PRODUCT; user, are the base OS images that the user can choose + from when creating a new instance. For example, &PRODUCT; includes + CentOS as a template. See Working with Templates. + + + In addition to these choices that are provided for users, there is + another type of service offering which is available only to the &PRODUCT; + root administrator, and is used for configuring virtual infrastructure + resources. For more information, see Upgrading a Virtual Router with + System Service Offerings. + +
+ diff --git a/docs/en-US/using-multiple-guest-networks.xml b/docs/en-US/using-multiple-guest-networks.xml index ce71caaf276..9076a816640 100644 --- a/docs/en-US/using-multiple-guest-networks.xml +++ b/docs/en-US/using-multiple-guest-networks.xml @@ -28,4 +28,6 @@ A VM's networks are defined at VM creation time. A VM cannot add or remove networks after it has been created, although the user can go into the guest and remove the IP address from the NIC on a particular network. Each VM has just one default network. The virtual router's DHCP reply will set the guest's default gateway as that for the default network. Multiple non-default networks may be added to a guest in addition to the single, required default network. The administrator can control which networks are available as the default network. Additional networks can either be available to all accounts or be assigned to a specific account. Networks that are available to all accounts are zone-wide. Any user with access to the zone can create a VM with access to that network. These zone-wide networks provide little or no isolation between guests.Networks that are assigned to a specific account provide strong isolation. + +
diff --git a/docs/en-US/using-sshkeys.xml b/docs/en-US/using-sshkeys.xml index b51569d1134..1e98eb699ad 100644 --- a/docs/en-US/using-sshkeys.xml +++ b/docs/en-US/using-sshkeys.xml @@ -23,27 +23,35 @@ -->
- Using the SSH Keys for Authentication on Cloud - In addition to the username and password authentication, CloudStack supports using SSH keys to log in to the cloud infrastructure for additional security for your cloud infrastructure. You can use the createSSHKeyPair API to generate the SSH keys. - Because each cloud user has their own ssh key, one cloud user cannot log in to another cloud user's instances unless they share their ssh key files. Using a single SSH key pair, you can manage multiple instances. - Creating an Instance Template that Supports SSH Keys + Using SSH Keys for Authentication + In addition to the username and password authentication, &PRODUCT; supports using SSH keys to log in to the cloud infrastructure for additional security. You can use the createSSHKeyPair API to generate the SSH keys. + Because each cloud user has their own SSH key, one cloud user cannot log in to another cloud user's instances unless they share their SSH key files. Using a single SSH key pair, you can manage multiple instances. +
+ Creating an Instance Template that Supports SSH Keys + Create a instance template that supports SSH Keys. - Create a instance template that supports SSH Keys. - Create a new instance by using the template provided by cloudstack. - For more information on creating a new instance, see + Create a new instance by using the template provided by cloudstack. + For more information on creating a new instance, see + Download the cloudstack script from The SSH Key Gen Scriptto the instance you have created. - wget http://downloads.sourceforge.net/project/cloudstack/SSH%20Key%20Gen%20Script/cloud-set-guest-sshkey.in?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fcloudstack%2Ffiles%2FSSH%2520Key%2520Gen%2520Script%2F&ts=1331225219&use_mirror=iweb + wget http://downloads.sourceforge.net/project/cloudstack/SSH%20Key%20Gen%20Script/cloud-set-guest-sshkey.in?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fcloudstack%2Ffiles%2FSSH%2520Key%2520Gen%2520Script%2F&ts=1331225219&use_mirror=iweb + Copy the file to /etc/init.d. - cp cloud-set-guest-sshkey.in /etc/init.d/ + cp cloud-set-guest-sshkey.in /etc/init.d/ + Give the necessary permissions on the script: - chmod +x /etc/init.d/cloud-set-guest-sshkey.in + chmod +x /etc/init.d/cloud-set-guest-sshkey.in + Run the script while starting up the operating system: - chkconfig --add cloud-set-guest-sshkey.in - Stop the instance. - - - Creating the SSH Keypair - You must make a call to the createSSHKeyPair api method. You can either use the cloudstack python api library or the curl commands to make the call to the cloudstack api. + chkconfig --add cloud-set-guest-sshkey.in + + Stop the instance. + + +
+
+ Creating the SSH Keypair + You must make a call to the createSSHKeyPair api method. You can either use the &PRODUCT; Python API library or the curl commands to make the call to the cloudstack api. For example, make a call from the cloudstack server to create a SSH keypair called "keypair-doc" for the admin account in the root domain: Ensure that you adjust these values to meet your needs. If you are making the API call from a different server, your URL/PORT will be different, and you will need to use the API keys. @@ -78,15 +86,20 @@ KfEEuzcCUIxtJYTahJ1pvlFkQ8anpuxjSEDp8x/18bq3 -----END RSA PRIVATE KEY----- Save the file. - Creating an Instance - After you save the SSH keypair file, you must create an instance by using the template that you created at . Ensure that you use the same SSH key name that you created at . +
+
+ Creating an Instance + After you save the SSH keypair file, you must create an instance by using the template that you created at . Ensure that you use the same SSH key name that you created at . You cannot create the instance by using the GUI at this time and associate the instance with the newly created SSH keypair. A sample curl command to create a new instance is: curl --globoff http://localhost:<port numbet>/?command=deployVirtualMachine\&zoneId=1\&serviceOfferingId=18727021-7556-4110-9322-d625b52e0813\&templateId=e899c18a-ce13-4bbf-98a9-625c5026e0b5\&securitygroupids=ff03f02f-9e3b-48f8-834d-91b822da40c5\&account=admin\&domainid=1\&keypair=keypair-doc Substitute the template, service offering and security group IDs (if you are using the security group feature) that are in your cloud environment. - Logging In Using the SSH Keypair +
+
+ Logging In Using the SSH Keypair To test your SSH key generation is successful, check whether you can log in to the cloud setup. For exaple, from a Linux OS, run: ssh -i ~/.ssh/keypair-doc <ip address> The -i parameter tells the ssh client to use a ssh key found at ~/.ssh/keypair-doc. +
diff --git a/docs/en-US/verifying-source.xml b/docs/en-US/verifying-source.xml new file mode 100644 index 00000000000..05b54ecb6a9 --- /dev/null +++ b/docs/en-US/verifying-source.xml @@ -0,0 +1,82 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ Verifying the downloaded release + + There are a number of mechanisms to check the authenticity and validity of a + downloaded release. + +
+ Getting the KEYS + + To enable you to verify the GPG signature, you will need to download the + KEYS + file. + + + You next need to import those keys, which you can do by running the following command: + # gpg --import KEYS + +
+
+ GPG + + The &PRODUCT; project provides a detached GPG signature of the release. + To check the signature, run the following command: + $ gpg --verify apache-cloudstack-4.0.0-incubating-src.tar.bz2.asc + + + If the signature is valid you will see a line of output that contains 'Good signature'. + +
+
+ MD5 + + In addition to the cryptographic signature, the &PRODUCT; provides a number + of cryptographic hashes to aid in assurance of validity of the downloaded + release. You can verify this hash by executing the following command: + $ gpg --print-md MD5 apache-cloudstack-4.0.0-incubating-src.tar.bz2 | diff - apache-cloudstack-4.0.0-incubating-src.tar.bz2.md5 + + + If this successfully completes you should see no output. If there is any output from them, + then there is a difference between the hash you generated locally and the hash that has been + pulled from the server. + +
+
+ SHA512 + + In addition to the MD5 hash, the &PRODUCT; project provides a SHA512 + cryptographic hash to aid in assurance of the validity of the downloaded + release. You can verify this hash by executing the following command: + $ gpg --print-md SHA512 apache-cloudstack-4.0.0-incubating-src.tar.bz2 | diff - apache-cloudstack-4.0.0-incubating-src.tar.bz2.sha + + + If this command successfully completes you should see no output. If there is any output from them, + then there is a difference between the hash you generated locally and the hash that has been + pulled from the server. + +
+
diff --git a/docs/en-US/virtual-machines.xml b/docs/en-US/virtual-machines.xml new file mode 100644 index 00000000000..7c74932b649 --- /dev/null +++ b/docs/en-US/virtual-machines.xml @@ -0,0 +1,34 @@ + + +%BOOK_ENTITIES; +]> + + + Working With Virtual Machines + + + + + + + + + + + + diff --git a/docs/en-US/vmware-install.xml b/docs/en-US/vmware-install.xml new file mode 100644 index 00000000000..736b122fd0f --- /dev/null +++ b/docs/en-US/vmware-install.xml @@ -0,0 +1,631 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ VMware vSphere Installation and Configuration + If you want to use the VMware vSphere hypervisor to run guest virtual machines, install vSphere on the host(s) in your cloud. + +
+ Preparation Checklist for VMware + For a smoother installation, gather the following information before you start: + + Information listed in + Information listed in + +
+ vCenter Checklist + You will need the following information about vCenter. + + + + + + + + vCenter Requirement + Value + Notes + + + + + vCenter User + + This user must have admin privileges. + + + vCenter User Password + + Password for the above user. + + + vCenter Datacenter Name + + Name of the datacenter. + + + vCenter Cluster Name + + Name of the cluster. + + + + +
+
+ Networking Checklist for VMware + You will need the following information about VLAN. + + + + + + + + VLAN Information + Value + Notes + + + + + ESXi VLAN + + VLAN on which all your ESXi hypervisors reside. + + + ESXI VLAN IP Address + + IP Address Range in the ESXi VLAN. One address per Virtual Router is used from this range. + + + ESXi VLAN IP Gateway + + + + + ESXi VLAN Netmask + + + + + Management Server VLAN + + VLAN on which the &PRODUCT; Management server is installed. + + + Public VLAN + + VLAN for the Public Network. + + + Public VLAN Gateway + + + + + Public VLAN Netmask + + + + + Public VLAN IP Address Range + + Range of Public IP Addresses available for &PRODUCT; use. These addresses will be used for virtual router on &PRODUCT; to route private traffic to external networks. + + + VLAN Range for Customer use + + A contiguous range of non-routable VLANs. One VLAN will be assigned for each customer. + + + + +
+
+
+ vSphere Installation Steps + + If you haven't already, you'll need to download and purchase vSphere from the VMware Website (https://www.vmware.com/tryvmware/index.php?p=vmware-vsphere&lp=1) and install it by following the VMware vSphere Installation Guide. + + Following installation, perform the following configuration, which are described in the next few sections: + + + + + + + Required + Optional + + + + + ESXi host setup + NIC bonding + + + Configure host physical networking, virtual switch, vCenter Management Network, and extended port range + Multipath storage + + + Prepare storage for iSCSI + + + + Configure clusters in vCenter and add hosts to them, or add hosts without clusters to vCenter + + + + + + + +
+
+ ESXi Host setup + All ESXi hosts should enable CPU hardware virtualization support in BIOS. Please note hardware virtualization support is not enabled by default on most servers. +
+
+ Physical Host Networking + You should have a plan for cabling the vSphere hosts. Proper network configuration is required before adding a vSphere host to &PRODUCT;. To configure an ESXi host, you can use vClient to add it as standalone host to vCenter first. Once you see the host appearing in the vCenter inventory tree, click the host node in the inventory tree, and navigate to the Configuration tab. + + + + + + vsphereclient.png: vSphere client + + + In the host configuration tab, click the "Hardware/Networking" link to bring up the networking configuration page as above. +
+ Configure Virtual Switch + A default virtual switch vSwitch0 is created. &PRODUCT; requires all ESXi hosts in the cloud to use the same set of virtual switch names. If you change the default virtual switch name, you will need to configure one or more &PRODUCT; configuration variables as well. +
+ Separating Traffic + &PRODUCT; allows you to use vCenter to configure three separate networks per ESXi host. These networks are identified by the name of the vSwitch they are connected to. The allowed networks for configuration are public (for traffic to/from the public internet), guest (for guest-guest traffic), and private (for management and usually storage traffic). You can use the default virtual switch for all three, or create one or two other vSwitches for those traffic types. + If you want to separate traffic in this way you should first create and configure vSwitches in vCenter according to the vCenter instructions. Take note of the vSwitch names you have used for each traffic type. You will configure &PRODUCT; to use these vSwitches. +
+
+ Increasing Ports + By default a virtual switch on ESXi hosts is created with 56 ports. We recommend setting it to 4088, the maximum number of ports allowed. To do that, click the "Properties..." link for virtual switch (note this is not the Properties link for Networking). + + + + + + vsphereclient.png: vSphere client + + + In vSwitch properties dialog, select the vSwitch and click Edit. You should see the following dialog: + + + + + + vsphereclient.png: vSphere client + + + In this dialog, you can change the number of switch ports. After you've done that, ESXi hosts are required to reboot in order for the setting to take effect. +
+
+
+ Configure vCenter Management Network + In the vSwitch properties dialog box, you may see a vCenter management network. This same network will also be used as the &PRODUCT; management network. &PRODUCT; requires the vCenter management network to be configured properly. Select the management network item in the dialog, then click Edit. + + + + + + vsphereclient.png: vSphere client + + + Make sure the following values are set: + + VLAN ID set to the desired ID + vMotion enabled. + Management traffic enabled. + + If the ESXi hosts have multiple VMKernel ports, and ESXi is not using the default value "Management Network" as the management network name, you must follow these guidelines to configure the management network port group so that &PRODUCT; can find it: + + Use one label for the management network port across all ESXi hosts. + In the &PRODUCT; UI, go to Configuration - Global Settings and set vmware.management.portgroup to the management network label from the ESXi hosts. + +
+
+ Extend Port Range for &PRODUCT; Console Proxy + (Applies only to VMware vSphere version 4.x) + You need to extend the range of firewall ports that the console proxy works with on the hosts. This is to enable the console proxy to work with VMware-based VMs. The default additional port range is 59000-60000. To extend the port range, log in to the VMware ESX service console on each host and run the following commands: + +esxcfg-firewall -o 59000-60000,tcp,in,vncextras +esxcfg-firewall -o 59000-60000,tcp,out,vncextras + +
+
+ Configure NIC Bonding for vSphere + NIC bonding on vSphere hosts may be done according to the vSphere installation guide. +
+
+ +
+ Storage Preparation for vSphere (iSCSI only) + Use of iSCSI requires preparatory work in vCenter. You must add an iSCSI target and create an iSCSI datastore. + If you are using NFS, skip this section. +
+ Enable iSCSI initiator for ESXi hosts + + + In vCenter, go to hosts and Clusters/Configuration, and click Storage Adapters link. You will see: + + + + + + vsphereclient.png: vSphere client + + + + + Select iSCSI software adapter and click Properties. + + + + + + vsphereclient.png: vSphere client + + + + + Click the Configure... button. + + + + + + vsphereclient.png: vSphere client + + + + Check Enabled to enable the initiator. + Click OK to save. + +
+
+ Add iSCSI target + Under the properties dialog, add the iSCSI target info: + + + + + + vsphereclient.png: vSphere client + + + Repeat these steps for all ESXi hosts in the cluster. +
+
+ Create an iSCSI datastore + You should now create a VMFS datastore. Follow these steps to do so: + + Select Home/Inventory/Datastores. + Right click on the datacenter node. + Choose Add Datastore... command. + Follow the wizard to create a iSCSI datastore. + + This procedure should be done on one host in the cluster. It is not necessary to do this on all hosts. + + + + + + vsphereclient.png: vSphere client + + +
+
+ Multipathing for vSphere (Optional) + Storage multipathing on vSphere nodes may be done according to the vSphere installation guide. +
+
+
+ Add Hosts or Configure Clusters (vSphere) + Use vCenter to create a vCenter cluster and add your desired hosts to the cluster. You will later add the entire cluster to &PRODUCT;. (see ). +
+
diff --git a/docs/en-US/vmware-requirements.xml b/docs/en-US/vmware-requirements.xml new file mode 100644 index 00000000000..207a4566de8 --- /dev/null +++ b/docs/en-US/vmware-requirements.xml @@ -0,0 +1,80 @@ + + +%BOOK_ENTITIES; +]> + + + +
+ System Requirements for vSphere Hosts +
+ Software requirements: + + + vSphere and vCenter, both version 4.1 or 5.0. + vSphere Standard is recommended. Note however that customers need to consider the CPU constraints in place with vSphere licensing. See http://www.vmware.com/files/pdf/vsphere_pricing.pdf and discuss with your VMware sales representative. + vCenter Server Standard is recommended. + + Be sure all the hotfixes provided by the hypervisor vendor are applied. Track the release of hypervisor patches through your hypervisor vendor's support channel, and apply patches as soon as possible after they are released. &PRODUCT; will not track or notify you of required hypervisor patches. It is essential that your hosts are completely up to date with the provided hypervisor patches. The hypervisor vendor is likely to refuse to support any system that is not up to date with patches. + + Apply All Necessary HotfixesThe lack of up-do-date hotfixes can lead to data corruption and lost VMs. +
+
+ Hardware requirements: + + The host must be certified as compatible with vSphere. See the VMware Hardware Compatibility Guide at http://www.vmware.com/resources/compatibility/search.php. + All hosts must be 64-bit and must support HVM (Intel-VT or AMD-V enabled). + All hosts within a cluster must be homogenous. That means the CPUs must be of the same type, count, and feature flags. + 64-bit x86 CPU (more cores results in better performance) + Hardware virtualization support required + 4 GB of memory + 36 GB of local disk + At least 1 NIC + Statically allocated IP Address + +
+
+ vCenter Server requirements: + + Processor - 2 CPUs 2.0GHz or higher Intel or AMD x86 processors. Processor requirements may be higher if the database runs on the same machine. + Memory - 3GB RAM. RAM requirements may be higher if your database runs on the same machine. + Disk storage - 2GB. Disk requirements may be higher if your database runs on the same machine. + Microsoft SQL Server 2005 Express disk requirements. The bundled database requires up to 2GB free disk space to decompress the installation archive. + Networking - 1Gbit or 10Gbit. + + For more information, see "vCenter Server and the vSphere Client Hardware Requirements" at http://pubs.vmware.com/vsp40/wwhelp/wwhimpl/js/html/wwhelp.htm#href=install/c_vc_hw.html. +
+
+ Other requirements: + + VMware vCenter Standard Edition 4.1 or 5.0 must be installed and available to manage the vSphere hosts. + vCenter must be configured to use the standard port 443 so that it can communicate with the &PRODUCT; Management Server. + You must re-install VMware ESXi if you are going to re-use a host from a previous install. + &PRODUCT; requires VMware vSphere 4.1 or 5.0. VMware vSphere 4.0 is not supported. + All hosts must be 64-bit and must support HVM (Intel-VT or AMD-V enabled). All hosts within a cluster must be homogenous. That means the CPUs must be of the same type, count, and feature flags. + The &PRODUCT; management network must not be configured as a separate virtual network. The &PRODUCT; management network is the same as the vCenter management network, and will inherit its configuration. See . + &PRODUCT; requires ESXi. ESX is not supported. + All resources used for &PRODUCT; must be used for &PRODUCT; only. &PRODUCT; cannot share instance of ESXi or storage with other management consoles. Do not share the same storage volumes that will be used by &PRODUCT; with a different set of ESXi servers that are not managed by &PRODUCT;. + Put all target ESXi hypervisors in a cluster in a separate Datacenter in vCenter. + The cluster that will be managed by &PRODUCT; should not contain any VMs. Do not run the management server, vCenter or any other VMs on the cluster that is designated for &PRODUCT; use. Create a separate cluster for use of &PRODUCT; and make sure that they are no VMs in this cluster. + All the required VLANS must be trunked into all network switches that are connected to the ESXi hypervisor hosts. These would include the VLANS for Management, Storage, vMotion, and guest VLANs. The guest VLAN (used in Advanced Networking; see Network Setup) is a contiguous range of VLANs that will be managed by &PRODUCT;. + +
+
diff --git a/docs/en-US/volume-status.xml b/docs/en-US/volume-status.xml index c2e58a544c6..35802f98253 100644 --- a/docs/en-US/volume-status.xml +++ b/docs/en-US/volume-status.xml @@ -23,7 +23,14 @@ -->
- Volume Status - When a snapshot operation is triggered by means of a recurring snapshot policy, a snapshot is skipped if a volume has remained inactive since its last snapshot was taken. A volume is considered to be inactive if it is either detached or attached to a VM that is not running. &PRODUCT; ensures that at least one snapshot is taken since the volume last became inactive. - When a snapshot is taken manually, a snapshot is always created regardless of whether a volume has been active or not. + Volume Status + When a snapshot operation is triggered by means of a recurring snapshot + policy, a snapshot is skipped if a volume has remained inactive since its + last snapshot was taken. A volume is considered to be inactive if it is + either detached or attached to a VM that is not running. &PRODUCT; ensures + that at least one snapshot is taken since the volume last became inactive. + + When a snapshot is taken manually, a snapshot is always created + regardless of whether a volume has been active or not. +
diff --git a/docs/en-US/vpn.xml b/docs/en-US/vpn.xml index a4599873856..724e4800f94 100644 --- a/docs/en-US/vpn.xml +++ b/docs/en-US/vpn.xml @@ -30,4 +30,8 @@ Road Warrior / Remote Access. Users want to be able to connect securely from a home or office to a private network in the cloud. Typically, the IP address of the connecting client is dynamic and cannot be preconfigured on the VPN server. Site to Site. In this scenario, two private subnets are connected over the public Internet with a secure VPN tunnel. The cloud user’s subnet (for example, an office network) is connected through a gateway to the network in the cloud. The address of the user’s gateway must be preconfigured on the VPN server in the cloud. Note that although L2TP-over-IPsec can be used to set up Site-to-Site VPNs, this is not the primary intent of this feature. + + + + diff --git a/docs/en-US/whats-new.xml b/docs/en-US/whats-new.xml index 44ec5183d6a..5f13db3a854 100644 --- a/docs/en-US/whats-new.xml +++ b/docs/en-US/whats-new.xml @@ -22,13 +22,21 @@ under the License. --> -
- What's New in 3.0.x? - The following describes any new major features of each CloudPlatform version as it applies to API usage. - - - - - - -
+ + What's New in the API? + The following describes any new major features of each &PRODUCT; version as it applies to API usage. +
+ What's New in the API for 4.0 + + +
+
+ What's New in the API for 3.0 + + + + + + +
+
diff --git a/docs/en-US/windows-installation.xml b/docs/en-US/windows-installation.xml index b6e0632b785..541f8ddd4e5 100644 --- a/docs/en-US/windows-installation.xml +++ b/docs/en-US/windows-installation.xml @@ -23,6 +23,9 @@ -->
- Windows OS Installation - Download the installer, CloudInstanceManager.msi, from Download page and run the installer in the newly created Windows VM. + Windows OS Installation + Download the installer, CloudInstanceManager.msi, from + Download page + and run the installer in the newly created Windows VM. +
diff --git a/docs/en-US/work-with-usage.xml b/docs/en-US/work-with-usage.xml index e9fb1d8d7ef..939ba6378a4 100644 --- a/docs/en-US/work-with-usage.xml +++ b/docs/en-US/work-with-usage.xml @@ -22,7 +22,15 @@ under the License. --> -
- Changing the Database Configuration - The &PRODUCT; Management Server stores database configuration information (e.g., hostname, port, credentials) in the file /etc/cloud/management/db.properties. To effect a change, edit this file on each Management Server, then restart the Management Server. -
+ + Working with Usage + The Usage Server is an optional, separately-installed part of &PRODUCT; that provides aggregated usage records which you can use to create billing integration for &PRODUCT;. The Usage Server works by taking data from the events log and creating summary usage records that you can access using the listUsageRecords API call. + The usage records show the amount of resources, such as VM run time or template storage + space, consumed by guest instances. + The Usage Server runs at least once per day. It can be configured to run multiple times per day. + + + + + + \ No newline at end of file diff --git a/docs/en-US/working-with-hosts.xml b/docs/en-US/working-with-hosts.xml index fb4364b3cae..4dcb8521ae2 100644 --- a/docs/en-US/working-with-hosts.xml +++ b/docs/en-US/working-with-hosts.xml @@ -22,7 +22,18 @@ under the License. --> -
- Removing Hosts - Hosts can be removed from the cloud as needed. The procedure to remove a host depends on the hypervisor type. -
+ + Working With Hosts +
+ Adding Hosts + Additional hosts can be added at any time to provide more capacity for guest VMs. For requirements and instructions, see . +
+ + + + + + + + +
\ No newline at end of file diff --git a/docs/en-US/working-with-snapshots.xml b/docs/en-US/working-with-snapshots.xml index 6145ffd8de1..d6b145875d4 100644 --- a/docs/en-US/working-with-snapshots.xml +++ b/docs/en-US/working-with-snapshots.xml @@ -25,8 +25,8 @@
Working with Snapshots (Supported for the following hypervisors: XenServer, VMware vSphere, and KVM) - &PRODUCT; supports snapshots of disk volumes. Snapshots are a point-in-time capture of virtual machine disks. Memory and CPU states are not captured. If you are using the Oracle VM hypervisor, you can not take snapshots, since OVM does not support them. - Snapshots may be taken for volumes, including both root and data disks (except when the Oracle VM hypervisor is used, which does not support snapshots). The administrator places a limit on the number of stored snapshots per user. Users can create new volumes from the snapshot for recovery of particular files and they can create templates from snapshots to boot from a restored disk. + &PRODUCT; supports snapshots of disk volumes. Snapshots are a point-in-time capture of virtual machine disks. Memory and CPU states are not captured. + Snapshots may be taken for volumes, including both root and data disks. The administrator places a limit on the number of stored snapshots per user. Users can create new volumes from the snapshot for recovery of particular files and they can create templates from snapshots to boot from a restored disk. Users can create snapshots manually or by setting up automatic recurring snapshot policies. Users can also create disk volumes from snapshots, which may be attached to a VM like any other disk volume. Snapshots of both root disks and data disks are supported. However, &PRODUCT; does not currently support booting a VM from a recovered root disk. A disk recovered from snapshot of a root disk is treated as a regular data disk; the data on recovered disk can be accessed by attaching the disk to a VM. A completed snapshot is copied from primary storage to secondary storage, where it is stored until deleted or purged by newer snapshot.
diff --git a/docs/en-US/working-with-system-vm.xml b/docs/en-US/working-with-system-vm.xml index 016d57977cc..ed2bdcded41 100644 --- a/docs/en-US/working-with-system-vm.xml +++ b/docs/en-US/working-with-system-vm.xml @@ -22,7 +22,12 @@ under the License. --> -
- Working with System Virtual Machines - &PRODUCT; uses several types of system virtual machines to perform tasks in the cloud. In general &PRODUCT; manages these system VMs and creates, starts, and stops them as needed based on scale and immediate needs. However, the administrator should be aware of them and their roles to assist in debugging issues. -
+ + Working with System Virtual Machines + &PRODUCT; uses several types of system virtual machines to perform tasks in the cloud. In general &PRODUCT; manages these system VMs and creates, starts, and stops them as needed based on scale and immediate needs. However, the administrator should be aware of them and their roles to assist in debugging issues. + + + + + + \ No newline at end of file diff --git a/docs/en-US/working-with-templates.xml b/docs/en-US/working-with-templates.xml index 57a0a58ee7f..a01c1814a21 100644 --- a/docs/en-US/working-with-templates.xml +++ b/docs/en-US/working-with-templates.xml @@ -22,7 +22,7 @@ under the License. --> -
+ Working with Templates A template is a reusable configuration for virtual machines. When users launch VMs, they can choose from a list of templates in &PRODUCT;. Specifically, a template is a virtual disk image that includes one of a variety of operating systems, optional additional software such as office applications, and settings such as access control to determine who can use the template. Each template is associated with a particular type of hypervisor, which is specified when the template is added to &PRODUCT;. @@ -38,7 +38,7 @@ - + -
+ diff --git a/docs/en-US/working-with-usage-data.xml b/docs/en-US/working-with-usage-data.xml index 95d83640e34..56a929fd6c1 100644 --- a/docs/en-US/working-with-usage-data.xml +++ b/docs/en-US/working-with-usage-data.xml @@ -22,7 +22,7 @@ under the License. --> -
+ Working With Usage Data The Usage Server provides aggregated usage records which you can use to create billing integration for the &PRODUCT; platform. The Usage Server works by taking data from the events log and creating summary usage records that you can access using the listUsageRecords API call. The usage records show the amount of resources, such as VM run time or template storage space, consumed by guest instances. In the special case of bare metal instances, no template storage resources are consumed, but records showing zero usage are still included in the Usage Server's output. @@ -31,4 +31,4 @@ -
+ diff --git a/docs/en-US/working-with-volumes.xml b/docs/en-US/working-with-volumes.xml index f4fce71c854..117912015d2 100644 --- a/docs/en-US/working-with-volumes.xml +++ b/docs/en-US/working-with-volumes.xml @@ -24,7 +24,25 @@
Using Swift for Secondary Storage - A volume provides storage to a guest VM. The volume can provide for a root disk or an additional data disk. &PRODUCT; supports additional volumes for guest VMs. - Volumes are created for a specific hypervisor type. A volume that has been attached to guest using one hypervisor type (e.g, XenServer) may not be attached to a guest that is using another hypervisor type (e.g. vSphere, Oracle VM, KVM). This is because the different hypervisors use different disk image formats. - &PRODUCT; defines a volume as a unit of storage available to a guest VM. Volumes are either root disks or data disks. The root disk has "/" in the file system and is usually the boot device. Data disks provide for additional storage (e.g. As "/opt" or "D:"). Every guest VM has a root disk, and VMs can also optionally have a data disk. End users can mount multiple data disks to guest VMs. Users choose data disks from the disk offerings created by administrators. The user can create a template from a volume as well; this is the standard procedure for private template creation. Volumes are hypervisor-specific: a volume from one hypervisor type may not be used on a guest of another hypervisor type. + A volume provides storage to a guest VM. The volume can provide for + a root disk or an additional data disk. &PRODUCT; supports additional + volumes for guest VMs. + + Volumes are created for a specific hypervisor type. A volume that has + been attached to guest using one hypervisor type (e.g, XenServer) may not + be attached to a guest that is using another hypervisor type (e.g. + vSphere, KVM). This is because the different hypervisors use + different disk image formats. + + &PRODUCT; defines a volume as a unit of storage available to a guest + VM. Volumes are either root disks or data disks. The root disk has "/" + in the file system and is usually the boot device. Data disks provide + for additional storage (e.g. As "/opt" or "D:"). Every guest VM has a root + disk, and VMs can also optionally have a data disk. End users can mount + multiple data disks to guest VMs. Users choose data disks from the disk + offerings created by administrators. The user can create a template from + a volume as well; this is the standard procedure for private template + creation. Volumes are hypervisor-specific: a volume from one hypervisor + type may not be used on a guest of another hypervisor type. +
diff --git a/docs/publican-install.cfg b/docs/publican-adminguide.cfg similarity index 90% rename from docs/publican-install.cfg rename to docs/publican-adminguide.cfg index 708200d460f..7a8a203a0f6 100644 --- a/docs/publican-install.cfg +++ b/docs/publican-adminguide.cfg @@ -1,4 +1,4 @@ -# Publican configuration file for CloudStack Installation Guide +# Publican configuration file for CloudStack Developer's Guide # Config::Simple 4.58 # Tue May 29 00:57:27 2012 # @@ -20,10 +20,11 @@ xml_lang: en-US type: Book -docname: cloudstack_installation +docname: Admin_Guide brand: cloudstack chunk_first: 1 chunk_section_depth: 1 +condition: admin diff --git a/docs/publican-all.cfg b/docs/publican-all.cfg index 89e1d304320..897f92b4caa 100644 --- a/docs/publican-all.cfg +++ b/docs/publican-all.cfg @@ -24,4 +24,5 @@ type: Book docname: cloudstack brand: cloudstack chunk_first: 1 -chunk_section_depth: 2 +chunk_section_depth: 1 +condition: install diff --git a/docs/publican-cloudstack/en-US/images/dot.png b/docs/publican-cloudstack/en-US/images/dot.png index 79908d10d4f..079add95ded 100644 Binary files a/docs/publican-cloudstack/en-US/images/dot.png and b/docs/publican-cloudstack/en-US/images/dot.png differ diff --git a/docs/publican-devguide.cfg b/docs/publican-devguide.cfg index 3b364d944b0..006c0d16d00 100644 --- a/docs/publican-devguide.cfg +++ b/docs/publican-devguide.cfg @@ -20,7 +20,7 @@ xml_lang: en-US type: Book -docname: cloudstack_developers +docname: API_Developers_Guide brand: cloudstack chunk_first: 1 chunk_section_depth: 1 diff --git a/docs/publican-installation.cfg b/docs/publican-installation.cfg index 708200d460f..e94044d4b60 100644 --- a/docs/publican-installation.cfg +++ b/docs/publican-installation.cfg @@ -20,10 +20,11 @@ xml_lang: en-US type: Book -docname: cloudstack_installation +docname: Installation_Guide brand: cloudstack chunk_first: 1 chunk_section_depth: 1 +condition: install diff --git a/docs/publican-trial-install.cfg b/docs/publican-plugin-niciranvp.cfg similarity index 78% rename from docs/publican-trial-install.cfg rename to docs/publican-plugin-niciranvp.cfg index 3e657b8fb8a..2e3696dc49e 100644 --- a/docs/publican-trial-install.cfg +++ b/docs/publican-plugin-niciranvp.cfg @@ -1,10 +1,11 @@ -# Publican configuration file for CloudStack Trial Installation Guide +# Publican configuration file for CloudStack Complete Documentation Set +# Contains all technical docs except release notes # Config::Simple 4.58 # Tue May 29 00:57:27 2012 # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information# +# distributed with this work for additional information# # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance @@ -20,10 +21,8 @@ xml_lang: en-US type: Book -docname: cloudstack_trial_installation +docname: CloudStack_Nicira_NVP_Guide brand: cloudstack chunk_first: 1 chunk_section_depth: 1 - - - +condition: install diff --git a/docs/publican-release-notes-4_0.cfg b/docs/publican-release-notes.cfg similarity index 97% rename from docs/publican-release-notes-4_0.cfg rename to docs/publican-release-notes.cfg index 07c9002516e..b6af40663bc 100644 --- a/docs/publican-release-notes-4_0.cfg +++ b/docs/publican-release-notes.cfg @@ -20,7 +20,7 @@ xml_lang: en-US type: Book -docname: release-notes-4.0 +docname: Release_Notes brand: cloudstack chunk_first: 0 chunk_section_depth: 0 diff --git a/patches/pom.xml b/patches/pom.xml index d62fc860185..ca34607f9cc 100644 --- a/patches/pom.xml +++ b/patches/pom.xml @@ -1,30 +1,22 @@ - + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cloud-patches Apache CloudStack SystemVM Patches org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT @@ -68,25 +60,77 @@ install - maven-assembly-plugin - 2.3 - - cloud-scripts - false - - cloudpatch-descriptor.xml - - + maven-antrun-plugin + 1.7 - make-cloud-scripts - package + build-cloud-scripts + install - single + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + vmware + + + nonoss + + + + + org.apache.cloudstack + cloud-plugin-hypervisor-vmware + ${project.version} + + + org.apache.cloudstack + cloud-vmware-base + ${project.version} + + + + diff --git a/patches/systemvm/debian/config/bin/vhd-util b/patches/systemvm/debian/config/bin/vhd-util deleted file mode 100755 index 12a13927821..00000000000 Binary files a/patches/systemvm/debian/config/bin/vhd-util and /dev/null differ diff --git a/patches/systemvm/debian/config/etc/httpd/conf/httpd.conf b/patches/systemvm/debian/config/etc/httpd/conf/httpd.conf deleted file mode 100644 index e11384ef772..00000000000 --- a/patches/systemvm/debian/config/etc/httpd/conf/httpd.conf +++ /dev/null @@ -1,990 +0,0 @@ -# -# This is the main Apache server configuration file. It contains the -# configuration directives that give the server its instructions. -# See for detailed information. -# In particular, see -# -# for a discussion of each configuration directive. -# -# -# Do NOT simply read the instructions in here without understanding -# what they do. They're here only as hints or reminders. If you are unsure -# consult the online docs. You have been warned. -# -# The configuration directives are grouped into three basic sections: -# 1. Directives that control the operation of the Apache server process as a -# whole (the 'global environment'). -# 2. Directives that define the parameters of the 'main' or 'default' server, -# which responds to requests that aren't handled by a virtual host. -# These directives also provide default values for the settings -# of all virtual hosts. -# 3. Settings for virtual hosts, which allow Web requests to be sent to -# different IP addresses or hostnames and have them handled by the -# same Apache server process. -# -# Configuration and logfile names: If the filenames you specify for many -# of the server's control files begin with "/" (or "drive:/" for Win32), the -# server will use that explicit path. If the filenames do *not* begin -# with "/", the value of ServerRoot is prepended -- so "logs/foo.log" -# with ServerRoot set to "/etc/httpd" will be interpreted by the -# server as "/etc/httpd/logs/foo.log". -# - -### Section 1: Global Environment -# -# The directives in this section affect the overall operation of Apache, -# such as the number of concurrent requests it can handle or where it -# can find its configuration files. -# - -# -# Don't give away too much information about all the subcomponents -# we are running. Comment out this line if you don't mind remote sites -# finding out what major optional modules you are running -ServerTokens OS - -# -# ServerRoot: The top of the directory tree under which the server's -# configuration, error, and log files are kept. -# -# NOTE! If you intend to place this on an NFS (or otherwise network) -# mounted filesystem then please read the LockFile documentation -# (available at ); -# you will save yourself a lot of trouble. -# -# Do NOT add a slash at the end of the directory path. -# -ServerRoot "/etc/httpd" - -# -# PidFile: The file in which the server should record its process -# identification number when it starts. -# -PidFile run/httpd.pid - -# -# Timeout: The number of seconds before receives and sends time out. -# -Timeout 120 - -# -# KeepAlive: Whether or not to allow persistent connections (more than -# one request per connection). Set to "Off" to deactivate. -# -KeepAlive Off - -# -# MaxKeepAliveRequests: The maximum number of requests to allow -# during a persistent connection. Set to 0 to allow an unlimited amount. -# We recommend you leave this number high, for maximum performance. -# -MaxKeepAliveRequests 100 - -# -# KeepAliveTimeout: Number of seconds to wait for the next request from the -# same client on the same connection. -# -KeepAliveTimeout 15 - -## -## Server-Pool Size Regulation (MPM specific) -## - -# prefork MPM -# StartServers: number of server processes to start -# MinSpareServers: minimum number of server processes which are kept spare -# MaxSpareServers: maximum number of server processes which are kept spare -# ServerLimit: maximum value for MaxClients for the lifetime of the server -# MaxClients: maximum number of server processes allowed to start -# MaxRequestsPerChild: maximum number of requests a server process serves - -StartServers 8 -MinSpareServers 5 -MaxSpareServers 20 -ServerLimit 256 -MaxClients 256 -MaxRequestsPerChild 4000 - - -# worker MPM -# StartServers: initial number of server processes to start -# MaxClients: maximum number of simultaneous client connections -# MinSpareThreads: minimum number of worker threads which are kept spare -# MaxSpareThreads: maximum number of worker threads which are kept spare -# ThreadsPerChild: constant number of worker threads in each server process -# MaxRequestsPerChild: maximum number of requests a server process serves - -StartServers 2 -MaxClients 150 -MinSpareThreads 25 -MaxSpareThreads 75 -ThreadsPerChild 25 -MaxRequestsPerChild 0 - - -# -# Listen: Allows you to bind Apache to specific IP addresses and/or -# ports, in addition to the default. See also the -# directive. -# -# Change this to Listen on specific IP addresses as shown below to -# prevent Apache from glomming onto all bound IP addresses (0.0.0.0) -# -#Listen 12.34.56.78:80 -Listen 10.1.1.1:80 - -# -# Dynamic Shared Object (DSO) Support -# -# To be able to use the functionality of a module which was built as a DSO you -# have to place corresponding `LoadModule' lines at this location so the -# directives contained in it are actually available _before_ they are used. -# Statically compiled modules (those listed by `httpd -l') do not need -# to be loaded here. -# -# Example: -# LoadModule foo_module modules/mod_foo.so -# -LoadModule auth_basic_module modules/mod_auth_basic.so -LoadModule auth_digest_module modules/mod_auth_digest.so -LoadModule authn_file_module modules/mod_authn_file.so -LoadModule authn_alias_module modules/mod_authn_alias.so -LoadModule authn_anon_module modules/mod_authn_anon.so -LoadModule authn_dbm_module modules/mod_authn_dbm.so -LoadModule authn_default_module modules/mod_authn_default.so -LoadModule authz_host_module modules/mod_authz_host.so -LoadModule authz_user_module modules/mod_authz_user.so -LoadModule authz_owner_module modules/mod_authz_owner.so -LoadModule authz_groupfile_module modules/mod_authz_groupfile.so -LoadModule authz_dbm_module modules/mod_authz_dbm.so -LoadModule authz_default_module modules/mod_authz_default.so -LoadModule ldap_module modules/mod_ldap.so -LoadModule authnz_ldap_module modules/mod_authnz_ldap.so -LoadModule include_module modules/mod_include.so -LoadModule log_config_module modules/mod_log_config.so -LoadModule logio_module modules/mod_logio.so -LoadModule env_module modules/mod_env.so -LoadModule ext_filter_module modules/mod_ext_filter.so -LoadModule mime_magic_module modules/mod_mime_magic.so -LoadModule expires_module modules/mod_expires.so -LoadModule deflate_module modules/mod_deflate.so -LoadModule headers_module modules/mod_headers.so -LoadModule usertrack_module modules/mod_usertrack.so -LoadModule setenvif_module modules/mod_setenvif.so -LoadModule mime_module modules/mod_mime.so -LoadModule dav_module modules/mod_dav.so -LoadModule status_module modules/mod_status.so -LoadModule autoindex_module modules/mod_autoindex.so -LoadModule info_module modules/mod_info.so -LoadModule dav_fs_module modules/mod_dav_fs.so -LoadModule vhost_alias_module modules/mod_vhost_alias.so -LoadModule negotiation_module modules/mod_negotiation.so -LoadModule dir_module modules/mod_dir.so -LoadModule actions_module modules/mod_actions.so -LoadModule speling_module modules/mod_speling.so -LoadModule userdir_module modules/mod_userdir.so -LoadModule alias_module modules/mod_alias.so -LoadModule rewrite_module modules/mod_rewrite.so -LoadModule proxy_module modules/mod_proxy.so -LoadModule proxy_balancer_module modules/mod_proxy_balancer.so -LoadModule proxy_ftp_module modules/mod_proxy_ftp.so -LoadModule proxy_http_module modules/mod_proxy_http.so -LoadModule proxy_connect_module modules/mod_proxy_connect.so -LoadModule cache_module modules/mod_cache.so -LoadModule suexec_module modules/mod_suexec.so -LoadModule disk_cache_module modules/mod_disk_cache.so -LoadModule file_cache_module modules/mod_file_cache.so -LoadModule mem_cache_module modules/mod_mem_cache.so -LoadModule cgi_module modules/mod_cgi.so - -# -# The following modules are not loaded by default: -# -#LoadModule cern_meta_module modules/mod_cern_meta.so -#LoadModule asis_module modules/mod_asis.so - -# -# Load config files from the config directory "/etc/httpd/conf.d". -# -Include conf.d/*.conf - -# -# ExtendedStatus controls whether Apache will generate "full" status -# information (ExtendedStatus On) or just basic information (ExtendedStatus -# Off) when the "server-status" handler is called. The default is Off. -# -#ExtendedStatus On - -# -# If you wish httpd to run as a different user or group, you must run -# httpd as root initially and it will switch. -# -# User/Group: The name (or #number) of the user/group to run httpd as. -# . On SCO (ODT 3) use "User nouser" and "Group nogroup". -# . On HPUX you may not be able to use shared memory as nobody, and the -# suggested workaround is to create a user www and use that user. -# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET) -# when the value of (unsigned)Group is above 60000; -# don't use Group #-1 on these systems! -# -User apache -Group apache - -### Section 2: 'Main' server configuration -# -# The directives in this section set up the values used by the 'main' -# server, which responds to any requests that aren't handled by a -# definition. These values also provide defaults for -# any containers you may define later in the file. -# -# All of these directives may appear inside containers, -# in which case these default settings will be overridden for the -# virtual host being defined. -# - -# -# ServerAdmin: Your address, where problems with the server should be -# e-mailed. This address appears on some server-generated pages, such -# as error documents. e.g. admin@your-domain.com -# -ServerAdmin root@localhost - -# -# ServerName gives the name and port that the server uses to identify itself. -# This can often be determined automatically, but we recommend you specify -# it explicitly to prevent problems during startup. -# -# If this is not set to valid DNS name for your host, server-generated -# redirections will not work. See also the UseCanonicalName directive. -# -# If your host doesn't have a registered DNS name, enter its IP address here. -# You will have to access it by its address anyway, and this will make -# redirections work in a sensible way. -# -#ServerName www.example.com:80 - -# -# UseCanonicalName: Determines how Apache constructs self-referencing -# URLs and the SERVER_NAME and SERVER_PORT variables. -# When set "Off", Apache will use the Hostname and Port supplied -# by the client. When set "On", Apache will use the value of the -# ServerName directive. -# -UseCanonicalName Off - -# -# DocumentRoot: The directory out of which you will serve your -# documents. By default, all requests are taken from this directory, but -# symbolic links and aliases may be used to point to other locations. -# -DocumentRoot "/var/www/html" - -# -# Each directory to which Apache has access can be configured with respect -# to which services and features are allowed and/or disabled in that -# directory (and its subdirectories). -# -# First, we configure the "default" to be a very restrictive set of -# features. -# - - Options FollowSymLinks - AllowOverride None - - -# -# Note that from this point forward you must specifically allow -# particular features to be enabled - so if something's not working as -# you might expect, make sure that you have specifically enabled it -# below. -# - -# -# This should be changed to whatever you set DocumentRoot to. -# - - -# -# Possible values for the Options directive are "None", "All", -# or any combination of: -# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews -# -# Note that "MultiViews" must be named *explicitly* --- "Options All" -# doesn't give it to you. -# -# The Options directive is both complicated and important. Please see -# http://httpd.apache.org/docs/2.2/mod/core.html#options -# for more information. -# - Options Indexes FollowSymLinks - -# -# AllowOverride controls what directives may be placed in .htaccess files. -# It can be "All", "None", or any combination of the keywords: -# Options FileInfo AuthConfig Limit -# - AllowOverride All - -# -# Controls who can get stuff from this server. -# - Order allow,deny - Allow from all - - - -# -# UserDir: The name of the directory that is appended onto a user's home -# directory if a ~user request is received. -# -# The path to the end user account 'public_html' directory must be -# accessible to the webserver userid. This usually means that ~userid -# must have permissions of 711, ~userid/public_html must have permissions -# of 755, and documents contained therein must be world-readable. -# Otherwise, the client will only receive a "403 Forbidden" message. -# -# See also: http://httpd.apache.org/docs/misc/FAQ.html#forbidden -# - - # - # UserDir is disabled by default since it can confirm the presence - # of a username on the system (depending on home directory - # permissions). - # - UserDir disable - - # - # To enable requests to /~user/ to serve the user's public_html - # directory, remove the "UserDir disable" line above, and uncomment - # the following line instead: - # - #UserDir public_html - - - -# -# Control access to UserDir directories. The following is an example -# for a site where these directories are restricted to read-only. -# -# -# AllowOverride FileInfo AuthConfig Limit -# Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec -# -# Order allow,deny -# Allow from all -# -# -# Order deny,allow -# Deny from all -# -# - -# -# DirectoryIndex: sets the file that Apache will serve if a directory -# is requested. -# -# The index.html.var file (a type-map) is used to deliver content- -# negotiated documents. The MultiViews Option can be used for the -# same purpose, but it is much slower. -# -DirectoryIndex index.html index.html.var - -# -# AccessFileName: The name of the file to look for in each directory -# for additional configuration directives. See also the AllowOverride -# directive. -# -AccessFileName .htaccess - -# -# The following lines prevent .htaccess and .htpasswd files from being -# viewed by Web clients. -# - - Order allow,deny - Deny from all - - -# -# TypesConfig describes where the mime.types file (or equivalent) is -# to be found. -# -TypesConfig /etc/mime.types - -# -# DefaultType is the default MIME type the server will use for a document -# if it cannot otherwise determine one, such as from filename extensions. -# If your server contains mostly text or HTML documents, "text/plain" is -# a good value. If most of your content is binary, such as applications -# or images, you may want to use "application/octet-stream" instead to -# keep browsers from trying to display binary files as though they are -# text. -# -DefaultType text/plain - -# -# The mod_mime_magic module allows the server to use various hints from the -# contents of the file itself to determine its type. The MIMEMagicFile -# directive tells the module where the hint definitions are located. -# - -# MIMEMagicFile /usr/share/magic.mime - MIMEMagicFile conf/magic - - -# -# HostnameLookups: Log the names of clients or just their IP addresses -# e.g., www.apache.org (on) or 204.62.129.132 (off). -# The default is off because it'd be overall better for the net if people -# had to knowingly turn this feature on, since enabling it means that -# each client request will result in AT LEAST one lookup request to the -# nameserver. -# -HostnameLookups Off - -# -# EnableMMAP: Control whether memory-mapping is used to deliver -# files (assuming that the underlying OS supports it). -# The default is on; turn this off if you serve from NFS-mounted -# filesystems. On some systems, turning it off (regardless of -# filesystem) can improve performance; for details, please see -# http://httpd.apache.org/docs/2.2/mod/core.html#enablemmap -# -#EnableMMAP off - -# -# EnableSendfile: Control whether the sendfile kernel support is -# used to deliver files (assuming that the OS supports it). -# The default is on; turn this off if you serve from NFS-mounted -# filesystems. Please see -# http://httpd.apache.org/docs/2.2/mod/core.html#enablesendfile -# -#EnableSendfile off - -# -# ErrorLog: The location of the error log file. -# If you do not specify an ErrorLog directive within a -# container, error messages relating to that virtual host will be -# logged here. If you *do* define an error logfile for a -# container, that host's errors will be logged there and not here. -# -ErrorLog logs/error_log - -# -# LogLevel: Control the number of messages logged to the error_log. -# Possible values include: debug, info, notice, warn, error, crit, -# alert, emerg. -# -LogLevel warn - -# -# The following directives define some format nicknames for use with -# a CustomLog directive (see below). -# -LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined -LogFormat "%h %l %u %t \"%r\" %>s %b" common -LogFormat "%{Referer}i -> %U" referer -LogFormat "%{User-agent}i" agent - -# "combinedio" includes actual counts of actual bytes received (%I) and sent (%O); this -# requires the mod_logio module to be loaded. -#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio - -# -# The location and format of the access logfile (Common Logfile Format). -# If you do not define any access logfiles within a -# container, they will be logged here. Contrariwise, if you *do* -# define per- access logfiles, transactions will be -# logged therein and *not* in this file. -# -#CustomLog logs/access_log common - -# -# If you would like to have separate agent and referer logfiles, uncomment -# the following directives. -# -#CustomLog logs/referer_log referer -#CustomLog logs/agent_log agent - -# -# For a single logfile with access, agent, and referer information -# (Combined Logfile Format), use the following directive: -# -CustomLog logs/access_log combined - -# -# Optionally add a line containing the server version and virtual host -# name to server-generated pages (internal error documents, FTP directory -# listings, mod_status and mod_info output etc., but not CGI generated -# documents or custom error documents). -# Set to "EMail" to also include a mailto: link to the ServerAdmin. -# Set to one of: On | Off | EMail -# -ServerSignature On - -# -# Aliases: Add here as many aliases as you need (with no limit). The format is -# Alias fakename realname -# -# Note that if you include a trailing / on fakename then the server will -# require it to be present in the URL. So "/icons" isn't aliased in this -# example, only "/icons/". If the fakename is slash-terminated, then the -# realname must also be slash terminated, and if the fakename omits the -# trailing slash, the realname must also omit it. -# -# We include the /icons/ alias for FancyIndexed directory listings. If you -# do not use FancyIndexing, you may comment this out. -# -Alias /icons/ "/var/www/icons/" - - - Options Indexes MultiViews FollowSymLinks - AllowOverride None - Order allow,deny - Allow from all - - -# -# WebDAV module configuration section. -# - - # Location of the WebDAV lock database. - DAVLockDB /var/lib/dav/lockdb - - -# -# ScriptAlias: This controls which directories contain server scripts. -# ScriptAliases are essentially the same as Aliases, except that -# documents in the realname directory are treated as applications and -# run by the server when requested rather than as documents sent to the client. -# The same rules about trailing "/" apply to ScriptAlias directives as to -# Alias. -# -ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" - -# -# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased -# CGI directory exists, if you have that configured. -# - - AllowOverride None - Options None - Order allow,deny - Allow from all - - -# -# Redirect allows you to tell clients about documents which used to exist in -# your server's namespace, but do not anymore. This allows you to tell the -# clients where to look for the relocated document. -# Example: -# Redirect permanent /foo http://www.example.com/bar - -# -# Directives controlling the display of server-generated directory listings. -# - -# -# IndexOptions: Controls the appearance of server-generated directory -# listings. -# -IndexOptions FancyIndexing VersionSort NameWidth=* HTMLTable - -# -# AddIcon* directives tell the server which icon to show for different -# files or filename extensions. These are only displayed for -# FancyIndexed directories. -# -AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip - -AddIconByType (TXT,/icons/text.gif) text/* -AddIconByType (IMG,/icons/image2.gif) image/* -AddIconByType (SND,/icons/sound2.gif) audio/* -AddIconByType (VID,/icons/movie.gif) video/* - -AddIcon /icons/binary.gif .bin .exe -AddIcon /icons/binhex.gif .hqx -AddIcon /icons/tar.gif .tar -AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv -AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip -AddIcon /icons/a.gif .ps .ai .eps -AddIcon /icons/layout.gif .html .shtml .htm .pdf -AddIcon /icons/text.gif .txt -AddIcon /icons/c.gif .c -AddIcon /icons/p.gif .pl .py -AddIcon /icons/f.gif .for -AddIcon /icons/dvi.gif .dvi -AddIcon /icons/uuencoded.gif .uu -AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl -AddIcon /icons/tex.gif .tex -AddIcon /icons/bomb.gif core - -AddIcon /icons/back.gif .. -AddIcon /icons/hand.right.gif README -AddIcon /icons/folder.gif ^^DIRECTORY^^ -AddIcon /icons/blank.gif ^^BLANKICON^^ - -# -# DefaultIcon is which icon to show for files which do not have an icon -# explicitly set. -# -DefaultIcon /icons/unknown.gif - -# -# AddDescription allows you to place a short description after a file in -# server-generated indexes. These are only displayed for FancyIndexed -# directories. -# Format: AddDescription "description" filename -# -#AddDescription "GZIP compressed document" .gz -#AddDescription "tar archive" .tar -#AddDescription "GZIP compressed tar archive" .tgz - -# -# ReadmeName is the name of the README file the server will look for by -# default, and append to directory listings. -# -# HeaderName is the name of a file which should be prepended to -# directory indexes. -ReadmeName README.html -HeaderName HEADER.html - -# -# IndexIgnore is a set of filenames which directory indexing should ignore -# and not include in the listing. Shell-style wildcarding is permitted. -# -IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t - -# -# DefaultLanguage and AddLanguage allows you to specify the language of -# a document. You can then use content negotiation to give a browser a -# file in a language the user can understand. -# -# Specify a default language. This means that all data -# going out without a specific language tag (see below) will -# be marked with this one. You probably do NOT want to set -# this unless you are sure it is correct for all cases. -# -# * It is generally better to not mark a page as -# * being a certain language than marking it with the wrong -# * language! -# -# DefaultLanguage nl -# -# Note 1: The suffix does not have to be the same as the language -# keyword --- those with documents in Polish (whose net-standard -# language code is pl) may wish to use "AddLanguage pl .po" to -# avoid the ambiguity with the common suffix for perl scripts. -# -# Note 2: The example entries below illustrate that in some cases -# the two character 'Language' abbreviation is not identical to -# the two character 'Country' code for its country, -# E.g. 'Danmark/dk' versus 'Danish/da'. -# -# Note 3: In the case of 'ltz' we violate the RFC by using a three char -# specifier. There is 'work in progress' to fix this and get -# the reference data for rfc1766 cleaned up. -# -# Catalan (ca) - Croatian (hr) - Czech (cs) - Danish (da) - Dutch (nl) -# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de) -# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja) -# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn) -# Norwegian (no) - Polish (pl) - Portugese (pt) -# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv) -# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW) -# -AddLanguage ca .ca -AddLanguage cs .cz .cs -AddLanguage da .dk -AddLanguage de .de -AddLanguage el .el -AddLanguage en .en -AddLanguage eo .eo -AddLanguage es .es -AddLanguage et .et -AddLanguage fr .fr -AddLanguage he .he -AddLanguage hr .hr -AddLanguage it .it -AddLanguage ja .ja -AddLanguage ko .ko -AddLanguage ltz .ltz -AddLanguage nl .nl -AddLanguage nn .nn -AddLanguage no .no -AddLanguage pl .po -AddLanguage pt .pt -AddLanguage pt-BR .pt-br -AddLanguage ru .ru -AddLanguage sv .sv -AddLanguage zh-CN .zh-cn -AddLanguage zh-TW .zh-tw - -# -# LanguagePriority allows you to give precedence to some languages -# in case of a tie during content negotiation. -# -# Just list the languages in decreasing order of preference. We have -# more or less alphabetized them here. You probably want to change this. -# -LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW - -# -# ForceLanguagePriority allows you to serve a result page rather than -# MULTIPLE CHOICES (Prefer) [in case of a tie] or NOT ACCEPTABLE (Fallback) -# [in case no accepted languages matched the available variants] -# -ForceLanguagePriority Prefer Fallback - -# -# Specify a default charset for all content served; this enables -# interpretation of all content as UTF-8 by default. To use the -# default browser choice (ISO-8859-1), or to allow the META tags -# in HTML content to override this choice, comment out this -# directive: -# -AddDefaultCharset UTF-8 - -# -# AddType allows you to add to or override the MIME configuration -# file mime.types for specific file types. -# -#AddType application/x-tar .tgz - -# -# AddEncoding allows you to have certain browsers uncompress -# information on the fly. Note: Not all browsers support this. -# Despite the name similarity, the following Add* directives have nothing -# to do with the FancyIndexing customization directives above. -# -#AddEncoding x-compress .Z -#AddEncoding x-gzip .gz .tgz - -# If the AddEncoding directives above are commented-out, then you -# probably should define those extensions to indicate media types: -# -AddType application/x-compress .Z -AddType application/x-gzip .gz .tgz - -# -# AddHandler allows you to map certain file extensions to "handlers": -# actions unrelated to filetype. These can be either built into the server -# or added with the Action directive (see below) -# -# To use CGI scripts outside of ScriptAliased directories: -# (You will also need to add "ExecCGI" to the "Options" directive.) -# -#AddHandler cgi-script .cgi - -# -# For files that include their own HTTP headers: -# -#AddHandler send-as-is asis - -# -# For type maps (negotiated resources): -# (This is enabled by default to allow the Apache "It Worked" page -# to be distributed in multiple languages.) -# -AddHandler type-map var - -# -# Filters allow you to process content before it is sent to the client. -# -# To parse .shtml files for server-side includes (SSI): -# (You will also need to add "Includes" to the "Options" directive.) -# -AddType text/html .shtml -AddOutputFilter INCLUDES .shtml - -# -# Action lets you define media types that will execute a script whenever -# a matching file is called. This eliminates the need for repeated URL -# pathnames for oft-used CGI file processors. -# Format: Action media/type /cgi-script/location -# Format: Action handler-name /cgi-script/location -# - -# -# Customizable error responses come in three flavors: -# 1) plain text 2) local redirects 3) external redirects -# -# Some examples: -#ErrorDocument 500 "The server made a boo boo." -#ErrorDocument 404 /missing.html -#ErrorDocument 404 "/cgi-bin/missing_handler.pl" -#ErrorDocument 402 http://www.example.com/subscription_info.html -# - -# -# Putting this all together, we can internationalize error responses. -# -# We use Alias to redirect any /error/HTTP_.html.var response to -# our collection of by-error message multi-language collections. We use -# includes to substitute the appropriate text. -# -# You can modify the messages' appearance without changing any of the -# default HTTP_.html.var files by adding the line: -# -# Alias /error/include/ "/your/include/path/" -# -# which allows you to create your own set of files by starting with the -# /var/www/error/include/ files and -# copying them to /your/include/path/, even on a per-VirtualHost basis. -# - -Alias /error/ "/var/www/error/" - - - - - AllowOverride None - Options IncludesNoExec - AddOutputFilter Includes html - AddHandler type-map var - Order allow,deny - Allow from all - LanguagePriority en es de fr - ForceLanguagePriority Prefer Fallback - - -# ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var -# ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var -# ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var -# ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var -# ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var -# ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var -# ErrorDocument 410 /error/HTTP_GONE.html.var -# ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var -# ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var -# ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var -# ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var -# ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var -# ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var -# ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var -# ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var -# ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var -# ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var - - - - -# -# The following directives modify normal HTTP response behavior to -# handle known problems with browser implementations. -# -BrowserMatch "Mozilla/2" nokeepalive -BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 -BrowserMatch "RealPlayer 4\.0" force-response-1.0 -BrowserMatch "Java/1\.0" force-response-1.0 -BrowserMatch "JDK/1\.0" force-response-1.0 - -# -# The following directive disables redirects on non-GET requests for -# a directory that does not include the trailing slash. This fixes a -# problem with Microsoft WebFolders which does not appropriately handle -# redirects for folders with DAV methods. -# Same deal with Apple's DAV filesystem and Gnome VFS support for DAV. -# -BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully -BrowserMatch "MS FrontPage" redirect-carefully -BrowserMatch "^WebDrive" redirect-carefully -BrowserMatch "^WebDAVFS/1.[0123]" redirect-carefully -BrowserMatch "^gnome-vfs/1.0" redirect-carefully -BrowserMatch "^XML Spy" redirect-carefully -BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully - -# -# Allow server status reports generated by mod_status, -# with the URL of http://servername/server-status -# Change the ".example.com" to match your domain to enable. -# -# -# SetHandler server-status -# Order deny,allow -# Deny from all -# Allow from .example.com -# - -# -# Allow remote server configuration reports, with the URL of -# http://servername/server-info (requires that mod_info.c be loaded). -# Change the ".example.com" to match your domain to enable. -# -# -# SetHandler server-info -# Order deny,allow -# Deny from all -# Allow from .example.com -# - -# -# Proxy Server directives. Uncomment the following lines to -# enable the proxy server: -# -# -#ProxyRequests On -# -# -# Order deny,allow -# Deny from all -# Allow from .example.com -# - -# -# Enable/disable the handling of HTTP/1.1 "Via:" headers. -# ("Full" adds the server version; "Block" removes all outgoing Via: headers) -# Set to one of: Off | On | Full | Block -# -#ProxyVia On - -# -# To enable a cache of proxied content, uncomment the following lines. -# See http://httpd.apache.org/docs/2.2/mod/mod_cache.html for more details. -# -# -# CacheEnable disk / -# CacheRoot "/var/cache/mod_proxy" -# -# - -# -# End of proxy directives. - -### Section 3: Virtual Hosts -# -# VirtualHost: If you want to maintain multiple domains/hostnames on your -# machine you can setup VirtualHost containers for them. Most configurations -# use only name-based virtual hosts so the server doesn't need to worry about -# IP addresses. This is indicated by the asterisks in the directives below. -# -# Please see the documentation at -# -# for further details before you try to setup virtual hosts. -# -# You may use the command line option '-S' to verify your virtual host -# configuration. - -# -# Use name-based virtual hosting. -# -#NameVirtualHost *:80 -# -# NOTE: NameVirtualHost cannot be used without a port specifier -# (e.g. :80) if mod_ssl is being used, due to the nature of the -# SSL protocol. -# - -# -# VirtualHost example: -# Almost any Apache directive may go into a VirtualHost container. -# The first VirtualHost section is used for requests without a known -# server name. -# -# -# ServerAdmin webmaster@dummy-host.example.com -# DocumentRoot /www/docs/dummy-host.example.com -# ServerName dummy-host.example.com -# ErrorLog logs/dummy-host.example.com-error_log -# CustomLog logs/dummy-host.example.com-access_log common -# diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index ca97d293c1c..7e5815682a8 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -115,6 +115,7 @@ get_boot_params() { cp -f $EXTRA_MOUNT/authorized_keys /var/cache/cloud/authorized_keys privkey=/var/cache/cloud/authorized_keys umount $EXTRA_MOUNT + cp -f $privkey /root/.ssh/ && chmod go-rwx /root/.ssh/authorized_keys ;; vmware) vmtoolsd --cmd 'machine.id.get' > /var/cache/cloud/cmdline @@ -407,7 +408,9 @@ setup_dnsmasq() { setup_sshd(){ local ip=$1 + local eth=$2 [ -f /etc/ssh/sshd_config ] && sed -i -e "s/^[#]*ListenAddress.*$/ListenAddress $ip/" /etc/ssh/sshd_config + sed -i "/3922/s/eth./$eth/" /etc/iptables/rules } @@ -455,7 +458,6 @@ setup_redundant_router() { mkdir -p /ramdisk mount tmpfs /ramdisk -t tmpfs mkdir -p /ramdisk/rrouter - rm /tmp/rrouter.lock ip route delete default cp /root/redundant_router/keepalived.conf.templ /etc/keepalived/keepalived.conf cp /root/redundant_router/conntrackd.conf.templ /etc/conntrackd/conntrackd.conf @@ -574,7 +576,6 @@ setup_router() { sed -i /gateway/d /etc/hosts echo "$ETH0_IP $NAME" >> /etc/hosts - setup_sshd $ETH1_IP enable_svc dnsmasq 1 enable_svc haproxy 1 @@ -584,6 +585,7 @@ setup_router() { enable_fwding 1 chkconfig nfs-common off cp /etc/iptables/iptables-router /etc/iptables/rules + setup_sshd $ETH1_IP "eth1" } @@ -643,20 +645,15 @@ EOF sudo ip rule add from $VPCCIDR table static_route 2>/dev/null sudo ip rule add from $VPCCIDR table static_route_back 2>/dev/null - sed -i /gateway/d /etc/hosts - - echo "$ETH0_IP $NAME" >> /etc/hosts - setup_sshd $ETH0_IP setup_vpc_apache2 enable_svc dnsmasq 1 enable_svc haproxy 1 - enable_svc cloud-passwd-srvr 1 enable_svc cloud 0 disable_rpfilter_domR enable_fwding 1 - chkconfig nfs-common off cp /etc/iptables/iptables-vpcrouter /etc/iptables/rules + setup_sshd $ETH0_IP "eth0" cp /etc/vpcdnsmasq.conf /etc/dnsmasq.conf cp /etc/cloud-nic.rules /etc/udev/rules.d/cloud-nic.rules echo "" > /etc/dnsmasq.d/dhcphosts.txt @@ -695,24 +692,18 @@ setup_dhcpsrvr() { sed -i /gateway/d /etc/hosts echo "$ETH0_IP $NAME" >> /etc/hosts - if [ "$SSHONGUEST" == "true" ] - then - setup_sshd $ETH0_IP - else - setup_sshd $ETH1_IP - fi - enable_svc dnsmasq 1 enable_svc haproxy 0 enable_svc cloud-passwd-srvr 1 enable_svc cloud 0 enable_fwding 0 chkconfig nfs-common off + cp /etc/iptables/iptables-router /etc/iptables/rules if [ "$SSHONGUEST" == "true" ] then - sed '/3922/i -A INPUT -i eth0 -p tcp -m state --state NEW --dport 3922 -j ACCEPT' /etc/iptables/iptables-router > /etc/iptables/rules + setup_sshd $ETH0_IP "eth0" else - cp /etc/iptables/iptables-router /etc/iptables/rules + setup_sshd $ETH1_IP "eth1" fi } @@ -744,9 +735,9 @@ setup_secstorage() { cp /etc/iptables/iptables-secstorage /etc/iptables/rules if [ "$hyp" == "vmware" ]; then - setup_sshd $ETH1_IP + setup_sshd $ETH1_IP "eth1" else - setup_sshd $ETH0_IP + setup_sshd $ETH0_IP "eth0" fi setup_apache2 $ETH2_IP @@ -768,9 +759,9 @@ setup_console_proxy() { echo "$public_ip $NAME" >> /etc/hosts cp /etc/iptables/iptables-consoleproxy /etc/iptables/rules if [ "$hyp" == "vmware" ]; then - setup_sshd $ETH1_IP + setup_sshd $ETH1_IP "eth1" else - setup_sshd $ETH0_IP + setup_sshd $ETH0_IP "eth0" fi disable_rpfilter @@ -791,13 +782,12 @@ setup_elbvm() { [ "$ETH2_IP" == "0.0.0.0" ] || [ "$ETH2_IP" == "" ] && public_ip=$ETH0_IP echo "$public_ip $NAME" >> /etc/hosts + cp /etc/iptables/iptables-elbvm /etc/iptables/rules if [ "$SSHONGUEST" == "true" ] then - sed '/3922/s/eth1/eth0/' - setup_sshd $ETH0_IP + setup_sshd $ETH0_IP "eth0" else - cp /etc/iptables/iptables-elbvm /etc/iptables/rules - setup_sshd $ETH1_IP + setup_sshd $ETH1_IP "eth1" fi enable_fwding 0 @@ -825,6 +815,8 @@ change_password() { } start() { + # Clear /tmp for file lock + rm -f /tmp/*.lock local hyp=$(hypervisor) [ $? -ne 0 ] && log_it "Failed to detect hypervisor type, bailing out of early init" && exit 10 log_it "Detected that we are running inside $hyp guest" diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-passwd-srvr b/patches/systemvm/debian/config/etc/init.d/cloud-passwd-srvr index 553fe0ae962..7c938f7a025 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-passwd-srvr +++ b/patches/systemvm/debian/config/etc/init.d/cloud-passwd-srvr @@ -29,15 +29,48 @@ ENABLED=0 [ -e /etc/default/cloud-passwd-srvr ] && . /etc/default/cloud-passwd-srvr +add_iptables_rules() +{ + #Delete any old iptables rule for port 8080 on eth0 + remove_iptables_rules + + #For all cidrs on eth0 for port 8080 accept only if source is withing that cidr + for cidr in $(ip addr | grep eth0 | grep inet | awk '{print $2}'); + do + iptables -A INPUT -i eth0 -p tcp -m state --state NEW -m tcp -s $cidr --dport 8080 -j ACCEPT + done + echo "Added cloud-passwd-srvr iptables rules" && return 0 +} + +remove_iptables_rules() +{ + #Change the Internal Field Separator so the for loop, loops on lines and not spaces + OIFS="${IFS}" + NIFS=$'\n' + IFS="${NIFS}" + + #Removed all iptable rules for port 8080 on eth0, they were added in start() + for srcdest in `iptables -L -n -v | grep eth0 | grep 8080 | grep ACCEPT | awk '{print "--source "$8" --destination "$9}'`; + do + eval "iptables -D INPUT -i eth0 -p tcp -m state --state NEW -m tcp $srcdest --dport 8080 -j ACCEPT"; + done + + #Restore IFS + IFS="${OIFS}" + + echo "Removed cloud-passwd-srvr iptables rules" && return 0 +} + start() { [ "$ENABLED" != 0 ] || exit 0 pid=$(getpid) [ "$pid" != "" ] && echo "Password server is already running (pid=$pid)" && return 0 - nohup bash /opt/cloud/bin/passwd_server& + add_iptables_rules + nohup bash /opt/cloud/bin/passwd_server & } getpid() { - pid=$(ps -ef | grep passwd_server | grep -v grep | awk '{print $2}') + pid=$(ps -ef | grep passwd_server_ip | grep -v grep | awk '{print $2}') echo $pid } @@ -50,7 +83,8 @@ stop_socat() { stop () { stop_socat pid=$(getpid) - [ "$pid" != "" ] && kill -9 $pid && echo "Stopped password server (pid=$pid)" && stop_socat && return 0 + [ "$pid" != "" ] && kill -9 $pid && remove_iptables_rules && echo "Stopped password server (pid=$pid)" && stop_socat && return 0 + echo "Password server is not running" && return 0 } diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-consoleproxy b/patches/systemvm/debian/config/etc/iptables/iptables-consoleproxy index 6e230386412..ae5d14d8461 100644 --- a/patches/systemvm/debian/config/etc/iptables/iptables-consoleproxy +++ b/patches/systemvm/debian/config/etc/iptables/iptables-consoleproxy @@ -30,7 +30,6 @@ COMMIT -A INPUT -i eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp --icmp-type 13 -j DROP -A INPUT -p icmp -j ACCEPT --A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT -A INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT -A INPUT -i eth0 -p tcp -m state --state NEW -m tcp --dport 8001 -j ACCEPT -A INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 8001 -j ACCEPT diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-router b/patches/systemvm/debian/config/etc/iptables/iptables-router index 1aba34c8d3f..59d2e4655b9 100644 --- a/patches/systemvm/debian/config/etc/iptables/iptables-router +++ b/patches/systemvm/debian/config/etc/iptables/iptables-router @@ -34,7 +34,6 @@ COMMIT -A INPUT -i eth0 -p udp -m udp --dport 67 -j ACCEPT -A INPUT -i eth0 -p udp -m udp --dport 53 -j ACCEPT -A INPUT -i eth1 -p tcp -m state --state NEW --dport 3922 -j ACCEPT --A INPUT -i eth0 -p tcp -m state --state NEW --dport 8080 -j ACCEPT -A INPUT -i eth0 -p tcp -m state --state NEW --dport 80 -j ACCEPT -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i eth0 -o eth2 -j ACCEPT diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-secstorage b/patches/systemvm/debian/config/etc/iptables/iptables-secstorage index 5218fa72de6..31399241126 100755 --- a/patches/systemvm/debian/config/etc/iptables/iptables-secstorage +++ b/patches/systemvm/debian/config/etc/iptables/iptables-secstorage @@ -33,6 +33,4 @@ COMMIT -A INPUT -p icmp --icmp-type 13 -j DROP -A INPUT -p icmp -j ACCEPT -A INPUT -i eth0 -p tcp -m state --state NEW --dport 3922 -j ACCEPT --A INPUT -i eth1 -p tcp -m state --state NEW --dport 3922 -j ACCEPT --A INPUT -i eth3 -p tcp -m state --state NEW --dport 3922 -j ACCEPT COMMIT diff --git a/patches/systemvm/debian/config/etc/logrotate.conf b/patches/systemvm/debian/config/etc/logrotate.conf index f5a660964d3..59a6242bb4c 100644 --- a/patches/systemvm/debian/config/etc/logrotate.conf +++ b/patches/systemvm/debian/config/etc/logrotate.conf @@ -1,32 +1,21 @@ -# see "man logrotate" for details # rotate log files daily daily - # keep 5 days worth rotate 5 - # create new (empty) log files after rotating old ones create - # use date as a suffix of the rotated file dateext - -# uncomment this if you want your log files compressed -#compress - # max size 50M size 50M - # RPM packages drop log rotation information into this directory include /etc/logrotate.d - # no packages own wtmp and btmp -- we'll rotate them here /var/log/wtmp { monthly create 0664 root utmp rotate 1 } - /var/log/btmp { missingok monthly @@ -34,4 +23,3 @@ include /etc/logrotate.d rotate 1 } -# system-specific logs may be also be configured here. diff --git a/patches/systemvm/debian/config/opt/cloud/bin/passwd_server b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server index 95225b6a901..71349dd0336 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/passwd_server +++ b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server @@ -16,18 +16,8 @@ # specific language governing permissions and limitations # under the License. -. /etc/default/cloud-passwd-srvr - -while [ "$ENABLED" == "1" ] -do - socat -lf /var/log/cloud.log TCP4-LISTEN:8080,reuseaddr,crnl,bind=0.0.0.0 SYSTEM:"/opt/cloud/bin/serve_password.sh \"\$SOCAT_PEERADDR\"" - - rc=$? - if [ $rc -ne 0 ] - then - logger -t cloud "Password server failed with error code $rc. Restarting socat..." - sleep 3 - fi - . /etc/default/cloud-passwd-srvr - -done +ips=$(ip addr show dev eth0 | grep inet | grep eth0 | awk '{print $2}' ); echo $ips +for ip in $ips; do + addr=$(echo $ip | awk -F'/' '{print $1}') + /opt/cloud/bin/passwd_server_ip $addr & +done; diff --git a/patches/systemvm/debian/config/opt/cloud/bin/passwd_server_ip b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server_ip new file mode 100755 index 00000000000..8d62dffa231 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server_ip @@ -0,0 +1,32 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +. /etc/default/cloud-passwd-srvr +addr=$1; +while [ "$ENABLED" == "1" ] +do + socat -lf /var/log/cloud.log TCP4-LISTEN:8080,reuseaddr,crnl,bind=$addr SYSTEM:"/opt/cloud/bin/serve_password.sh \"\$SOCAT_PEERADDR\"" + + rc=$? + if [ $rc -ne 0 ] + then + logger -t cloud "Password server failed with error code $rc. Restarting socat..." + sleep 3 + fi + . /etc/default/cloud-passwd-srvr +done diff --git a/patches/systemvm/debian/config/opt/cloud/bin/patchsystemvm.sh b/patches/systemvm/debian/config/opt/cloud/bin/patchsystemvm.sh index bdec43af1a9..3bbf7b1bf88 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/patchsystemvm.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/patchsystemvm.sh @@ -70,7 +70,6 @@ routing_svcs() { grep "redundant_router=1" /var/cache/cloud/cmdline > /dev/null RROUTER=$? chkconfig cloud off - chkconfig cloud-passwd-srvr on ; chkconfig haproxy on ; chkconfig ssh on chkconfig nfs-common off @@ -78,22 +77,38 @@ routing_svcs() { if [ $RROUTER -eq 0 ] then chkconfig dnsmasq off + chkconfig cloud-passwd-srvr off chkconfig keepalived on chkconfig conntrackd on chkconfig postinit on echo "keepalived conntrackd postinit" > /var/cache/cloud/enabled_svcs - echo "dnsmasq " > /var/cache/cloud/disabled_svcs + echo "dnsmasq cloud-passwd-srvr" > /var/cache/cloud/disabled_svcs else chkconfig dnsmasq on + chkconfig cloud-passwd-srvr on chkconfig keepalived off chkconfig conntrackd off - echo "dnsmasq " > /var/cache/cloud/enabled_svcs + echo "dnsmasq cloud-passwd-srvr " > /var/cache/cloud/enabled_svcs echo "keepalived conntrackd " > /var/cache/cloud/disabled_svcs fi - echo "cloud-passwd-srvr ssh haproxy apache2" >> /var/cache/cloud/enabled_svcs + echo "ssh haproxy apache2" >> /var/cache/cloud/enabled_svcs echo "cloud nfs-common portmap" > /var/cache/cloud/disabled_svcs } +vpcrouting_svcs() { + chkconfig cloud off + chkconfig haproxy on ; + chkconfig ssh on + chkconfig nfs-common off + chkconfig portmap off + chkconfig dnsmasq on + chkconfig keepalived off + chkconfig conntrackd off + chkconfig apache2 off + echo "ssh haproxy dnsmasq" > /var/cache/cloud/enabled_svcs + echo "cloud cloud-passwd-srvr apache2 nfs-common portmap keepalived conntrackd" > /var/cache/cloud/disabled_svcs +} + dhcpsrvr_svcs() { chkconfig cloud off chkconfig cloud-passwd-srvr on ; @@ -177,7 +192,7 @@ then enable_serial_console fi -if [ "$TYPE" == "router" ] +if [ "$TYPE" == "router" ] || [ "$TYPE" == "vpcrouter" ] then routing_svcs if [ $? -gt 0 ] @@ -187,6 +202,16 @@ then fi fi +if [ "$TYPE" == "vpcrouter" ] +then + vpcrouting_svcs + if [ $? -gt 0 ] + then + printf "Failed to execute vpcrouting_svcs\n" >$logfile + exit 6 + fi +fi + if [ "$TYPE" == "dhcpsrvr" ] then dhcpsrvr_svcs diff --git a/patches/systemvm/debian/config/opt/cloud/bin/serve_password.sh b/patches/systemvm/debian/config/opt/cloud/bin/serve_password.sh index c1f928ddcc8..b829b540666 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/serve_password.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/serve_password.sh @@ -20,6 +20,15 @@ # set -x +source /root/func.sh + +lock="passwdlock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + PASSWD_FILE=/var/cache/cloud/passwords # $1 filename @@ -91,4 +100,4 @@ fi # echo -e \"\\\"\\\n\\\"\" -exit 0 +unlock_exit 0 $lock $locked diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh index 7331c53ea67..faf62c6ff0c 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh @@ -48,7 +48,7 @@ destroy_acl_chain() { create_acl_chain() { destroy_acl_chain sudo iptables -t mangle -N ACL_OUTBOUND_$dev 2>/dev/null - sudo iptables -t mangle -A ACL_OUTBOUND_$dev -j DROP 2>/dev/null + sudo iptables -t mangle -A ACL_OUTBOUND_$dev -j ACCEPT 2>/dev/null sudo iptables -t mangle -A PREROUTING -m state --state NEW -i $dev -s $subnet/$mask ! -d $ip -j ACL_OUTBOUND_$dev 2>/dev/null sudo iptables -N ACL_INBOUND_$dev 2>/dev/null # drop if no rules match (this will be the last rule in the chain) @@ -66,6 +66,7 @@ setup_apache2() { sed -i -e "s/Listen .*:80/Listen $ip:80/g" /etc/apache2/conf.d/vhost$dev.conf sed -i -e "s/Listen .*:443/Listen $ip:443/g" /etc/apache2/conf.d/vhost$dev.conf service apache2 restart + sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT sudo iptables -A INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT } @@ -79,6 +80,11 @@ desetup_apache2() { setup_dnsmasq() { logger -t cloud "Setting up dnsmasq for network $ip/$mask " + # setup rules to allow dhcp/dns request + sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT + sudo iptables -D INPUT -i $dev -d $ip -p udp -m udp --dport 53 -j ACCEPT + sudo iptables -A INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT + sudo iptables -A INPUT -i $dev -d $ip -p udp -m udp --dport 53 -j ACCEPT # setup static sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf echo "dhcp-range=interface:$dev,set:interface-$dev,$ip,static" >> /etc/dnsmasq.d/cloud.conf @@ -89,11 +95,13 @@ setup_dnsmasq() { echo "dhcp-option=tag:interface-$dev,15,$DOMAIN" >> /etc/dnsmasq.d/cloud.conf service dnsmasq restart sleep 1 -} +} desetup_dnsmasq() { - logger -t cloud "Setting up dnsmasq for network $ip/$mask " - + logger -t cloud "Desetting up dnsmasq for network $ip/$mask " + # remove rules to allow dhcp/dns request + sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT + sudo iptables -D INPUT -i $dev -d $ip -p udp -m udp --dport 53 -j ACCEPT sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,option:router.*$/d" /etc/dnsmasq.d/cloud.conf sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,6.*$/d" /etc/dnsmasq.d/cloud.conf sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf @@ -101,45 +109,53 @@ desetup_dnsmasq() { sleep 1 } +setup_passwdsvcs() { + logger -t cloud "Setting up password service for network $ip/$mask, eth $dev " + sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 8080 -j ACCEPT + sudo iptables -A INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 8080 -j ACCEPT + nohup bash /opt/cloud/bin/vpc_passwd_server $ip >/dev/null 2>&1 & +} + +desetup_passwdsvcs() { + logger -t cloud "Desetting up password service for network $ip/$mask, eth $dev " + sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 8080 -j ACCEPT + pid=`ps -ef | grep socat | grep $ip | grep -v grep | awk '{print $2}'` + if [ -n "$pid" ] + then + kill -9 $pid + fi +} + create_guest_network() { logger -t cloud " $(basename $0): Create network on interface $dev, gateway $gw, network $ip/$mask " # setup ip configuration sudo ip addr add dev $dev $ip/$mask brd + sudo ip link set $dev up sudo arping -c 3 -I $dev -A -U -s $ip $ip - # setup rules to allow dhcp/dns request - sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT - sudo iptables -D INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT - sudo iptables -A INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT - sudo iptables -A INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT - sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 8080 -j ACCEPT - sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 80 -j ACCEPT - sudo iptables -A INPUT -i $dev -p tcp -m state --state NEW --dport 8080 -j ACCEPT - sudo iptables -A INPUT -i $dev -p tcp -m state --state NEW --dport 80 -j ACCEPT # restore mark from connection mark local tableName="Table_$dev" sudo ip route add $subnet/$mask dev $dev table $tableName proto static + sudo iptables -t mangle -D PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark + sudo iptables -t nat -D POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip sudo iptables -t mangle -A PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark # set up hairpin sudo iptables -t nat -A POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip create_acl_chain setup_dnsmasq setup_apache2 + setup_passwdsvcs } destroy_guest_network() { logger -t cloud " $(basename $0): Create network on interface $dev, gateway $gw, network $ip/$mask " sudo ip addr del dev $dev $ip/$mask - sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT - sudo iptables -D INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT - sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 8080 -j ACCEPT - sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 80 -j ACCEPT sudo iptables -t mangle -D PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark - sudo iptables -t nat -A POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip + sudo iptables -t nat -D POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip destroy_acl_chain desetup_dnsmasq desetup_apache2 + desetup_passwdsvcs } #set -x diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_passwd_server b/patches/systemvm/debian/config/opt/cloud/bin/vpc_passwd_server new file mode 100755 index 00000000000..6488bec86f4 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_passwd_server @@ -0,0 +1,32 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + + +ip=$1 +result=$ip +while [ -n "$result" ] +do + socat -lf /var/log/cloud.log TCP4-LISTEN:8080,reuseaddr,crnl,bind=$ip SYSTEM:"/opt/cloud/bin/serve_password.sh \"\$SOCAT_PEERADDR\"" + rc=$? + if [ $rc -ne 0 ] + then + logger -t cloud "Password server failed with error code $rc. Restarting socat..." + sleep 3 + fi + result=`ip addr show | grep $ip` +done diff --git a/patches/systemvm/debian/config/root/redundant_router/arping_gateways.sh.templ b/patches/systemvm/debian/config/root/redundant_router/arping_gateways.sh.templ index 80f7f030dcb..176bce22559 100644 --- a/patches/systemvm/debian/config/root/redundant_router/arping_gateways.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/arping_gateways.sh.templ @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + ip link|grep BROADCAST|grep -v eth0|grep -v eth1|cut -d ":" -f 2 > /tmp/iflist while read i do diff --git a/patches/systemvm/debian/config/root/redundant_router/backup.sh.templ b/patches/systemvm/debian/config/root/redundant_router/backup.sh.templ index 8378f64663d..03111b557a5 100644 --- a/patches/systemvm/debian/config/root/redundant_router/backup.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/backup.sh.templ @@ -1,4 +1,20 @@ #!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. source /root/func.sh diff --git a/patches/systemvm/debian/config/root/redundant_router/check_heartbeat.sh.templ b/patches/systemvm/debian/config/root/redundant_router/check_heartbeat.sh.templ index 26954650a6d..908c0d8f06f 100755 --- a/patches/systemvm/debian/config/root/redundant_router/check_heartbeat.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/check_heartbeat.sh.templ @@ -1,4 +1,21 @@ #!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + if [ -e [RROUTER_BIN_PATH]/keepalived.ts2 ] then diff --git a/patches/systemvm/debian/config/root/redundant_router/checkrouter.sh.templ b/patches/systemvm/debian/config/root/redundant_router/checkrouter.sh.templ index ae22ec7629d..fbf4f0f54d0 100755 --- a/patches/systemvm/debian/config/root/redundant_router/checkrouter.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/checkrouter.sh.templ @@ -1,4 +1,21 @@ #!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + source /root/func.sh diff --git a/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh b/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh index 84631f67951..af5edbfd2a1 100644 --- a/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh +++ b/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh @@ -21,4 +21,5 @@ while read i do ifconfig $i down done < /tmp/iflist +service cloud-passwd-srvr stop service dnsmasq stop diff --git a/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ b/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ index 32604954990..ccdef0b7ea6 100644 --- a/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ @@ -1,12 +1,35 @@ #!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. set -e ip link|grep BROADCAST|grep -v eth0|grep -v eth1|cut -d ":" -f 2 > /tmp/iflist while read i do - ifdown $i - ifup $i + if [ "$i" == "eth2" ] + then + ifdown $i + ifup $i + else + ifconfig $i down + ifconfig $i up + fi done < /tmp/iflist ip route add default via [GATEWAY] dev eth2 && \ +service cloud-passwd-srvr restart && \ service dnsmasq restart diff --git a/patches/systemvm/debian/config/root/redundant_router/fault.sh.templ b/patches/systemvm/debian/config/root/redundant_router/fault.sh.templ index 2305fb24c0a..aecb08db247 100644 --- a/patches/systemvm/debian/config/root/redundant_router/fault.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/fault.sh.templ @@ -1,4 +1,20 @@ #!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. source /root/func.sh diff --git a/patches/systemvm/debian/config/root/redundant_router/heartbeat.sh.templ b/patches/systemvm/debian/config/root/redundant_router/heartbeat.sh.templ index 90d790b5372..e064c1a2cf3 100755 --- a/patches/systemvm/debian/config/root/redundant_router/heartbeat.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/heartbeat.sh.templ @@ -1,4 +1,20 @@ #!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. t=$(date +%s) echo $t > [RROUTER_BIN_PATH]/keepalived.ts diff --git a/patches/systemvm/debian/config/root/redundant_router/keepalived.conf.templ b/patches/systemvm/debian/config/root/redundant_router/keepalived.conf.templ index fd7235f67e2..a4969a5b698 100644 --- a/patches/systemvm/debian/config/root/redundant_router/keepalived.conf.templ +++ b/patches/systemvm/debian/config/root/redundant_router/keepalived.conf.templ @@ -1,4 +1,19 @@ -! Configuration File for keepalived +! Licensed to the Apache Software Foundation (ASF) under one +! or more contributor license agreements. See the NOTICE file +! distributed with this work for additional information +! regarding copyright ownership. The ASF licenses this file +! to you 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. global_defs { router_id [ROUTER_ID] @@ -36,29 +51,7 @@ vrrp_instance inside_network { heartbeat } - #nopreempt - - # notify scripts and alerts are optional - # - # filenames of scripts to run on transitions - # can be unquoted (if just filename) - # or quoted (if has parameters) - # to MASTER transition notify_master "[RROUTER_BIN_PATH]/master.sh" - # to BACKUP transition notify_backup "[RROUTER_BIN_PATH]/backup.sh" - # FAULT transition notify_fault "[RROUTER_BIN_PATH]/fault.sh" - - # for ANY state transition. - # "notify" script is called AFTER the - # notify_* script(s) and is executed - # with 3 arguments provided by keepalived - # (ie don't include parameters in the notify line). - # arguments - # $1 = "GROUP"|"INSTANCE" - # $2 = name of group or instance - # $3 = target state of transition - # ("MASTER"|"BACKUP"|"FAULT") - #notify [RROUTER_BIN_PATH]/notify.sh } diff --git a/patches/systemvm/debian/config/root/redundant_router/master.sh.templ b/patches/systemvm/debian/config/root/redundant_router/master.sh.templ index c8d06374de2..418fd5d83b8 100644 --- a/patches/systemvm/debian/config/root/redundant_router/master.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/master.sh.templ @@ -1,4 +1,20 @@ #!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. source /root/func.sh diff --git a/patches/systemvm/debian/config/var/lib/misc/dnsmasq.leases b/patches/systemvm/debian/config/var/lib/misc/dnsmasq.leases deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/patches/systemvm/debian/vpn/etc/ipsec.conf b/patches/systemvm/debian/vpn/etc/ipsec.conf index a1c4bfb52b8..dc363b3a65f 100644 --- a/patches/systemvm/debian/vpn/etc/ipsec.conf +++ b/patches/systemvm/debian/vpn/etc/ipsec.conf @@ -1,50 +1,9 @@ -# /etc/ipsec.conf - Openswan IPsec configuration file - -# This file: /usr/share/doc/openswan/ipsec.conf-sample -# # Manual: ipsec.conf.5 +version 2.0 - -version 2.0 # conforms to second version of ipsec.conf specification - -# basic configuration config setup - # Do not set debug options to debug configuration issues! - # plutodebug / klipsdebug = "all", "none" or a combation from below: - # "raw crypt parsing emitting control klips pfkey natt x509 dpd private" - # eg: - # plutodebug="control parsing" - # - # enable to get logs per-peer - # plutoopts="--perpeerlog" - # - # Again: only enable plutodebug or klipsdebug when asked by a developer - # - # NAT-TRAVERSAL support, see README.NAT-Traversal nat_traversal=yes - # exclude networks used on server side by adding %v4:!a.b.c.0/24 virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12 - # OE is now off by default. Uncomment and change to on, to enable. - oe=off - # which IPsec stack to use. auto will try netkey, then klips then mast protostack=auto - -# Add connections here - -# sample VPN connection -# for more examples, see /etc/ipsec.d/examples/ -#conn sample -# # Left security gateway, subnet behind it, nexthop toward right. -# left=10.0.0.1 -# leftsubnet=172.16.0.0/24 -# leftnexthop=10.22.33.44 -# # Right security gateway, subnet behind it, nexthop toward left. -# right=10.12.12.1 -# rightsubnet=192.168.0.0/24 -# rightnexthop=10.101.102.103 -# # To authorize this connection, but not actually start it, -# # at startup, uncomment this. -# #auto=add - include /etc/ipsec.d/*.conf diff --git a/patches/systemvm/debian/vpn/etc/ipsec.conf.orig b/patches/systemvm/debian/vpn/etc/ipsec.conf.orig deleted file mode 100644 index d185e6cd502..00000000000 --- a/patches/systemvm/debian/vpn/etc/ipsec.conf.orig +++ /dev/null @@ -1,48 +0,0 @@ -# /etc/ipsec.conf - Openswan IPsec configuration file - -# This file: /usr/share/doc/openswan/ipsec.conf-sample -# -# Manual: ipsec.conf.5 - - -version 2.0 # conforms to second version of ipsec.conf specification - -# basic configuration -config setup - # Do not set debug options to debug configuration issues! - # plutodebug / klipsdebug = "all", "none" or a combation from below: - # "raw crypt parsing emitting control klips pfkey natt x509 dpd private" - # eg: - # plutodebug="control parsing" - # - # enable to get logs per-peer - # plutoopts="--perpeerlog" - # - # Again: only enable plutodebug or klipsdebug when asked by a developer - # - # NAT-TRAVERSAL support, see README.NAT-Traversal - nat_traversal=yes - # exclude networks used on server side by adding %v4:!a.b.c.0/24 - virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12 - # OE is now off by default. Uncomment and change to on, to enable. - oe=off - # which IPsec stack to use. auto will try netkey, then klips then mast - protostack=auto - - -# Add connections here - -# sample VPN connection -# for more examples, see /etc/ipsec.d/examples/ -#conn sample -# # Left security gateway, subnet behind it, nexthop toward right. -# left=10.0.0.1 -# leftsubnet=172.16.0.0/24 -# leftnexthop=10.22.33.44 -# # Right security gateway, subnet behind it, nexthop toward left. -# right=10.12.12.1 -# rightsubnet=192.168.0.0/24 -# rightnexthop=10.101.102.103 -# # To authorize this connection, but not actually start it, -# # at startup, uncomment this. -# #auto=add diff --git a/patches/systemvm/debian/vpn/etc/ipsec.secrets b/patches/systemvm/debian/vpn/etc/ipsec.secrets index 67ae69886cb..d9a9a43c747 100644 --- a/patches/systemvm/debian/vpn/etc/ipsec.secrets +++ b/patches/systemvm/debian/vpn/etc/ipsec.secrets @@ -1,12 +1,2 @@ -# RCSID $Id: ipsec.secrets.proto,v 1.3.6.1 2005/09/28 13:59:14 paul Exp $ -# This file holds shared secrets or RSA private keys for inter-Pluto -# authentication. See ipsec_pluto(8) manpage, and HTML documentation. - -# RSA private key for this host, authenticating it to any other host -# which knows the public part. Suitable public keys, for ipsec.conf, DNS, -# or configuration of other implementations, can be extracted conveniently -# with "ipsec showhostkey". - -# this file is managed with debconf and will contain the automatically created RSA keys include /var/lib/openswan/ipsec.secrets.inc include /etc/ipsec.d/ipsec.*.secrets diff --git a/patches/systemvm/debian/vpn/etc/ipsec.secrets.orig b/patches/systemvm/debian/vpn/etc/ipsec.secrets.orig deleted file mode 100644 index 6885545e8e8..00000000000 --- a/patches/systemvm/debian/vpn/etc/ipsec.secrets.orig +++ /dev/null @@ -1,11 +0,0 @@ -# RCSID $Id: ipsec.secrets.proto,v 1.3.6.1 2005/09/28 13:59:14 paul Exp $ -# This file holds shared secrets or RSA private keys for inter-Pluto -# authentication. See ipsec_pluto(8) manpage, and HTML documentation. - -# RSA private key for this host, authenticating it to any other host -# which knows the public part. Suitable public keys, for ipsec.conf, DNS, -# or configuration of other implementations, can be extracted conveniently -# with "ipsec showhostkey". - -# this file is managed with debconf and will contain the automatically created RSA keys -include /var/lib/openswan/ipsec.secrets.inc diff --git a/patches/systemvm/debian/vpn/etc/xl2tpd/xl2tpd.conf.orig b/patches/systemvm/debian/vpn/etc/xl2tpd/xl2tpd.conf.orig deleted file mode 100644 index 9f2f03a5048..00000000000 --- a/patches/systemvm/debian/vpn/etc/xl2tpd/xl2tpd.conf.orig +++ /dev/null @@ -1,76 +0,0 @@ -; -; Sample l2tpd configuration file -; -; This example file should give you some idea of how the options for l2tpd -; should work. The best place to look for a list of all options is in -; the source code itself, until I have the time to write better documetation :) -; Specifically, the file "file.c" contains a list of commands at the end. -; -; You most definitely don't have to spell out everything as it is done here -; -; [global] ; Global parameters: -; port = 1701 ; * Bind to port 1701 -; auth file = /etc/l2tpd/l2tp-secrets ; * Where our challenge secrets are -; access control = yes ; * Refuse connections without IP match -; rand source = dev ; Source for entropy for random -; ; numbers, options are: -; ; dev - reads of /dev/urandom -; ; sys - uses rand() -; ; egd - reads from egd socket -; ; egd is not yet implemented -; -; [lns default] ; Our fallthrough LNS definition -; exclusive = no ; * Only permit one tunnel per host -; ip range = 192.168.0.1-192.168.0.20 ; * Allocate from this IP range -; no ip range = 192.168.0.3-192.168.0.9 ; * Except these hosts -; ip range = 192.168.0.5 ; * But this one is okay -; ip range = lac1-lac2 ; * And anything from lac1 to lac2's IP -; lac = 192.168.1.4 - 192.168.1.8 ; * These can connect as LAC's -; no lac = untrusted.marko.net ; * This guy can't connect -; hidden bit = no ; * Use hidden AVP's? -; local ip = 192.168.1.2 ; * Our local IP to use -; length bit = yes ; * Use length bit in payload? -; require chap = yes ; * Require CHAP auth. by peer -; refuse pap = yes ; * Refuse PAP authentication -; refuse chap = no ; * Refuse CHAP authentication -; refuse authentication = no ; * Refuse authentication altogether -; require authentication = yes ; * Require peer to authenticate -; unix authentication = no ; * Use /etc/passwd for auth. -; name = myhostname ; * Report this as our hostname -; ppp debug = no ; * Turn on PPP debugging -; pppoptfile = /etc/ppp/options.l2tpd.lns ; * ppp options file -; call rws = 10 ; * RWS for call (-1 is valid) -; tunnel rws = 4 ; * RWS for tunnel (must be > 0) -; flow bit = yes ; * Include sequence numbers -; challenge = yes ; * Challenge authenticate peer ; -; rx bps = 10000000 ; Receive tunnel speed -; tx bps = 10000000 ; Transmit tunnel speed -; bps = 100000 ; Define both receive and transmit speed in one option - -; [lac marko] ; Example VPN LAC definition -; lns = lns.marko.net ; * Who is our LNS? -; lns = lns2.marko.net ; * A backup LNS (not yet used) -; redial = yes ; * Redial if disconnected? -; redial timeout = 15 ; * Wait n seconds between redials -; max redials = 5 ; * Give up after n consecutive failures -; hidden bit = yes ; * User hidden AVP's? -; local ip = 192.168.1.1 ; * Force peer to use this IP for us -; remote ip = 192.168.1.2 ; * Force peer to use this as their IP -; length bit = no ; * Use length bit in payload? -; require pap = no ; * Require PAP auth. by peer -; require chap = yes ; * Require CHAP auth. by peer -; refuse pap = yes ; * Refuse PAP authentication -; refuse chap = no ; * Refuse CHAP authentication -; refuse authentication = no ; * Refuse authentication altogether -; require authentication = yes ; * Require peer to authenticate -; name = marko ; * Report this as our hostname -; ppp debug = no ; * Turn on PPP debugging -; pppoptfile = /etc/ppp/options.l2tpd.marko ; * ppp options file for this lac -; call rws = 10 ; * RWS for call (-1 is valid) -; tunnel rws = 4 ; * RWS for tunnel (must be > 0) -; flow bit = yes ; * Include sequence numbers -; challenge = yes ; * Challenge authenticate peer -; -; [lac cisco] ; Another quick LAC -; lns = cisco.marko.net ; * Required, but can take from default -; require authentication = yes diff --git a/patches/systemvm/debian/xe/xe-linux-distribution.init b/patches/systemvm/debian/xe/xe-linux-distribution.init deleted file mode 100644 index df6c8455213..00000000000 --- a/patches/systemvm/debian/xe/xe-linux-distribution.init +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash -# -# xe-linux-distribution Write Linux distribution information to XenStore. -# -# chkconfig: 2345 14 86 -# description: Writes Linux distribution version information to XenStore. -# -### BEGIN INIT INFO -# Provides: XenServer Virtual Machine Tools -# Required-Start: $local_fs -# Required-Stop: $local_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: XenServer Virtual Machine daemon providing host integration services -# Description: Writes Linux distribution version information to XenStore. -### END INIT INFO - -LANG="C" -export LANG - -if [ -f /etc/init.d/functions ] ; then -. /etc/init.d/functions -else -action() -{ - descr=$1 ; shift - cmd=$@ - echo -n "$descr " - $cmd - ret=$? - if [ $ret -eq 0 ] ; then - echo "OK" - else - echo "Failed" - fi - return $ret -} -fi - -XE_LINUX_DISTRIBUTION=/usr/sbin/xe-linux-distribution -XE_LINUX_DISTRIBUTION_CACHE=/var/cache/xe-linux-distribution -XE_DAEMON=/usr/sbin/xe-daemon -XE_DAEMON_PIDFILE=/var/run/xe-daemon.pid - -if [ ! -x "${XE_LINUX_DISTRIBUTION}" ] ; then - exit 0 -fi - -start() -{ - if [ ! -e /proc/xen/xenbus ] ; then - if [ ! -d /proc/xen ] ; then - action $"Mounting xenfs on /proc/xen:" /bin/false - echo "Could not find /proc/xen directory." - echo "You need a post 2.6.29-rc1 kernel with CONFIG_XEN_COMPAT_XENFS=y and CONFIG_XENFS=y|m" - exit 1 - else - # This is needed post 2.6.29-rc1 when /proc/xen support was pushed upstream as a xen filesystem - action $"Mounting xenfs on /proc/xen:" mount -t xenfs none /proc/xen - fi - fi - - if [ -e /proc/xen/capabilities ] && grep -q control_d /proc/xen/capabilities ; then - # Do not want daemon in domain 0 - exit 0 - fi - - action $"Detecting Linux distribution version:" \ - ${XE_LINUX_DISTRIBUTION} ${XE_LINUX_DISTRIBUTION_CACHE} - - action $"Starting xe daemon: " /bin/true - mkdir -p $(dirname ${XE_DAEMON_PIDFILE}) - # This is equivalent to daemon() in C - ( exec &>/dev/null ; ${XE_DAEMON} -p ${XE_DAEMON_PIDFILE} & ) -} - -stop() -{ - action $"Stopping xe daemon: " kill -TERM $(cat ${XE_DAEMON_PIDFILE}) -} - -# fail silently if not running xen -if [ ! -d /proc/xen ]; then - exit -fi - -case "$1" in - start) - start - ;; - stop) - stop - ;; - force-reload|restart) - stop - start - ;; - *) - # do not advertise unreasonable commands that there is no reason - # to use with this device - echo $"Usage: $0 start|restart" - exit 1 -esac - -exit $? - diff --git a/patches/systemvm/debian/xe/xen-vcpu-hotplug.rules b/patches/systemvm/debian/xe/xen-vcpu-hotplug.rules deleted file mode 100644 index ecb200e2201..00000000000 --- a/patches/systemvm/debian/xe/xen-vcpu-hotplug.rules +++ /dev/null @@ -1 +0,0 @@ -ACTION=="add", SUBSYSTEM=="cpu", RUN+="/bin/sh -c '[ ! -e /sys$devpath/online ] || echo 1 > /sys$devpath/online'" diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index ca2fae143ab..78829356170 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-planner-user-concentrated-pod Apache CloudStack Plugin - User Concentrated Pod Deployment Planner org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index 6e1ffc6f026..33f6582e72f 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-planner-user-dispersing Apache CloudStack Plugin - User Dispersing Deployment Planner org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/file-systems/netapp/pom.xml b/plugins/file-systems/netapp/pom.xml index f10e5a4a499..e1c8866d15d 100644 --- a/plugins/file-systems/netapp/pom.xml +++ b/plugins/file-systems/netapp/pom.xml @@ -16,22 +16,21 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-netapp Apache CloudStack Plugin - NetApp File System org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml com.cloud.com.netapp manageontap - 1.0 + 4.0 diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index ad66c0e0af0..ba7e1ae1e65 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-host-allocator-random Apache CloudStack Plugin - Host Allocator Random org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/kvm/agent-descriptor.xml b/plugins/hypervisors/kvm/agent-descriptor.xml new file mode 100644 index 00000000000..51024a879ef --- /dev/null +++ b/plugins/hypervisors/kvm/agent-descriptor.xml @@ -0,0 +1,68 @@ + + + kvm-agent + + zip + + yes + + + + + + + + + ../../../agent/scripts + + 774 + + run.sh + _run.sh + agent.sh + + + + target + + 555 + + cloud-plugin-hypervisor-kvm-*.jar + + + + ../../../scripts + scripts + 555 + + + ../../../agent/conf + conf + 555 + 774 + + agent.properties + log4j-cloud.xml + + + + diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 48630856769..d3eca911a04 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-hypervisor-kvm Apache CloudStack Plugin - Hypervisor KVM org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml @@ -45,4 +44,56 @@ 0.4.9
+ + install + src + test + + + maven-assembly-plugin + 2.3 + + kvm-agent + false + + agent-descriptor.xml + + + + + make-agent + package + + single + + + + + + maven-resources-plugin + 2.6 + + + copy-resources + + package + + copy-resources + + + dist + + + target + + kvm-agent.zip + + + + + + + + +
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java index cf4de095cf7..116c09d3807 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java @@ -85,11 +85,18 @@ public class BridgeVifDriver extends VifDriverBase { URI broadcastUri = nic.getBroadcastUri(); vlanId = broadcastUri.getHost(); } + String trafficLabel = nic.getName(); if (nic.getType() == Networks.TrafficType.Guest) { if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { - String brName = createVlanBr(vlanId, _pifs.get("private")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + if(trafficLabel != null || !trafficLabel.isEmpty()) { + s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel); + String brName = createVlanBr(vlanId, _pifs.get(trafficLabel)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } else { + String brName = createVlanBr(vlanId, _pifs.get("private")); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } } else { intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType)); } @@ -100,8 +107,14 @@ public class BridgeVifDriver extends VifDriverBase { } else if (nic.getType() == Networks.TrafficType.Public) { if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { - String brName = createVlanBr(vlanId, _pifs.get("public")); - intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + if(trafficLabel != null || !trafficLabel.isEmpty()){ + s_logger.debug("creating a vlan dev and bridge for public traffic per traffic label " + trafficLabel); + String brName = createVlanBr(vlanId, _pifs.get(trafficLabel)); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } else { + String brName = createVlanBr(vlanId, _pifs.get("public")); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType)); + } } else { intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType)); } @@ -120,22 +133,32 @@ public class BridgeVifDriver extends VifDriverBase { // Nothing needed as libvirt cleans up tap interface from bridge. } - private String setVnetBrName(String vnetId) { - return "cloudVirBr" + vnetId; + private String setVnetBrName(String pifName, String vnetId) { + String brName = "br" + pifName + "-"+ vnetId; + String oldStyleBrName = "cloudVirBr" + vnetId; + + String cmdout = Script.runSimpleBashScript("brctl show | grep " + oldStyleBrName); + if (cmdout != null && cmdout.contains(oldStyleBrName)) { + s_logger.info("Using old style bridge name for vlan " + vnetId + " because existing bridge " + oldStyleBrName + " was found"); + brName = oldStyleBrName; + } + + return brName; } private String createVlanBr(String vlanId, String nic) throws InternalErrorException { - String brName = setVnetBrName(vlanId); - createVnet(vlanId, nic); + String brName = setVnetBrName(nic, vlanId); + createVnet(vlanId, nic, brName); return brName; } - private void createVnet(String vnetId, String pif) + private void createVnet(String vnetId, String pif, String brName) throws InternalErrorException { final Script command = new Script(_modifyVlanPath, _timeout, s_logger); command.add("-v", vnetId); command.add("-p", pif); + command.add("-b", brName); command.add("-o", "add"); final String result = command.execute(); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java index 88bb0f5f060..b4771cacb10 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/KVMGuestOsMapper.java @@ -105,7 +105,7 @@ public class KVMGuestOsMapper { s_mapper.put("Ubuntu 8.04 (64-bit)", "Other Linux"); s_mapper.put("Debian GNU/Linux 5(32-bit)", "Debian GNU/Linux 5"); s_mapper.put("Debian GNU/Linux 5(64-bit)", "Debian GNU/Linux 5"); - s_mapper.put("Debian GNU/Linux 5.0(32-bit)", "Debian GNU/Linux 5"); + s_mapper.put("Debian GNU/Linux 5.0 (32-bit)", "Debian GNU/Linux 5"); s_mapper.put("Debian GNU/Linux 4(32-bit)", "Debian GNU/Linux 4"); s_mapper.put("Debian GNU/Linux 4(64-bit)", "Debian GNU/Linux 4"); s_mapper.put("Debian GNU/Linux 6(64-bit)", "Debian GNU/Linux 6"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 65742d8a784..c783daa5947 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -44,6 +44,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.regex.Pattern; +import java.util.regex.Matcher; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -681,7 +683,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements _sysvmISOPath = (String) params.get("systemvm.iso.path"); if (_sysvmISOPath == null) { String[] isoPaths = { "/usr/lib64/cloud/agent/vms/systemvm.iso", - "/usr/lib/cloud/agent/vms/systemvm.iso" }; + "/usr/lib/cloud/agent/vms/systemvm.iso", + "/usr/lib64/cloud/common/vms/systemvm.iso", + "/usr/lib/cloud/common/vms/systemvm.iso" }; for (String isoPath : isoPaths) { if (_storage.exists(isoPath)) { _sysvmISOPath = isoPath; @@ -775,32 +779,33 @@ public class LibvirtComputingResource extends ServerResourceBase implements } private void getPifs() { - /* get pifs from bridge */ - String pubPif = null; - String privPif = null; - String vlan = null; - if (_publicBridgeName != null) { - pubPif = Script.runSimpleBashScript("brctl show | grep " - + _publicBridgeName + " | awk '{print $4}'"); - vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + pubPif); - if (vlan != null && !vlan.isEmpty()) { - pubPif = Script - .runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" - + pubPif + " | awk {'print $2'}"); + /* gather all available bridges and find their pifs, so that we can match them against traffic labels later */ + String cmdout = Script.runSimpleBashScript("brctl show | tail -n +2 | grep -v \"^\\s\"|awk '{print $1}'|sed '{:q;N;s/\\n/%/g;t q}'"); + s_logger.debug("cmdout was " + cmdout); + List bridges = Arrays.asList(cmdout.split("%")); + for (String bridge : bridges) { + s_logger.debug("looking for pif for bridge " + bridge); + String pif = getPif(bridge); + if(_publicBridgeName != null && bridge.equals(_publicBridgeName)){ + _pifs.put("public", pif); } - } - if (_guestBridgeName != null) { - privPif = Script.runSimpleBashScript("brctl show | grep " - + _guestBridgeName + " | awk '{print $4}'"); - vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + privPif); - if (vlan != null && !vlan.isEmpty()) { - privPif = Script - .runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" - + privPif + " | awk {'print $2'}"); + if (_guestBridgeName != null && bridge.equals(_guestBridgeName)) { + _pifs.put("private", pif); } + _pifs.put(bridge, pif); } - _pifs.put("private", privPif); - _pifs.put("public", pubPif); + s_logger.debug("done looking for pifs, no more bridges"); + } + + private String getPif(String bridge) { + String pif = Script.runSimpleBashScript("brctl show | grep " + bridge + " | awk '{print $4}'"); + String vlan = Script.runSimpleBashScript("ls /proc/net/vlan/" + pif); + + if (vlan != null && !vlan.isEmpty()) { + pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}"); + } + + return pif; } private boolean checkNetwork(String networkName) { @@ -2316,12 +2321,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements _vms.put(vmName, State.Stopping); } + List ifaces = null; + Domain dm = null; Connect dconn = null; Domain destDomain = null; Connect conn = null; try { conn = LibvirtConnection.getConnection(); + ifaces = getInterfaces(conn, vmName); dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName .getBytes())); dconn = new Connect("qemu+tcp://" + cmd.getDestinationIp() @@ -2360,6 +2368,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements } } else { destroy_network_rules_for_vm(conn, vmName); + for (InterfaceDef iface : ifaces) { + _vifDriver.unplug(iface); + } cleanupVM(conn, vmName, getVnetId(VirtualMachineName.getVnet(vmName))); } @@ -2580,6 +2591,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Connect conn = LibvirtConnection.getConnection(); List disks = getDisks(conn, vmName); + List ifaces = getInterfaces(conn, vmName); + destroy_network_rules_for_vm(conn, vmName); String result = stopVM(conn, vmName, defineOps.UNDEFINE_VM); if (result == null) { @@ -2595,11 +2608,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements } } } - } - - List ifaces = getInterfaces(conn, vmName); - for(InterfaceDef iface: ifaces){ - _vifDriver.unplug(iface); + for (InterfaceDef iface: ifaces) { + _vifDriver.unplug(iface); + } } final String result2 = cleanupVnet(conn, cmd.getVnet()); @@ -2626,11 +2637,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements File sshKeysDir = new File(_SSHKEYSPATH); String result = null; if (!sshKeysDir.exists()) { - sshKeysDir.mkdir(); // Change permissions for the 700 - Script script = new Script("chmod", _timeout, s_logger); - script.add("700", _SSHKEYSPATH); + Script script = new Script("mkdir", _timeout, s_logger); + script.add("-m","700"); + script.add(_SSHKEYSPATH); script.execute(); + + if(!sshKeysDir.exists()) { + s_logger.debug("failed to create directory " + _SSHKEYSPATH); + } } File pubKeyFile = new File(_SSHPUBKEYPATH); @@ -3908,7 +3923,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements } private String getVnetIdFromBrName(String vnetBrName) { - return vnetBrName.replaceAll("cloudVirBr", ""); + if (vnetBrName.contains("cloudVirBr")) { + return vnetBrName.replaceAll("cloudVirBr", ""); + } else { + Pattern r = Pattern.compile("-(\\d+)$"); + Matcher m = r.matcher(vnetBrName); + if(m.group(1) != null || !m.group(1).isEmpty()) { + return m.group(1); + } else { + s_logger.debug("unable to get a vlan ID from name " + vnetBrName); + return ""; + } + } } private void cleanupVMNetworks(Connect conn, List nics) { @@ -4285,7 +4311,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements /* online snapshot supported by enhanced qemu-kvm */ private boolean isSnapshotSupported() { - String result = executeBashScript("qemu-img --help|grep convert |grep snapshot"); + String result = executeBashScript("qemu-img --help|grep convert"); if (result != null) { return false; } else { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java index 8246a5c8c81..2c0e0ac9b6f 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java @@ -49,7 +49,7 @@ public class KVMStoragePoolManager { } public KVMStoragePool getStoragePoolByURI(String uri) { - return this._storageAdaptor.getStoragePoolByUri(uri); + return this._storageAdaptor.getStoragePoolByURI(uri); } public KVMStoragePool createStoragePool(String name, String host, int port, String path, diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index d6236a0d603..6c55743696d 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -101,81 +101,6 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { return pool.storageVolCreateXML(volDef.toString(), 0); } - public StoragePool getStoragePoolbyURI(Connect conn, URI uri) - throws LibvirtException { - String sourcePath; - String uuid; - String sourceHost = ""; - String protocal; - if (uri.getScheme().equalsIgnoreCase("local")) { - sourcePath = _mountPoint + File.separator - + uri.toString().replace("local:///", ""); - sourcePath = sourcePath.replace("//", "/"); - uuid = UUID.nameUUIDFromBytes(new String(sourcePath).getBytes()) - .toString(); - protocal = "DIR"; - } else { - sourcePath = uri.getPath(); - sourcePath = sourcePath.replace("//", "/"); - sourceHost = uri.getHost(); - uuid = UUID.nameUUIDFromBytes( - new String(sourceHost + sourcePath).getBytes()).toString(); - protocal = "NFS"; - } - - String targetPath = _mountPoint + File.separator + uuid; - StoragePool sp = null; - try { - sp = conn.storagePoolLookupByUUIDString(uuid); - } catch (LibvirtException e) { - } - - if (sp == null) { - try { - LibvirtStoragePoolDef spd = null; - if (protocal.equalsIgnoreCase("NFS")) { - _storageLayer.mkdir(targetPath); - spd = new LibvirtStoragePoolDef(poolType.NETFS, uuid, uuid, - sourceHost, sourcePath, targetPath); - s_logger.debug(spd.toString()); - // addStoragePool(uuid); - - } else if (protocal.equalsIgnoreCase("DIR")) { - _storageLayer.mkdir(targetPath); - spd = new LibvirtStoragePoolDef(poolType.DIR, uuid, uuid, - null, null, sourcePath); - } - - synchronized (getStoragePool(uuid)) { - sp = conn.storagePoolDefineXML(spd.toString(), 0); - if (sp == null) { - s_logger.debug("Failed to define storage pool"); - return null; - } - sp.create(0); - } - - return sp; - } catch (LibvirtException e) { - try { - if (sp != null) { - sp.undefine(); - sp.free(); - } - } catch (LibvirtException l) { - - } - throw e; - } - } else { - StoragePoolInfo spi = sp.getInfo(); - if (spi.state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) { - sp.create(0); - } - return sp; - } - } - public void storagePoolRefresh(StoragePool pool) { try { synchronized (getStoragePool(pool.getUUIDString())) { @@ -199,7 +124,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { sp.create(0); return sp; } catch (LibvirtException e) { - s_logger.debug(e.toString()); + s_logger.error(e.toString()); if (sp != null) { try { sp.undefine(); @@ -213,10 +138,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } } - private StoragePool CreateSharedStoragePool(Connect conn, String uuid, + private StoragePool createSharedStoragePool(Connect conn, String uuid, String host, String path) { String mountPoint = path; if (!_storageLayer.exists(mountPoint)) { + s_logger.error(mountPoint + " does not exists. Check local.storage.path in agent.properties."); return null; } LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(poolType.DIR, @@ -229,7 +155,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { return sp; } catch (LibvirtException e) { - s_logger.debug(e.toString()); + s_logger.error(e.toString()); if (sp != null) { try { sp.undefine(); @@ -259,7 +185,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { sp.create(0); return sp; } catch (LibvirtException e) { - s_logger.debug(e.toString()); + s_logger.error(e.toString()); if (sp != null) { try { sp.undefine(); @@ -286,14 +212,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { Secret s = null; - sd.setCephName(userInfoTemp[0]); + sd.setCephName(userInfoTemp[0] + "@" + host + ":" + port + "/" + path); try { s_logger.debug(sd.toString()); s = conn.secretDefineXML(sd.toString()); s.setValue(Base64.decodeBase64(userInfoTemp[1])); } catch (LibvirtException e) { - s_logger.debug(e.toString()); + s_logger.error(e.toString()); if (s != null) { try { s.undefine(); @@ -367,32 +293,6 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { return parser.parseStorageVolumeXML(volDefXML); } - public StorageVol getVolumeFromURI(Connect conn, String volPath) - throws LibvirtException, URISyntaxException { - int index = volPath.lastIndexOf("/"); - URI volDir = null; - StoragePool sp = null; - StorageVol vol = null; - try { - volDir = new URI(volPath.substring(0, index)); - String volName = volPath.substring(index + 1); - sp = getStoragePoolbyURI(conn, volDir); - vol = sp.storageVolLookupByName(volName); - return vol; - } catch (LibvirtException e) { - s_logger.debug("Faild to get vol path: " + e.toString()); - throw e; - } finally { - try { - if (sp != null) { - sp.free(); - } - } catch (LibvirtException e) { - - } - } - } - public StoragePool createFileBasedStoragePool(Connect conn, String localStoragePath, String uuid) { if (!(_storageLayer.exists(localStoragePath) && _storageLayer @@ -550,7 +450,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { sp = createNfsStoragePool(conn, name, host, path); } else if (type == StoragePoolType.SharedMountPoint || type == StoragePoolType.Filesystem) { - sp = CreateSharedStoragePool(conn, name, host, path); + sp = createSharedStoragePool(conn, name, host, path); } else if (type == StoragePoolType.RBD) { sp = createRBDStoragePool(conn, name, host, port, userInfo, path); } else if (type == StoragePoolType.CLVM) { @@ -820,7 +720,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } @Override - public KVMStoragePool getStoragePoolByUri(String uri) { + public KVMStoragePool getStoragePoolByURI(String uri) { URI storageUri = null; try { @@ -837,11 +737,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { sourcePath = storageUri.getPath(); sourcePath = sourcePath.replace("//", "/"); sourceHost = storageUri.getHost(); - uuid = UUID.randomUUID().toString(); + uuid = UUID.nameUUIDFromBytes( + new String(sourceHost + sourcePath).getBytes()).toString(); protocal = StoragePoolType.NetworkFilesystem; } - return createStoragePool(uuid, sourceHost, 0, sourcePath, "", protocal); + return createStoragePool(uuid, sourceHost, 0, sourcePath, "", protocal); } @Override diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java index ec103322cf1..ef1e7c9302a 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java @@ -55,7 +55,7 @@ public interface StorageAdaptor { public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName, String name, KVMStoragePool destPool); - public KVMStoragePool getStoragePoolByUri(String uri); + public KVMStoragePool getStoragePoolByURI(String uri); public KVMPhysicalDisk getPhysicalDiskFromURI(String uri); diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index a8b23d0b943..5700c14d4eb 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -16,15 +16,21 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-hypervisor-ovm Apache CloudStack Plugin - Hypervisor OracleVM org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml + + + org.apache.cloudstack + xapi + ${cs.xapi.version} + + diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index 435ae38b847..0aa6340c866 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-hypervisor-vmware Apache CloudStack Plugin - Hypervisor VMware org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml @@ -33,5 +32,38 @@ cloud-vmware-base ${project.version} + + com.cloud.com.vmware + vmware-vim25 + ${cs.vmware.api.version} + provided + + + com.cloud.com.vmware + vmware-vim + ${cs.vmware.api.version} + provided + + + com.cloud.com.vmware + vmware-apputils + ${cs.vmware.api.version} + provided + + + org.apache.axis + axis + ${cs.axis.version} + + + org.apache.axis + axis-jaxrpc + ${cs.axis.version} + + + wsdl4j + wsdl4j + 1.4 + diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 205fb26f09d..64ded51b453 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -230,25 +230,31 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis _privateNetworkVSwitchName = configDao.getValue(Config.VmwarePrivateNetworkVSwitch.key()); if (_privateNetworkVSwitchName == null) { - _privateNetworkVSwitchName = "vSwitch0"; - } else { - _privateNetworkVSwitchName = "privateEthernetPortProfile"; + if (_nexusVSwitchActive) { + _privateNetworkVSwitchName = "privateEthernetPortProfile"; + } else { + _privateNetworkVSwitchName = "vSwitch0"; + } } _publicNetworkVSwitchName = configDao.getValue(Config.VmwarePublicNetworkVSwitch.key()); if (_publicNetworkVSwitchName == null) { - _publicNetworkVSwitchName = "vSwitch0"; - } else { - _publicNetworkVSwitchName = "publicEthernetPortProfile"; + if (_nexusVSwitchActive) { + _publicNetworkVSwitchName = "publicEthernetPortProfile"; + } else { + _publicNetworkVSwitchName = "vSwitch0"; + } } _guestNetworkVSwitchName = configDao.getValue(Config.VmwareGuestNetworkVSwitch.key()); if (_guestNetworkVSwitchName == null) { - _guestNetworkVSwitchName = "vSwitch0"; - } else { - _guestNetworkVSwitchName = "guestEthernetPortProfile"; + if (_nexusVSwitchActive) { + _guestNetworkVSwitchName = "guestEthernetPortProfile"; + } else { + _guestNetworkVSwitchName = "vSwitch0"; + } } _serviceConsoleName = configDao.getValue(Config.VmwareServiceConsole.key()); @@ -658,9 +664,9 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis File file = new File(url.getFile()); File isoFile = new File(file.getParent() + "/vms/systemvm.iso"); if (!isoFile.exists()) { - isoFile = new File("/usr/lib64/cloud/agent/" + "/vms/systemvm.iso"); + isoFile = new File("/usr/lib64/cloud/common/" + "/vms/systemvm.iso"); if (!isoFile.exists()) { - isoFile = new File("/usr/lib/cloud/agent/" + "/vms/systemvm.iso"); + isoFile = new File("/usr/lib/cloud/common/" + "/vms/systemvm.iso"); } } return isoFile; @@ -673,9 +679,9 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis File keyFile = new File(file.getParent(), "/scripts/vm/systemvm/id_rsa.cloud"); if (!keyFile.exists()) { - keyFile = new File("/usr/lib64/cloud/agent" + "/scripts/vm/systemvm/id_rsa.cloud"); + keyFile = new File("/usr/lib64/cloud/common" + "/scripts/vm/systemvm/id_rsa.cloud"); if (!keyFile.exists()) { - keyFile = new File("/usr/lib/cloud/agent" + "/scripts/vm/systemvm/id_rsa.cloud"); + keyFile = new File("/usr/lib/cloud/common" + "/scripts/vm/systemvm/id_rsa.cloud"); } } return keyFile; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 1fa14fa1e5b..0b0f285a960 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -250,9 +250,6 @@ import com.vmware.vim25.VirtualMachineGuestOsIdentifier; import com.vmware.vim25.VirtualMachinePowerState; import com.vmware.vim25.VirtualMachineRuntimeInfo; import com.vmware.vim25.VirtualSCSISharing; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.VIF; -import com.xensource.xenapi.VM; public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService { private static final Logger s_logger = Logger.getLogger(VmwareResource.class); @@ -936,7 +933,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, nic.getMac()); s_logger.info("find interface index. routerIp: " + routerIp + ", mac: " + nic.getMac() + ", index: " + ethDeviceNum); - String args = "-C "; + String args =(cmd.isAdd()?"-C":"-D"); String dev = "eth" + ethDeviceNum; args += " -d " + dev; args += " -i " + domrGIP; @@ -4558,12 +4555,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa try { if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /root/netusage.sh " + args + " on DomR " + privateIpAddress); + s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress); } VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/root/netusage.sh " + args); + Pair result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args); if (!result.first()) { return null; diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java b/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java index 80c8ecfe9bb..bdb235dc761 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java +++ b/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java @@ -110,7 +110,7 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme } @Override - public boolean destroy(Network network) + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java index fce66a97539..fc298c895c8 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageContextFactory.java @@ -17,6 +17,7 @@ package com.cloud.storage.resource; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import com.cloud.hypervisor.vmware.util.VmwareContext; @@ -60,10 +61,11 @@ public class VmwareSecondaryStorageContextFactory { public static void invalidate(VmwareContext context) { synchronized(s_contextMap) { - for(Map.Entry entry : s_contextMap.entrySet()) { - if(entry.getValue() == context) { - s_contextMap.remove(entry.getKey()); - } + for(Iterator> entryIter = s_contextMap.entrySet().iterator(); entryIter.hasNext();) { + Map.Entry entry = entryIter.next(); + if(entry.getValue() == context) { + entryIter.remove(); + } } } diff --git a/plugins/hypervisors/xen/pom.xml b/plugins/hypervisors/xen/pom.xml index bf38e47adfa..959c972e080 100644 --- a/plugins/hypervisors/xen/pom.xml +++ b/plugins/hypervisors/xen/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-hypervisor-xen Apache CloudStack Plugin - Hypervisor Xen org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml @@ -33,5 +32,16 @@ cloud-plugin-network-ovs ${project.version} + + org.apache.cloudstack + xapi + ${cs.xapi.version} + + + junit + junit + + + diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 5c4db2b45fb..d2db85c8597 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -7359,7 +7359,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new SetupGuestNetworkAnswer(cmd, false, "Can not find vif with mac " + mac + " for VM " + domrName); } - String args = "vpc_guestnw.sh " + domrIP + " -C"; + String args = "vpc_guestnw.sh " + domrIP + (cmd.isAdd()?" -C":" -D"); String dev = "eth" + domrVif.getDevice(conn); args += " -d " + dev; args += " -i " + domrGIP; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java index d4260c72930..0a1064707b1 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java @@ -74,7 +74,11 @@ public class XcpOssResource extends CitrixResourceBase { @Override protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXcpGuestOsType(stdType); + if (stdType.equalsIgnoreCase("Debian GNU/Linux 6(64-bit)")) { + return "Debian Squeeze 6.0 (64-bit)"; + } else { + return CitrixHelper.getXcpGuestOsType(stdType); + } } protected VBD createPatchVbd(Connection conn, String vmName, VM vm) throws XmlRpcException, XenAPIException { diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index c1ab2c56664..dac500d8fd2 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-network-elb Apache CloudStack Plugin - Network Elastic Load Balancer org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/element/ElasticLoadBalancerElement.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/element/ElasticLoadBalancerElement.java index 8490534f613..34cbe086452 100644 --- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/element/ElasticLoadBalancerElement.java +++ b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/element/ElasticLoadBalancerElement.java @@ -125,7 +125,7 @@ public class ElasticLoadBalancerElement extends AdapterBase implements LoadBalan } @Override - public boolean destroy(Network network) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { // TODO kill all loadbalancer vms by calling the ElasticLoadBalancerManager return false; } diff --git a/plugins/network-elements/f5/pom.xml b/plugins/network-elements/f5/pom.xml index 0cba48cdfcf..bf40332cfbb 100644 --- a/plugins/network-elements/f5/pom.xml +++ b/plugins/network-elements/f5/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-network-f5 Apache CloudStack Plugin - F5 org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java b/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java index 13967e3bcba..00114f2575f 100644 --- a/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java +++ b/plugins/network-elements/f5/src/com/cloud/network/element/F5ExternalLoadBalancerElement.java @@ -166,7 +166,7 @@ public class F5ExternalLoadBalancerElement extends ExternalLoadBalancerDeviceMan } @Override - public boolean destroy(Network config) { + public boolean destroy(Network config, ReservationContext context) { return true; } diff --git a/plugins/network-elements/juniper-srx/pom.xml b/plugins/network-elements/juniper-srx/pom.xml index 38a2b550c7e..6040720da6e 100644 --- a/plugins/network-elements/juniper-srx/pom.xml +++ b/plugins/network-elements/juniper-srx/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-network-srx Apache CloudStack Plugin - Juniper SRX org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java b/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java index cd4a0749a35..6e815476804 100644 --- a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java +++ b/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java @@ -203,7 +203,7 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan } @Override - public boolean destroy(Network config) { + public boolean destroy(Network config, ReservationContext context) { return true; } diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index 377e6e0f228..b11009d8b1a 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-network-netscaler Apache CloudStack Plugin - Network Netscaler org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index 77aa4477d5a..7c51ff79135 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -209,7 +209,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } @Override - public boolean destroy(Network config) { + public boolean destroy(Network config, ReservationContext context) { return true; } diff --git a/plugins/network-elements/nicira-nvp/README.NiciraIntegration b/plugins/network-elements/nicira-nvp/README.NiciraIntegration deleted file mode 100644 index 4019c17f9fe..00000000000 --- a/plugins/network-elements/nicira-nvp/README.NiciraIntegration +++ /dev/null @@ -1,87 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. ------------------------------------------------------------ - - -Nicira Network Virtualization Platform (NVP) integration code is contributed -by Nicira and Schuberg Philis and copyright is donated to the Apache Software -Foundation. - -Authors - Somik Behera - Hugo Trippaers - -== New API Calls - -The following API calls are added to CloudStack to support the integrations with -the Nicira NVP platform. Please see the API documentation of CloudStack for -parameters and return values. - - * addNiciraNvpDevice - * deleteNiciraNvpDevice - * listNiciraNvpDevices - * listNiciraNvpDeviceNetworks - -== How to enable the Nicira NVP integration. - -When configuring a zone create a new physical network for "Guest" traffic and -select "STT" as the isolation type. Set the Xen traffic label for "Guest" -traffic to the label of the integration bridge (refer to the Nicira -Documentation for setting up the integration bridge). Note that this requires -all traffic types to have their traffic labels set. - -These steps are specified by the API calls as there is currently no GUI -available. - -1. addNetworkServiceProvider - name="NiciraNvp", physicalnetworkid=, - servicelist="Connectivity" -2. updateNetworkServiceProvider - id=, state="Enabled" -3. addNiciraNvpDevice - physicalnetworkid=, - hostname= - username= - password= - transportzoneuuid= - -== How to use the Nicira integration - -When creating a guest network make sure it is created in the physical network -with the isolation type set to "STT". When the first virtual machine is -launched in this network the NiciraNvpNetworkGuru will configure a logical -switch on the NVP Controller. During the startup of a virtual machine the -NiciraNvpElement will create a logical port for any NICs in the guest networks -and attach the port to the existing logical swith. - -== Debugging/Troubleshooting - -All elements created on the NVP controller have tags with the name of the -account, this can be used to search the items using the NVP manager. The NVP -uuid of the logical switch is also stored in the BroadcastUri of the -corresponding Guest network in an lswitch uri scheme. The CloudStack uuid of -the NIC is used to make the Vif attachement on the logical switchport. - -The following classes should be set to log level debug when troubleshooting. - com.cloud.network - (Most NiciraNvp related objects live in this package and subpackages) - org.apache.commons.httpclient - (used by NiciraNvpApi to make calls to the SDN Controller) - httpclient.wire - (wirelevel http tracing of httpclient) - -Please report any findings to the developer mailing list. diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 37c3a3a6ecd..70f85607e4a 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-network-nvp Apache CloudStack Plugin - Network Nicira NVP org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterAnswer.java new file mode 100644 index 00000000000..40bde6c6e74 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterAnswer.java @@ -0,0 +1,34 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +/** + * + */ +public class ConfigurePortForwardingRulesOnLogicalRouterAnswer extends Answer { + + public ConfigurePortForwardingRulesOnLogicalRouterAnswer(Command command, + boolean success, String details) { + super(command, success, details); + } + + public ConfigurePortForwardingRulesOnLogicalRouterAnswer(Command command, + Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterCommand.java new file mode 100644 index 00000000000..5f0ea384af3 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePortForwardingRulesOnLogicalRouterCommand.java @@ -0,0 +1,60 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +import java.util.List; + +import com.cloud.agent.api.to.PortForwardingRuleTO; + +/** + * + */ +public class ConfigurePortForwardingRulesOnLogicalRouterCommand extends Command { + + private String logicalRouterUuid; + private List rules; + + public ConfigurePortForwardingRulesOnLogicalRouterCommand(String logicalRouterUuid, List rules) { + this.logicalRouterUuid = logicalRouterUuid; + this.rules = rules; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + /* (non-Javadoc) + * @see com.cloud.agent.api.Command#executeInSequence() + */ + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java new file mode 100644 index 00000000000..12b1a1ffb3f --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +public class ConfigurePublicIpsOnLogicalRouterAnswer extends Answer { + + public ConfigurePublicIpsOnLogicalRouterAnswer(Command command, + boolean success, String details) { + super(command, success, details); + } + + public ConfigurePublicIpsOnLogicalRouterAnswer(Command command, Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java new file mode 100644 index 00000000000..8ee3793ed89 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +import java.util.List; + +public class ConfigurePublicIpsOnLogicalRouterCommand extends Command { + + private String logicalRouterUuid; + private String l3GatewayServiceUuid; + private List publicCidrs; + + public ConfigurePublicIpsOnLogicalRouterCommand(String logicalRouterUuid, + String l3GatewayServiceUuid, + List publicCidrs) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + this.publicCidrs = publicCidrs; + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public String getL3GatewayServiceUuid() { + return l3GatewayServiceUuid; + } + + public void setL3GatewayServiceUuid(String l3GatewayServiceUuid) { + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } + + public List getPublicCidrs() { + return publicCidrs; + } + + public void setPublicCidrs(List publicCidrs) { + this.publicCidrs = publicCidrs; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterAnswer.java new file mode 100644 index 00000000000..463dd4628cf --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterAnswer.java @@ -0,0 +1,43 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +/** + * + */ +public class ConfigureStaticNatRulesOnLogicalRouterAnswer extends Answer { + + /** + * @param command + * @param success + * @param details + */ + public ConfigureStaticNatRulesOnLogicalRouterAnswer(Command command, + boolean success, String details) { + super(command, success, details); + } + + /** + * @param command + * @param e + */ + public ConfigureStaticNatRulesOnLogicalRouterAnswer(Command command, + Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterCommand.java new file mode 100644 index 00000000000..960f609cb54 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigureStaticNatRulesOnLogicalRouterCommand.java @@ -0,0 +1,63 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +import java.util.List; + +import com.cloud.agent.api.to.StaticNatRuleTO; + +/** + * + */ +public class ConfigureStaticNatRulesOnLogicalRouterCommand extends Command { + + private String logicalRouterUuid; + private List rules; + + public ConfigureStaticNatRulesOnLogicalRouterCommand( + String logicalRouterUuid, List rules) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + this.rules = rules; + + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + /* (non-Javadoc) + * @see com.cloud.agent.api.Command#executeInSequence() + */ + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java new file mode 100644 index 00000000000..4a09e449af8 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java @@ -0,0 +1,40 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +/** + * + */ +public class CreateLogicalRouterAnswer extends Answer { + + private String _logicalRouterUuid; + + public CreateLogicalRouterAnswer(Command command, boolean success, + String details, String logicalRouterUuid) { + super(command, success, details); + this._logicalRouterUuid = logicalRouterUuid; + } + + public CreateLogicalRouterAnswer(Command command, Exception e) { + super(command, e); + } + + public String getLogicalRouterUuid() { + return _logicalRouterUuid; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java new file mode 100644 index 00000000000..57440dfc4b0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java @@ -0,0 +1,115 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +/** + * + */ +public class CreateLogicalRouterCommand extends Command { + private String _gatewayServiceUuid; + private String _logicalSwitchUuid; + private long _vlanId; + private String _name; + private String _ownerName; + private String _publicIpCidr; + private String _publicNextHop; + private String _internalIpCidr; + + public CreateLogicalRouterCommand(String gatewayServiceUuid, long vlanId, + String logicalSwitchUuid, String name, + String publicIpCidr, String publicNextHop, + String internalIpCidr, String ownerName) { + super(); + this._gatewayServiceUuid = gatewayServiceUuid; + this._logicalSwitchUuid = logicalSwitchUuid; + this._vlanId = vlanId; + this._name = name; + this._ownerName = ownerName; + this._publicIpCidr = publicIpCidr; + this._publicNextHop = publicNextHop; + this._internalIpCidr = internalIpCidr; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getGatewayServiceUuid() { + return _gatewayServiceUuid; + } + + public void setGatewayServiceUuid(String gatewayServiceUuid) { + this._gatewayServiceUuid = gatewayServiceUuid; + } + + public String getLogicalSwitchUuid() { + return _logicalSwitchUuid; + } + + public void setLogicalSwitchUuid(String logicalSwitchUuid) { + _logicalSwitchUuid = logicalSwitchUuid; + } + + public long getVlanId() { + return _vlanId; + } + + public void setVlanId(long vlanId) { + this._vlanId = vlanId; + } + + public String getName() { + return _name; + } + + public void setName(String name) { + this._name = name; + } + + public String getOwnerName() { + return _ownerName; + } + + public void setOwnerName(String ownerName) { + this._ownerName = ownerName; + } + + public String getPublicIpCidr() { + return _publicIpCidr; + } + + public void setPublicIpCidr(String publicIpCidr) { + this._publicIpCidr = publicIpCidr; + } + + public String getInternalIpCidr() { + return _internalIpCidr; + } + + public void setInternalIpCidr(String internalIpCidr) { + this._internalIpCidr = internalIpCidr; + } + + public String getPublicNextHop() { + return _publicNextHop; + } + + public void setPublicNextHop(String publicNextHop) { + this._publicNextHop = publicNextHop; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterAnswer.java new file mode 100644 index 00000000000..8a6bb9f193a --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterAnswer.java @@ -0,0 +1,32 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +/** + * + */ +public class DeleteLogicalRouterAnswer extends Answer { + + public DeleteLogicalRouterAnswer(Command command, boolean success, + String details) { + super(command, success, details); + } + + public DeleteLogicalRouterAnswer(Command command, Exception e) { + super(command, e); + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterCommand.java new file mode 100644 index 00000000000..4799f9e58fe --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/DeleteLogicalRouterCommand.java @@ -0,0 +1,41 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api; + +/** + * + */ +public class DeleteLogicalRouterCommand extends Command { + + private String _logicalRouterUuid; + + public DeleteLogicalRouterCommand(String logicalRouterUuid) { + this._logicalRouterUuid = logicalRouterUuid; + } + + /* (non-Javadoc) + * @see com.cloud.agent.api.Command#executeInSequence() + */ + @Override + public boolean executeInSequence() { + return false; + } + + public String getLogicalRouterUuid() { + return _logicalRouterUuid; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java index 6eac21f7255..ef12bf62605 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java @@ -42,9 +42,9 @@ import com.cloud.user.UserContext; import com.cloud.utils.exception.CloudRuntimeException; @Implementation(responseObject=NiciraNvpDeviceResponse.class, description="Adds a Nicira NVP device") -public class AddNiciraNvpDeviceCmd extends BaseCmd { +public class AddNiciraNvpDeviceCmd extends BaseAsyncCmd { private static final Logger s_logger = Logger.getLogger(AddNiciraNvpDeviceCmd.class.getName()); - private static final String s_name = "addniciranvpdevice"; + private static final String s_name = "addniciranvpdeviceresponse"; @PlugService NiciraNvpElementService _niciraNvpElementService; ///////////////////////////////////////////////////// @@ -67,6 +67,9 @@ public class AddNiciraNvpDeviceCmd extends BaseCmd { @Parameter(name=ApiConstants.NICIRA_NVP_TRANSPORT_ZONE_UUID, type=CommandType.STRING, required = true, description="The Transportzone UUID configured on the Nicira Controller") private String transportzoneuuid; + @Parameter(name=ApiConstants.NICIRA_NVP_GATEWAYSERVICE_UUID, type=CommandType.STRING, required = false, description="The L3 Gateway Service UUID configured on the Nicira Controller") + private String l3gatewayserviceuuid; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -90,6 +93,10 @@ public class AddNiciraNvpDeviceCmd extends BaseCmd { public String getTransportzoneUuid() { return transportzoneuuid; } + + public String getL3GatewayServiceUuid() { + return l3gatewayserviceuuid; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// @@ -123,4 +130,14 @@ public class AddNiciraNvpDeviceCmd extends BaseCmd { public long getEntityOwnerId() { return UserContext.current().getCaller().getId(); } + + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_NVP_CONTROLLER_ADD; + } + + @Override + public String getEventDescription() { + return "Adding a Nicira Nvp Controller"; + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java index 01a39466fd3..9cc8d626bb5 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/DeleteNiciraNvpDeviceCmd.java @@ -19,6 +19,7 @@ package com.cloud.api.commands; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; import com.cloud.api.BaseCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; @@ -26,6 +27,7 @@ import com.cloud.api.Parameter; import com.cloud.api.PlugService; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; @@ -36,9 +38,9 @@ import com.cloud.user.UserContext; import com.cloud.utils.exception.CloudRuntimeException; @Implementation(responseObject=SuccessResponse.class, description=" delete a nicira nvp device") -public class DeleteNiciraNvpDeviceCmd extends BaseCmd { +public class DeleteNiciraNvpDeviceCmd extends BaseAsyncCmd { private static final Logger s_logger = Logger.getLogger(DeleteNiciraNvpDeviceCmd.class.getName()); - private static final String s_name = "addniciranvpdevice"; + private static final String s_name = "deleteniciranvpdeviceresponse"; @PlugService NiciraNvpElementService _niciraNvpElementService; ///////////////////////////////////////////////////// @@ -89,4 +91,14 @@ public class DeleteNiciraNvpDeviceCmd extends BaseCmd { return UserContext.current().getCaller().getId(); } + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_LB_DEVICE_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting Nicira Nvp Controller"; + } + } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java index f9c157d9feb..f38cb16c8e9 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/ListNiciraNvpDevicesCmd.java @@ -43,7 +43,7 @@ import com.cloud.utils.exception.CloudRuntimeException; @Implementation(responseObject=NiciraNvpDeviceResponse.class, description="Lists Nicira NVP devices") public class ListNiciraNvpDevicesCmd extends BaseListCmd { private static final Logger s_logger = Logger.getLogger(ListNiciraNvpDevicesCmd.class.getName()); - private static final String s_name = "listniciranvpdevices"; + private static final String s_name = "listniciranvpdeviceresponse"; @PlugService NiciraNvpElementService _niciraNvpElementService; ///////////////////////////////////////////////////// diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java b/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java index d5c82b34a87..e50be813879 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/response/NiciraNvpDeviceResponse.java @@ -33,7 +33,16 @@ public class NiciraNvpDeviceResponse extends BaseResponse { @SerializedName(ApiConstants.NICIRA_NVP_DEVICE_NAME) @Param(description="device name") private String deviceName; - + + @SerializedName(ApiConstants.HOST_NAME) @Param(description="the controller Ip address") + private String hostName; + + @SerializedName(ApiConstants.NICIRA_NVP_TRANSPORT_ZONE_UUID) @Param(description="the transport zone Uuid") + private String transportZoneUuid; + + @SerializedName(ApiConstants.NICIRA_NVP_GATEWAYSERVICE_UUID) @Param(description="this L3 gateway service Uuid") + private String l3GatewayServiceUuid; + public void setId(long nvpDeviceId) { this.id.setValue(nvpDeviceId); } @@ -48,6 +57,26 @@ public class NiciraNvpDeviceResponse extends BaseResponse { public void setDeviceName(String deviceName) { this.deviceName = deviceName; - } + } + + public void setId(IdentityProxy id) { + this.id = id; + } + + public void setPhysicalNetworkId(IdentityProxy physicalNetworkId) { + this.physicalNetworkId = physicalNetworkId; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public void setTransportZoneUuid(String transportZoneUuid) { + this.transportZoneUuid = transportZoneUuid; + } + + public void setL3GatewayServiceUuid(String l3GatewayServiceUuid) { + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/NiciraNvpRouterMappingVO.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/NiciraNvpRouterMappingVO.java new file mode 100644 index 00000000000..037ba699fc0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/NiciraNvpRouterMappingVO.java @@ -0,0 +1,79 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="nicira_nvp_router_map") +public class NiciraNvpRouterMappingVO { + //FIXME the ddl for this table should be in one of the upgrade scripts + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="logicalrouter_uuid") + private String logicalRouterUuid; + + @Column(name="network_id") + private long networkId; + + public NiciraNvpRouterMappingVO() { + } + + public NiciraNvpRouterMappingVO(String logicalRouterUuid, long networkId) { + this.logicalRouterUuid = logicalRouterUuid; + this.networkId = networkId; + } + + public NiciraNvpRouterMappingVO(long id, String logicalRouterUuid, long networkId) { + this.id = id; + this.logicalRouterUuid = logicalRouterUuid; + this.networkId = networkId; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public long getNetworkId() { + return networkId; + } + + public void setNetworkId(long networkId) { + this.networkId = networkId; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java new file mode 100644 index 00000000000..c6c58c8846f --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java @@ -0,0 +1,25 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.dao; + +import com.cloud.network.NiciraNvpRouterMappingVO; +import com.cloud.utils.db.GenericDao; + +public interface NiciraNvpRouterMappingDao extends GenericDao { + + public NiciraNvpRouterMappingVO findByNetworkId(long id); +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java new file mode 100644 index 00000000000..091207c8896 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java @@ -0,0 +1,46 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.dao; + +import javax.ejb.Local; + +import com.cloud.network.NiciraNvpRouterMappingVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +@Local(value=NiciraNvpRouterMappingDao.class) +public class NiciraNvpRouterMappingDaoImpl extends GenericDaoBase implements NiciraNvpRouterMappingDao { + + protected final SearchBuilder networkSearch; + + public NiciraNvpRouterMappingDaoImpl() { + networkSearch = createSearchBuilder(); + networkSearch.and("network_id", networkSearch.entity().getNetworkId(), Op.EQ); + networkSearch.done(); + } + + @Override + public NiciraNvpRouterMappingVO findByNetworkId(long id) { + SearchCriteria sc = networkSearch.create(); + sc.setParameters("network_id", id); + return findOneBy(sc); + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java index 1fcccdb1ee3..b1e9af2fd52 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.element; import java.util.ArrayList; @@ -47,8 +30,18 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; +import com.cloud.agent.api.CreateLogicalRouterAnswer; +import com.cloud.agent.api.CreateLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalSwitchPortAnswer; import com.cloud.agent.api.CreateLogicalSwitchPortCommand; +import com.cloud.agent.api.DeleteLogicalRouterAnswer; +import com.cloud.agent.api.DeleteLogicalRouterCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer; import com.cloud.agent.api.DeleteLogicalSwitchPortCommand; import com.cloud.agent.api.FindLogicalSwitchPortAnswer; @@ -57,11 +50,16 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer; import com.cloud.agent.api.UpdateLogicalSwitchPortCommand; +import com.cloud.agent.api.to.PortForwardingRuleTO; +import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.api.commands.AddNiciraNvpDeviceCmd; import com.cloud.api.commands.DeleteNiciraNvpDeviceCmd; import com.cloud.api.commands.ListNiciraNvpDeviceNetworksCmd; import com.cloud.api.commands.ListNiciraNvpDevicesCmd; import com.cloud.api.response.NiciraNvpDeviceResponse; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.dc.Vlan; +import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -80,29 +78,43 @@ import com.cloud.network.Network.Service; import com.cloud.network.NetworkVO; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.IpAddress; +import com.cloud.network.NetworkManager; import com.cloud.network.NiciraNvpDeviceVO; import com.cloud.network.NiciraNvpNicMappingVO; +import com.cloud.network.NiciraNvpRouterMappingVO; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkVO; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.NiciraNvpDao; import com.cloud.network.dao.NiciraNvpNicMappingDao; +import com.cloud.network.dao.NiciraNvpRouterMappingDao; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.guru.NiciraNvpGuestNetworkGuru; import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.PortForwardingRule; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.rules.StaticNatRule; +import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.offering.NetworkOffering; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; +import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; @@ -111,433 +123,827 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; @Local(value = NetworkElement.class) -public class NiciraNvpElement extends AdapterBase implements ConnectivityProvider, NiciraNvpElementService, ResourceStateAdapter { - private static final Logger s_logger = Logger.getLogger(NiciraNvpElement.class); - - private static final Map> capabilities = setCapabilities(); - +public class NiciraNvpElement extends AdapterBase implements + ConnectivityProvider, SourceNatServiceProvider, + PortForwardingServiceProvider, StaticNatServiceProvider, + NiciraNvpElementService, ResourceStateAdapter, IpDeployer { + private static final Logger s_logger = Logger + .getLogger(NiciraNvpElement.class); - @Inject - NicDao _nicDao; - @Inject - ResourceManager _resourceMgr; - @Inject - PhysicalNetworkDao _physicalNetworkDao; - @Inject - PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; - @Inject - NiciraNvpDao _niciraNvpDao; - @Inject - HostDetailsDao _hostDetailsDao; - @Inject - HostDao _hostDao; - @Inject - AgentManager _agentMgr; - @Inject - NiciraNvpNicMappingDao _niciraNvpNicMappingDao; - @Inject - NetworkDao _networkDao; - - @Override - public Map> getCapabilities() { - return capabilities; - } + private static final Map> capabilities = setCapabilities(); - @Override - public Provider getProvider() { - return Provider.NiciraNvp; - } - - private boolean canHandle(Network network) { - if (network.getBroadcastDomainType() != BroadcastDomainType.Lswitch) { - return false; - } - - return true; - } - - @Override - public boolean configure(String name, Map params) - throws ConfigurationException { - super.configure(name, params); - _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); - return true; - } + @Inject + NicDao _nicDao; + @Inject + ResourceManager _resourceMgr; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; + @Inject + NiciraNvpDao _niciraNvpDao; + @Inject + HostDetailsDao _hostDetailsDao; + @Inject + HostDao _hostDao; + @Inject + AgentManager _agentMgr; + @Inject + NiciraNvpNicMappingDao _niciraNvpNicMappingDao; + @Inject + NiciraNvpRouterMappingDao _niciraNvpRouterMappingDao; + @Inject + NetworkDao _networkDao; + @Inject + NetworkManager _networkManager; + @Inject + ConfigurationManager _configMgr; + @Inject + NetworkServiceMapDao _ntwkSrvcDao; + @Inject + VlanDao _vlanDao; - @Override - public boolean implement(Network network, NetworkOffering offering, - DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - - if (!canHandle(network)) { - return false; - } - - return true; - } + @Override + public Map> getCapabilities() { + return capabilities; + } - @Override - public boolean prepare(Network network, NicProfile nic, - VirtualMachineProfile vm, - DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - - if (!canHandle(network)) { + @Override + public Provider getProvider() { + return Provider.NiciraNvp; + } + + private boolean canHandle(Network network, Service service) { + s_logger.debug("Checking if NiciraNvpElement can handle service " + + service.getName() + " on network " + network.getDisplayText()); + if (network.getBroadcastDomainType() != BroadcastDomainType.Lswitch) { + return false; + } + + if (!_networkManager.isProviderForNetwork(getProvider(), + network.getId())) { + s_logger.debug("NiciraNvpElement is not a provider for network " + + network.getDisplayText()); + return false; + } + + if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), + service, Network.Provider.NiciraNvp)) { + s_logger.debug("NiciraNvpElement can't provide the " + + service.getName() + " service on network " + + network.getDisplayText()); + return false; + } + + return true; + } + + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { + super.configure(name, params); + _resourceMgr.registerResourceStateAdapter(this.getClass() + .getSimpleName(), this); + return true; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + s_logger.debug("entering NiciraNvpElement implement function for network " + + network.getDisplayText() + + " (state " + + network.getState() + + ")"); + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); + return false; + } + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + _hostDao.loadDetails(niciraNvpHost); + + Account owner = context.getAccount(); + + /** + * Lock the network as we might need to do multiple operations that + * should be done only once. + */ + Network lock = _networkDao.acquireInLockTable(network.getId(), + _networkManager.getNetworkLockTimeout()); + if (lock == null) { + throw new ConcurrentOperationException("Unable to lock network " + + network.getId()); + } + try { + // Implement SourceNat immediately as we have al the info already + if (_networkManager.isProviderSupportServiceInNetwork( + network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + s_logger.debug("Apparently we are supposed to provide SourceNat on this network"); + + PublicIp sourceNatIp = _networkManager + .assignSourceNatIpAddressToGuestNetwork(owner, network); + String publicCidr = sourceNatIp.getAddress().addr() + "/" + + NetUtils.getCidrSize(sourceNatIp.getVlanNetmask()); + String internalCidr = network.getGateway() + "/" + + network.getCidr().split("/")[1]; + long vlanid = (Vlan.UNTAGGED.equals(sourceNatIp.getVlanTag())) ? 0 + : Long.parseLong(sourceNatIp.getVlanTag()); + + CreateLogicalRouterCommand cmd = new CreateLogicalRouterCommand( + niciraNvpHost.getDetail("l3gatewayserviceuuid"), vlanid, + network.getBroadcastUri().getSchemeSpecificPart(), + "router-" + network.getDisplayText(), publicCidr, + sourceNatIp.getGateway(), internalCidr, context + .getDomain().getName() + + "-" + + context.getAccount().getAccountName()); + CreateLogicalRouterAnswer answer = (CreateLogicalRouterAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to create Logical Router for network " + + network.getDisplayText()); + return false; + } + + // Store the uuid so we can easily find it during cleanup + NiciraNvpRouterMappingVO routermapping = + new NiciraNvpRouterMappingVO(answer.getLogicalRouterUuid(), network.getId()); + _niciraNvpRouterMappingDao.persist(routermapping); + } + } finally { + if (lock != null) { + _networkDao.releaseFromLockTable(lock.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Lock is released for network id " + + lock.getId() + " as a part of router startup in " + + dest); + } + } + } + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, + VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); + return false; + } + + NicVO nicVO = _nicDao.findById(nic.getId()); + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpNicMappingVO existingNicMap = _niciraNvpNicMappingDao + .findByNicUuid(nicVO.getUuid()); + if (existingNicMap != null) { + FindLogicalSwitchPortCommand findCmd = new FindLogicalSwitchPortCommand( + existingNicMap.getLogicalSwitchUuid(), + existingNicMap.getLogicalSwitchPortUuid()); + FindLogicalSwitchPortAnswer answer = (FindLogicalSwitchPortAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), findCmd); + + if (answer.getResult()) { + s_logger.warn("Existing Logical Switchport found for nic " + + nic.getName() + " with uuid " + + existingNicMap.getLogicalSwitchPortUuid()); + UpdateLogicalSwitchPortCommand cmd = new UpdateLogicalSwitchPortCommand( + existingNicMap.getLogicalSwitchPortUuid(), network + .getBroadcastUri().getSchemeSpecificPart(), + nicVO.getUuid(), context.getDomain().getName() + "-" + + context.getAccount().getAccountName(), + nic.getName()); + _agentMgr.easySend(niciraNvpHost.getId(), cmd); + return true; + } else { + s_logger.error("Stale entry found for nic " + nic.getName() + + " with logical switchport uuid " + + existingNicMap.getLogicalSwitchPortUuid()); + _niciraNvpNicMappingDao.remove(existingNicMap.getId()); + } + } + + CreateLogicalSwitchPortCommand cmd = new CreateLogicalSwitchPortCommand( + network.getBroadcastUri().getSchemeSpecificPart(), + nicVO.getUuid(), context.getDomain().getName() + "-" + + context.getAccount().getAccountName(), nic.getName()); + CreateLogicalSwitchPortAnswer answer = (CreateLogicalSwitchPortAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("CreateLogicalSwitchPortCommand failed"); + return false; + } + + NiciraNvpNicMappingVO nicMap = new NiciraNvpNicMappingVO(network + .getBroadcastUri().getSchemeSpecificPart(), + answer.getLogicalSwitchPortUuid(), nicVO.getUuid()); + _niciraNvpNicMappingDao.persist(nicMap); + + return true; + } + + @Override + public boolean release(Network network, NicProfile nic, + VirtualMachineProfile vm, + ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException { + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); + return false; + } + + NicVO nicVO = _nicDao.findById(nic.getId()); + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpNicMappingVO nicMap = _niciraNvpNicMappingDao + .findByNicUuid(nicVO.getUuid()); + if (nicMap == null) { + s_logger.error("No mapping for nic " + nic.getName()); + return false; + } + + DeleteLogicalSwitchPortCommand cmd = new DeleteLogicalSwitchPortCommand( + nicMap.getLogicalSwitchUuid(), + nicMap.getLogicalSwitchPortUuid()); + DeleteLogicalSwitchPortAnswer answer = (DeleteLogicalSwitchPortAnswer) _agentMgr + .easySend(niciraNvpHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("DeleteLogicalSwitchPortCommand failed"); + return false; + } + + _niciraNvpNicMappingDao.remove(nicMap.getId()); + + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, + boolean cleanup) throws ConcurrentOperationException, + ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + if (_networkManager.isProviderSupportServiceInNetwork(network.getId(), + Service.SourceNat, Provider.NiciraNvp)) { + s_logger.debug("Apparently we were providing SourceNat on this network"); + + // Deleting the LogicalRouter will also take care of all provisioned + // nat rules. + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.warn("No logical router uuid found for network " + + network.getDisplayText()); + // This might be cause by a failed deployment, so don't make shutdown fail as well. + return true; + } + + DeleteLogicalRouterCommand cmd = new DeleteLogicalRouterCommand(routermapping.getLogicalRouterUuid()); + DeleteLogicalRouterAnswer answer = + (DeleteLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to delete LogicalRouter for network " + + network.getDisplayText()); + return false; + } + + _niciraNvpRouterMappingDao.remove(routermapping.getId()); + } + + return true; + } + + @Override + public boolean destroy(Network network, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + return true; + } + + @Override + public boolean shutdownProviderInstances( + PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { + // Nothing to do here. + return true; + } + + @Override + public boolean canEnableIndividualServices() { + return true; + } + + @Override + public boolean verifyServicesCombination(Set services) { + // This element can only function in a Nicra Nvp based + // SDN network, so Connectivity needs to be present here + if (!services.contains(Service.Connectivity)) { + s_logger.warn("Unable to provide services without Connectivity service enabled for this element"); + return false; + } + if ((services.contains(Service.PortForwarding) || services.contains(Service.StaticNat)) && !services.contains(Service.SourceNat)) { + s_logger.warn("Unable to provide StaticNat and/or PortForwarding without the SourceNat service"); + return false; + } + return true; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + // L2 Support : SDN provisioning + capabilities.put(Service.Connectivity, null); + + // L3 Support : Generic? + capabilities.put(Service.Gateway, null); + + // L3 Support : SourceNat + Map sourceNatCapabilities = new HashMap(); + sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, + "peraccount"); + sourceNatCapabilities.put(Capability.RedundantRouter, "false"); + capabilities.put(Service.SourceNat, sourceNatCapabilities); + + // L3 Support : Port Forwarding + capabilities.put(Service.PortForwarding, null); + + // L3 support : StaticNat + capabilities.put(Service.StaticNat, null); + + return capabilities; + } + + @Override + public String getPropertiesFile() { + return "nicira-nvp_commands.properties"; + } + + @Override + @DB + public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd) { + ServerResource resource = new NiciraNvpResource(); + String deviceName = Network.Provider.NiciraNvp.getName(); + NetworkDevice networkDevice = NetworkDevice + .getNetworkDevice(deviceName); + Long physicalNetworkId = cmd.getPhysicalNetworkId(); + NiciraNvpDeviceVO niciraNvpDevice = null; + + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException( + "Could not find phyical network with ID: " + + physicalNetworkId); + } + long zoneId = physicalNetwork.getDataCenterId(); + + PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao + .findByServiceProvider(physicalNetwork.getId(), + networkDevice.getNetworkServiceProvder()); + if (ntwkSvcProvider == null) { + throw new CloudRuntimeException("Network Service Provider: " + + networkDevice.getNetworkServiceProvder() + + " is not enabled in the physical network: " + + physicalNetworkId + "to add this device"); + } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) { + throw new CloudRuntimeException("Network Service Provider: " + + ntwkSvcProvider.getProviderName() + + " is in shutdown state in the physical network: " + + physicalNetworkId + "to add this device"); + } + + if (_niciraNvpDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) { + throw new CloudRuntimeException( + "A NiciraNvp device is already configured on this physical network"); + } + + Map params = new HashMap(); + params.put("guid", UUID.randomUUID().toString()); + params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId())); + params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId())); + params.put("name", "Nicira Controller - " + cmd.getHost()); + params.put("ip", cmd.getHost()); + params.put("adminuser", cmd.getUsername()); + params.put("adminpass", cmd.getPassword()); + params.put("transportzoneuuid", cmd.getTransportzoneUuid()); + // FIXME What to do with multiple isolation types + params.put("transportzoneisotype", + physicalNetwork.getIsolationMethods().get(0).toLowerCase()); + if (cmd.getL3GatewayServiceUuid() != null) { + params.put("l3gatewayserviceuuid", cmd.getL3GatewayServiceUuid()); + } + + Map hostdetails = new HashMap(); + hostdetails.putAll(params); + + Transaction txn = Transaction.currentTxn(); + try { + resource.configure(cmd.getHost(), hostdetails); + + Host host = _resourceMgr.addHost(zoneId, resource, + Host.Type.L2Networking, params); + if (host != null) { + txn.start(); + + niciraNvpDevice = new NiciraNvpDeviceVO(host.getId(), + physicalNetworkId, ntwkSvcProvider.getProviderName(), + deviceName); + _niciraNvpDao.persist(niciraNvpDevice); + + DetailVO detail = new DetailVO(host.getId(), + "niciranvpdeviceid", String.valueOf(niciraNvpDevice + .getId())); + _hostDetailsDao.persist(detail); + + txn.commit(); + return niciraNvpDevice; + } else { + throw new CloudRuntimeException( + "Failed to add Nicira Nvp Device due to internal error."); + } + } catch (ConfigurationException e) { + txn.rollback(); + throw new CloudRuntimeException(e.getMessage()); + } + } + + @Override + public NiciraNvpDeviceResponse createNiciraNvpDeviceResponse( + NiciraNvpDeviceVO niciraNvpDeviceVO) { + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDeviceVO.getHostId()); + _hostDao.loadDetails(niciraNvpHost); + + NiciraNvpDeviceResponse response = new NiciraNvpDeviceResponse(); + response.setDeviceName(niciraNvpDeviceVO.getDeviceName()); + response.setPhysicalNetworkId(niciraNvpDeviceVO.getPhysicalNetworkId()); + response.setId(niciraNvpDeviceVO.getId()); + response.setProviderName(niciraNvpDeviceVO.getProviderName()); + response.setHostName(niciraNvpHost.getDetail("ip")); + response.setTransportZoneUuid(niciraNvpHost.getDetail("transportzoneuuid")); + response.setL3GatewayServiceUuid(niciraNvpHost.getDetail("l3gatewayserviceuuid")); + response.setObjectName("niciranvpdevice"); + return response; + } + + @Override + public boolean deleteNiciraNvpDevice(DeleteNiciraNvpDeviceCmd cmd) { + Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); + NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao + .findById(niciraDeviceId); + if (niciraNvpDevice == null) { + throw new InvalidParameterValueException( + "Could not find a nicira device with id " + niciraDeviceId); + } + + // Find the physical network we work for + Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork != null) { + // Lets see if there are networks that use us + // Find the nicira networks on this physical network + List networkList = _networkDao + .listByPhysicalNetwork(physicalNetworkId); + + // Networks with broadcast type lswitch are ours + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { + if ((network.getState() != Network.State.Shutdown) + && (network.getState() != Network.State.Destroy)) { + throw new CloudRuntimeException( + "This Nicira Nvp device can not be deleted as there are one or more logical networks provisioned by cloudstack."); + } + } + } + } + + HostVO niciraHost = _hostDao.findById(niciraNvpDevice.getHostId()); + Long hostId = niciraHost.getId(); + + niciraHost.setResourceState(ResourceState.Maintenance); + _hostDao.update(hostId, niciraHost); + _resourceMgr.deleteHost(hostId, false, false); + + _niciraNvpDao.remove(niciraDeviceId); + return true; + } + + @Override + public List listNiciraNvpDevices( + ListNiciraNvpDevicesCmd cmd) { + Long physicalNetworkId = cmd.getPhysicalNetworkId(); + Long niciraNvpDeviceId = cmd.getNiciraNvpDeviceId(); + List responseList = new ArrayList(); + + if (physicalNetworkId == null && niciraNvpDeviceId == null) { + throw new InvalidParameterValueException( + "Either physical network Id or nicira device Id must be specified"); + } + + if (niciraNvpDeviceId != null) { + NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao + .findById(niciraNvpDeviceId); + if (niciraNvpDevice == null) { + throw new InvalidParameterValueException( + "Could not find Nicira Nvp device with id: " + + niciraNvpDevice); + } + responseList.add(niciraNvpDevice); + } else { + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException( + "Could not find a physical network with id: " + + physicalNetworkId); + } + responseList = _niciraNvpDao + .listByPhysicalNetwork(physicalNetworkId); + } + + return responseList; + } + + @Override + public List listNiciraNvpDeviceNetworks( + ListNiciraNvpDeviceNetworksCmd cmd) { + Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); + NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao + .findById(niciraDeviceId); + if (niciraNvpDevice == null) { + throw new InvalidParameterValueException( + "Could not find a nicira device with id " + niciraDeviceId); + } + + // Find the physical network we work for + Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao + .findById(physicalNetworkId); + if (physicalNetwork == null) { + // No such physical network, so no provisioned networks + return Collections.emptyList(); + } + + // Find the nicira networks on this physical network + List networkList = _networkDao + .listByPhysicalNetwork(physicalNetworkId); + + // Networks with broadcast type lswitch are ours + List responseList = new ArrayList(); + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { + responseList.add(network); + } + } + + return responseList; + } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, + StartupCommand[] cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, + StartupCommand[] startup, ServerResource resource, + Map details, List hostTags) { + if (!(startup[0] instanceof StartupNiciraNvpCommand)) { + return null; + } + host.setType(Host.Type.L2Networking); + return host; + } + + @Override + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, + boolean isForceDeleteStorage) throws UnableDeleteHostException { + if (!(host.getType() == Host.Type.L2Networking)) { + return null; + } + return new DeleteHostAnswer(true); + } + + /** + * From interface SourceNatServiceProvider + */ + @Override + public IpDeployer getIpDeployer(Network network) { + return this; + } + + /** + * From interface IpDeployer + * + * @param network + * @param ipAddress + * @param services + * @return + * @throws ResourceUnavailableException + */ + @Override + public boolean applyIps(Network network, + List ipAddress, Set services) + throws ResourceUnavailableException { + if (services.contains(Service.SourceNat)) { + // Only if we need to provide SourceNat we need to configure the logical router + // SourceNat is required for StaticNat and PortForwarding + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + _hostDao.loadDetails(niciraNvpHost); + + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.error("No logical router uuid found for network " + + network.getDisplayText()); + return false; + } + + List cidrs = new ArrayList(); + for (PublicIpAddress ip : ipAddress) { + cidrs.add(ip.getAddress().addr() + "/" + NetUtils.getCidrSize(ip.getNetmask())); + } + ConfigurePublicIpsOnLogicalRouterCommand cmd = new ConfigurePublicIpsOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), + niciraNvpHost.getDetail("l3gatewayserviceuuid"), cidrs); + ConfigurePublicIpsOnLogicalRouterAnswer answer = (ConfigurePublicIpsOnLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); + return answer.getResult(); + } + else { + s_logger.debug("No need to provision ip addresses as we are not providing L3 services."); + } + + return true; + } + + /** + * From interface StaticNatServiceProvider + */ + @Override + public boolean applyStaticNats(Network network, + List rules) + throws ResourceUnavailableException { + if (!canHandle(network, Service.StaticNat)) { return false; } - if (network.getBroadcastUri() == null) { - s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); - return false; - } + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.error("No logical router uuid found for network " + + network.getDisplayText()); + return false; + } - NicVO nicVO = _nicDao.findById(nic.getId()); - - List devices = _niciraNvpDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); - if (devices.isEmpty()) { - s_logger.error("No NiciraNvp Controller on physical network " + network.getPhysicalNetworkId()); - return false; - } - NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); - HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); - - NiciraNvpNicMappingVO existingNicMap = _niciraNvpNicMappingDao.findByNicUuid(nicVO.getUuid()); - if (existingNicMap != null) { - FindLogicalSwitchPortCommand findCmd = new FindLogicalSwitchPortCommand(existingNicMap.getLogicalSwitchUuid(), - existingNicMap.getLogicalSwitchPortUuid()); - FindLogicalSwitchPortAnswer answer = (FindLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), findCmd); - - if (answer.getResult()) { - s_logger.warn("Existing Logical Switchport found for nic " + nic.getName() + " with uuid " + existingNicMap.getLogicalSwitchPortUuid()); - UpdateLogicalSwitchPortCommand cmd = new UpdateLogicalSwitchPortCommand(existingNicMap.getLogicalSwitchPortUuid(), - network.getBroadcastUri().getSchemeSpecificPart(), nicVO.getUuid(), - context.getDomain().getName() + "-" + context.getAccount().getAccountName(), nic.getName()); - _agentMgr.easySend(niciraNvpHost.getId(), cmd); - return true; - } - else { - s_logger.error("Stale entry found for nic " + nic.getName() + " with logical switchport uuid " + existingNicMap.getLogicalSwitchPortUuid()); - _niciraNvpNicMappingDao.remove(existingNicMap.getId()); - } + List staticNatRules = new ArrayList(); + for (StaticNat rule : rules) { + IpAddress sourceIp = _networkManager.getIp(rule.getSourceIpAddressId()); + // Force the nat rule into the StaticNatRuleTO, no use making a new TO object + // we only need the source and destination ip. Unfortunately no mention if a rule + // is new. + StaticNatRuleTO ruleTO = new StaticNatRuleTO(1, + sourceIp.getAddress().addr(), 0, 65535, + rule.getDestIpAddress(), 0, 65535, + "any", rule.isForRevoke(), false); + staticNatRules.add(ruleTO); } - CreateLogicalSwitchPortCommand cmd = new CreateLogicalSwitchPortCommand(network.getBroadcastUri().getSchemeSpecificPart(), nicVO.getUuid(), - context.getDomain().getName() + "-" + context.getAccount().getAccountName(), nic.getName()); - CreateLogicalSwitchPortAnswer answer = (CreateLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); + ConfigureStaticNatRulesOnLogicalRouterCommand cmd = + new ConfigureStaticNatRulesOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), staticNatRules); + ConfigureStaticNatRulesOnLogicalRouterAnswer answer = (ConfigureStaticNatRulesOnLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); - if (answer == null || !answer.getResult()) { - s_logger.error ("CreateLogicalSwitchPortCommand failed"); + return answer.getResult(); + } + + /** + * From interface PortForwardingServiceProvider + */ + @Override + public boolean applyPFRules(Network network, List rules) + throws ResourceUnavailableException { + if (!canHandle(network, Service.PortForwarding)) { return false; } - NiciraNvpNicMappingVO nicMap = new NiciraNvpNicMappingVO(network.getBroadcastUri().getSchemeSpecificPart(), answer.getLogicalSwitchPortUuid(), nicVO.getUuid()); - _niciraNvpNicMappingDao.persist(nicMap); - - return true; - } - - @Override - public boolean release(Network network, NicProfile nic, - VirtualMachineProfile vm, - ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { - - if (!canHandle(network)) { - return false; - } - - if (network.getBroadcastUri() == null) { - s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid"); - return false; + List devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.error("No logical router uuid found for network " + + network.getDisplayText()); + return false; + } + + List portForwardingRules = new ArrayList(); + for (PortForwardingRule rule : rules) { + IpAddress sourceIp = _networkManager.getIp(rule.getSourceIpAddressId()); + Vlan vlan = _vlanDao.findById(sourceIp.getVlanId()); + PortForwardingRuleTO ruleTO = new PortForwardingRuleTO((PortForwardingRule) rule, vlan.getVlanTag(), sourceIp.getAddress().addr()); + portForwardingRules.add(ruleTO); } - NicVO nicVO = _nicDao.findById(nic.getId()); - - List devices = _niciraNvpDao.listByPhysicalNetwork(network.getPhysicalNetworkId()); - if (devices.isEmpty()) { - s_logger.error("No NiciraNvp Controller on physical network " + network.getPhysicalNetworkId()); - return false; - } - NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); - HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + ConfigurePortForwardingRulesOnLogicalRouterCommand cmd = + new ConfigurePortForwardingRulesOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), portForwardingRules); + ConfigurePortForwardingRulesOnLogicalRouterAnswer answer = (ConfigurePortForwardingRulesOnLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); - NiciraNvpNicMappingVO nicMap = _niciraNvpNicMappingDao.findByNicUuid(nicVO.getUuid()); - if (nicMap == null) { - s_logger.error("No mapping for nic " + nic.getName()); - return false; - } - - DeleteLogicalSwitchPortCommand cmd = new DeleteLogicalSwitchPortCommand(nicMap.getLogicalSwitchUuid(), nicMap.getLogicalSwitchPortUuid()); - DeleteLogicalSwitchPortAnswer answer = (DeleteLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); - - if (answer == null || !answer.getResult()) { - s_logger.error ("DeleteLogicalSwitchPortCommand failed"); - return false; - } - - _niciraNvpNicMappingDao.remove(nicMap.getId()); - - return true; - } - - @Override - public boolean shutdown(Network network, ReservationContext context, - boolean cleanup) throws ConcurrentOperationException, - ResourceUnavailableException { - if (!canHandle(network)) { - return false; - } - - return true; - } - - @Override - public boolean destroy(Network network) - throws ConcurrentOperationException, ResourceUnavailableException { - if (!canHandle(network)) { - return false; - } - - return true; - } - - @Override - public boolean isReady(PhysicalNetworkServiceProvider provider) { - return true; - } - - @Override - public boolean shutdownProviderInstances( - PhysicalNetworkServiceProvider provider, ReservationContext context) - throws ConcurrentOperationException, ResourceUnavailableException { - // Nothing to do here. - return true; - } - - @Override - public boolean canEnableIndividualServices() { - return false; - } - - @Override - public boolean verifyServicesCombination(Set services) { - return true; - } - - private static Map> setCapabilities() { - Map> capabilities = new HashMap>(); - - capabilities.put(Service.Connectivity, null); - return capabilities; - } - - @Override - public String getPropertiesFile() { - return "nicira-nvp_commands.properties"; - } - - @Override - @DB - public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd) { - ServerResource resource = new NiciraNvpResource(); - String deviceName = Network.Provider.NiciraNvp.getName(); - NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName); - Long physicalNetworkId = cmd.getPhysicalNetworkId(); - NiciraNvpDeviceVO niciraNvpDevice = null; - - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { - throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId); - } - long zoneId = physicalNetwork.getDataCenterId(); - - PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), networkDevice.getNetworkServiceProvder()); - if (ntwkSvcProvider == null) { - throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() + - " is not enabled in the physical network: " + physicalNetworkId + "to add this device"); - } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) { - throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + - " is in shutdown state in the physical network: " + physicalNetworkId + "to add this device"); - } - - if (_niciraNvpDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) { - throw new CloudRuntimeException("A NiciraNvp device is already configured on this physical network"); - } - - Map params = new HashMap(); - params.put("guid", UUID.randomUUID().toString()); - params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId())); - params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId())); - params.put("name", "Nicira Controller - " + cmd.getHost()); - params.put("ip", cmd.getHost()); - params.put("adminuser", cmd.getUsername()); - params.put("adminpass", cmd.getPassword()); - params.put("transportzoneuuid", cmd.getTransportzoneUuid()); - params.put("transportzoneisotype", physicalNetwork.getIsolationMethods().get(0).toLowerCase()); // FIXME What to do with multiple isolation types - - Map hostdetails = new HashMap(); - hostdetails.putAll(params); - - - Transaction txn = Transaction.currentTxn(); - try { - resource.configure(cmd.getHost(), hostdetails); - - Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params); - if (host != null) { - txn.start(); - - niciraNvpDevice = new NiciraNvpDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName); - _niciraNvpDao.persist(niciraNvpDevice); - - DetailVO detail = new DetailVO(host.getId(), "niciranvpdeviceid", String.valueOf(niciraNvpDevice.getId())); - _hostDetailsDao.persist(detail); - - txn.commit(); - return niciraNvpDevice; - } else { - throw new CloudRuntimeException("Failed to add Nicira Nvp Device due to internal error."); - } - } catch (ConfigurationException e) { - txn.rollback(); - throw new CloudRuntimeException(e.getMessage()); - } - } - - @Override - public NiciraNvpDeviceResponse createNiciraNvpDeviceResponse( - NiciraNvpDeviceVO niciraNvpDeviceVO) { - NiciraNvpDeviceResponse response = new NiciraNvpDeviceResponse(); - response.setDeviceName(niciraNvpDeviceVO.getDeviceName()); - response.setPhysicalNetworkId(niciraNvpDeviceVO.getPhysicalNetworkId()); - response.setId(niciraNvpDeviceVO.getId()); - response.setProviderName(niciraNvpDeviceVO.getProviderName()); - return response; - } - - @Override - public boolean deleteNiciraNvpDevice(DeleteNiciraNvpDeviceCmd cmd) { - Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); - NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraDeviceId); - if (niciraNvpDevice == null) { - throw new InvalidParameterValueException("Could not find a nicira device with id " + niciraDeviceId); - } - - // Find the physical network we work for - Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork != null) { - // Lets see if there are networks that use us - // Find the nicira networks on this physical network - List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); - - // Networks with broadcast type lswitch are ours - for (NetworkVO network : networkList) { - if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { - if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) { - throw new CloudRuntimeException("This Nicira Nvp device can not be deleted as there are one or more logical networks provisioned by cloudstack."); - } - } - } - } - - HostVO niciraHost = _hostDao.findById(niciraNvpDevice.getHostId()); - Long hostId = niciraHost.getId(); - - niciraHost.setResourceState(ResourceState.Maintenance); - _hostDao.update(hostId, niciraHost); - _resourceMgr.deleteHost(hostId, false, false); - - _niciraNvpDao.remove(niciraDeviceId); - - return true; - } - - @Override - public List listNiciraNvpDevices(ListNiciraNvpDevicesCmd cmd) { - Long physicalNetworkId = cmd.getPhysicalNetworkId(); - Long niciraNvpDeviceId = cmd.getNiciraNvpDeviceId(); - List responseList = new ArrayList(); - - if (physicalNetworkId == null && niciraNvpDeviceId == null) { - throw new InvalidParameterValueException("Either physical network Id or nicira device Id must be specified"); - } - - if (niciraNvpDeviceId != null) { - NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraNvpDeviceId); - if (niciraNvpDevice == null) { - throw new InvalidParameterValueException("Could not find Nicira Nvp device with id: " + niciraNvpDevice); - } - responseList.add(niciraNvpDevice); - } - else { - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { - throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId); - } - responseList = _niciraNvpDao.listByPhysicalNetwork(physicalNetworkId); - } - - return responseList; - } - - @Override - public List listNiciraNvpDeviceNetworks(ListNiciraNvpDeviceNetworksCmd cmd) { - Long niciraDeviceId = cmd.getNiciraNvpDeviceId(); - NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraDeviceId); - if (niciraNvpDevice == null) { - throw new InvalidParameterValueException("Could not find a nicira device with id " + niciraDeviceId); - } - - // Find the physical network we work for - Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId(); - PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { - // No such physical network, so no provisioned networks - return Collections.emptyList(); - } - - // Find the nicira networks on this physical network - List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); - - // Networks with broadcast type lswitch are ours - List responseList = new ArrayList(); - for (NetworkVO network : networkList) { - if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) { - responseList.add(network); - } - } - - return responseList; - } - - @Override - public HostVO createHostVOForConnectedAgent(HostVO host, - StartupCommand[] cmd) { - // TODO Auto-generated method stub - return null; - } - - @Override - public HostVO createHostVOForDirectConnectAgent(HostVO host, - StartupCommand[] startup, ServerResource resource, - Map details, List hostTags) { - if (!(startup[0] instanceof StartupNiciraNvpCommand)) { - return null; - } - host.setType(Host.Type.L2Networking); - return host; - } - - @Override - public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, - boolean isForceDeleteStorage) throws UnableDeleteHostException { - if (!(host.getType() == Host.Type.L2Networking)) { - return null; - } - return new DeleteHostAnswer(true); - } + return answer.getResult(); + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java index 00ae1f69e30..a386ae53b47 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.guru; import java.net.URI; diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java index 2699b6db020..b1b1ebc3545 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.nicira; public abstract class Attachment { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/DestinationNatRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/DestinationNatRule.java new file mode 100644 index 00000000000..f1ea9052a41 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/DestinationNatRule.java @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +public class DestinationNatRule extends NatRule { + { + type = "DestinationNatRule"; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java new file mode 100644 index 00000000000..8b807fd9e72 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java @@ -0,0 +1,52 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +/** + * + */ +public class L3GatewayAttachment extends Attachment { + private String l3_gateway_service_uuid; + private String type = "L3GatewayAttachment"; + private Long vlan_id; + + public L3GatewayAttachment(String l3_gateway_service_uuid) { + this.l3_gateway_service_uuid = l3_gateway_service_uuid; + } + + public L3GatewayAttachment(String l3_gateway_service_uuid, long vlan_id) { + this.l3_gateway_service_uuid = l3_gateway_service_uuid; + this.vlan_id = vlan_id; + } + + public String getL3GatewayServiceUuid() { + return l3_gateway_service_uuid; + } + + public void setL3GatewayServiceUuid(String l3_gateway_service_uuid) { + this.l3_gateway_service_uuid = l3_gateway_service_uuid; + } + + public long getVlanId() { + return vlan_id; + } + + public void setVlanId(long vlan_id) { + this.vlan_id = vlan_id; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterConfig.java new file mode 100644 index 00000000000..897ee06b844 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterConfig.java @@ -0,0 +1,64 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +import java.util.List; + +/** + * + */ +public class LogicalRouterConfig { + private String display_name; + private RoutingConfig routing_config; + private String type = "LogicalRouterConfig"; + private String uuid; + private List tags; + + public RoutingConfig getRoutingConfig() { + return routing_config; + } + + public void setRoutingConfig(RoutingConfig routing_config) { + this.routing_config = routing_config; + } + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterPort.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterPort.java new file mode 100644 index 00000000000..196106dbe40 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalRouterPort.java @@ -0,0 +1,90 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +import java.util.List; + +/** + * + */ +public class LogicalRouterPort { + private String display_name; + private List tags; + private Integer portno; + private boolean admin_status_enabled; + private List ip_addresses; + private String mac_address; + private String type = "LogicalRouterPortConfig"; + private String uuid; + + public int getPortno() { + return portno; + } + + public void setPortno(int portno) { + this.portno = portno; + } + + public boolean isAdminStatusEnabled() { + return admin_status_enabled; + } + + public void setAdminStatusEnabled(boolean admin_status_enabled) { + this.admin_status_enabled = admin_status_enabled; + } + + public List getIpAddresses() { + return ip_addresses; + } + + public void setIpAddresses(List ip_addresses) { + this.ip_addresses = ip_addresses; + } + + public String getMacAddress() { + return mac_address; + } + + public void setMacAddress(String mac_address) { + this.mac_address = mac_address; + } + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java index 14d7753ab6c..f56518924b8 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.nicira; import java.util.List; diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java index f8cb5d62212..c5714585c99 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.nicira; import java.util.List; diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Match.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Match.java new file mode 100644 index 00000000000..ce5205ba47f --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Match.java @@ -0,0 +1,133 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +/** + * + */ +public class Match { + private Integer protocol; + private String source_ip_addresses; + private Boolean source_ip_addresses_not; + private String destination_ip_addresses; + private Boolean destination_ip_addresses_not; + private Integer source_port_min; + private Integer source_port_max; + private Boolean source_port_not; + private Integer destination_port_min; + private Integer destination_port_max; + private Boolean destination_port_not; + private String ethertype = "IPv4"; + + public Integer getProtocol() { + return protocol; + } + + public void setProtocol(Integer protocol) { + this.protocol = protocol; + } + + public Integer getSource_port_min() { + return source_port_min; + } + + public void setSourcePortMin(Integer source_port_min) { + this.source_port_min = source_port_min; + } + + public Integer getSourcePortMax() { + return source_port_max; + } + + public void setSourcePortMax(Integer source_port_max) { + this.source_port_max = source_port_max; + } + + public Boolean isSourcePortNot() { + return source_port_not; + } + + public void setSourcePortNot(Boolean source_port_not) { + this.source_port_not = source_port_not; + } + + public Integer getDestinationPortMin() { + return destination_port_min; + } + + public void setDestinationPortMin(Integer destination_port_min) { + this.destination_port_min = destination_port_min; + } + + public Integer getDestinationPortMax() { + return destination_port_max; + } + + public void setDestinationPortMax(Integer destination_port_max) { + this.destination_port_max = destination_port_max; + } + + public Boolean isDestinationPortNot() { + return destination_port_not; + } + + public void setDestinationPortNot(Boolean destination_port_not) { + this.destination_port_not = destination_port_not; + } + + public String getEthertype() { + return ethertype; + } + + public void setEthertype(String ethertype) { + this.ethertype = ethertype; + } + + public String getSourceIpAddresses() { + return source_ip_addresses; + } + + public void setSourceIpAddresses(String source_ip_addresses) { + this.source_ip_addresses = source_ip_addresses; + } + + public boolean isSourceIpAddressesNot() { + return source_ip_addresses_not; + } + + public void setSourceIpAddresses_not(boolean source_ip_addresses_not) { + this.source_ip_addresses_not = source_ip_addresses_not; + } + + public String getDestinationIpAddresses() { + return destination_ip_addresses; + } + + public void setDestinationIpAddresses(String destination_ip_addresses) { + this.destination_ip_addresses = destination_ip_addresses; + } + + public Boolean isDestinationIpAddressesNot() { + return destination_ip_addresses_not; + } + + public void setDestinationIpAddressesNot(Boolean destination_ip_addresses_not) { + this.destination_ip_addresses_not = destination_ip_addresses_not; + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java new file mode 100644 index 00000000000..7255ab67d39 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java @@ -0,0 +1,113 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +/** + * + */ +public class NatRule { + protected Match match; + protected String to_source_ip_address_min; + protected String to_source_ip_address_max; + protected Integer to_source_port_min; + protected Integer to_source_port_max; + protected String uuid; + protected String type; + protected String to_destination_ip_address_min; + protected String to_destination_ip_address_max; + protected Integer to_destination_port; + + public NatRule() {} + + public Match getMatch() { + return match; + } + + public void setMatch(Match match) { + this.match = match; + } + + public String getToSourceIpAddressMin() { + return to_source_ip_address_min; + } + + public void setToSourceIpAddressMin(String to_source_ip_address_min) { + this.to_source_ip_address_min = to_source_ip_address_min; + } + + public String getToSourceIpAddressMax() { + return to_source_ip_address_max; + } + + public void setToSourceIpAddressMax(String to_source_ip_address_max) { + this.to_source_ip_address_max = to_source_ip_address_max; + } + + public Integer getToSourcePortMin() { + return to_source_port_min; + } + + public void setToSourcePortMin(Integer to_source_port_min) { + this.to_source_port_min = to_source_port_min; + } + + public Integer getToSourcePortMax() { + return to_source_port_max; + } + + public void setToSourcePortMax(Integer to_source_port_max) { + this.to_source_port_max = to_source_port_max; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getToDestinationIpAddressMin() { + return to_destination_ip_address_min; + } + + public void setToDestinationIpAddressMin( + String to_destination_ip_address_min) { + this.to_destination_ip_address_min = to_destination_ip_address_min; + } + + public String getToDestinationIpAddressMax() { + return to_destination_ip_address_max; + } + + public void setToDestinationIpAddressMax( + String to_destination_ip_address_max) { + this.to_destination_ip_address_max = to_destination_ip_address_max; + } + + public Integer getToDestinationPort() { + return to_destination_port; + } + + public void setToDestinationPort(Integer to_destination_port) { + this.to_destination_port = to_destination_port; + } + + public String getType() { + return type; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index 2c002abdbff..6aeb8778f5b 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.nicira; import java.io.IOException; @@ -78,6 +61,7 @@ import com.google.gson.reflect.TypeToken; public class NiciraNvpApi { private static final Logger s_logger = Logger.getLogger(NiciraNvpApi.class); + private final static String _protocol = "https"; private String _name; private String _host; @@ -117,7 +101,7 @@ public class NiciraNvpApi { String url; try { - url = new URL("https", _host, "/ws.v1/login").toString(); + url = new URL(_protocol, _host, "/ws.v1/login").toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); @@ -180,7 +164,7 @@ public class NiciraNvpApi { NiciraNvpList lspl = executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); - if (lspl == null || lspl.getResult_count() != 1) { + if (lspl == null || lspl.getResultCount() != 1) { throw new NiciraNvpApiException("Unexpected response from API"); } @@ -210,11 +194,112 @@ public class NiciraNvpApi { return lspl; } + public LogicalRouterConfig createLogicalRouter(LogicalRouterConfig logicalRouterConfig) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter"; + + LogicalRouterConfig lrc = executeCreateObject(logicalRouterConfig, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + + return lrc; + } + + public void deleteLogicalRouter(String logicalRouterUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid; + + executeDeleteObject(uri); + } + + public LogicalRouterPort createLogicalRouterPort(String logicalRouterUuid, LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport"; + + LogicalRouterPort lrp = executeCreateObject(logicalRouterPort, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + return lrp; + } + + public void deleteLogicalRouterPort(String logicalRouterUuid, String logicalRouterPortUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPortUuid; + + executeDeleteObject(uri); + } + + public void modifyLogicalRouterPort(String logicalRouterUuid, LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPort.getUuid(); + + executeUpdateObject(logicalRouterPort, uri, Collections.emptyMap()); + } + + public void modifyLogicalRouterPortAttachment(String logicalRouterUuid, String logicalRouterPortUuid, Attachment attachment) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPortUuid + "/attachment"; + executeUpdateObject(attachment, uri, Collections.emptyMap()); + } + + public NatRule createLogicalRouterNatRule(String logicalRouterUuid, NatRule natRule) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat"; + + if (natRule instanceof SourceNatRule) { + return executeCreateObject(natRule, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + } + else if (natRule instanceof DestinationNatRule) { + return executeCreateObject(natRule, new TypeToken(){}.getType(), uri, Collections.emptyMap()); + } + + throw new NiciraNvpApiException("Unknown NatRule type"); + } + + public void modifyLogicalRouterNatRule(String logicalRouterUuid, NatRule natRule) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + natRule.getUuid(); + + executeUpdateObject(natRule, uri, Collections.emptyMap()); + } + + public void deleteLogicalRouterNatRule(String logicalRouterUuid, String natRuleUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + natRuleUuid; + + executeDeleteObject(uri); + } + + public NiciraNvpList findLogicalRouterPortByGatewayServiceAndVlanId(String logicalRouterUuid, String gatewayServiceUuid, long vlanId) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport"; + Map params = new HashMap(); + params.put("attachment_gwsvc_uuid", gatewayServiceUuid); + params.put("attachment_vlan", "0"); + params.put("fields","*"); + + return executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); + } + + public LogicalRouterConfig findOneLogicalRouterByUuid(String logicalRouterUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid; + + return executeRetrieveObject(new TypeToken(){}.getType(), uri, Collections.emptyMap()); + } + + public void updateLogicalRouterPortConfig(String logicalRouterUuid, LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport" + logicalRouterPort.getUuid(); + + executeUpdateObject(logicalRouterPort, uri, Collections.emptyMap()); + } + + public NiciraNvpList findNatRulesByLogicalRouterUuid(String logicalRouterUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat"; + Map params = new HashMap(); + params.put("fields","*"); + + return executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); + } + + public NiciraNvpList findLogicalRouterPortByGatewayServiceUuid(String logicalRouterUuid, String l3GatewayServiceUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport"; + Map params = new HashMap(); + params.put("fields", "*"); + params.put("attachment_gwsvc_uuid", l3GatewayServiceUuid); + + return executeRetrieveObject(new TypeToken>(){}.getType(), uri, params); + } private void executeUpdateObject(T newObject, String uri, Map parameters) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Connection to NVP Failed"); @@ -244,7 +329,7 @@ public class NiciraNvpApi { private T executeCreateObject(T newObject, Type returnObjectType, String uri, Map parameters) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); @@ -282,7 +367,7 @@ public class NiciraNvpApi { private void executeDeleteObject(String uri) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); @@ -303,7 +388,7 @@ public class NiciraNvpApi { private T executeRetrieveObject(Type returnObjectType, String uri, Map parameters) throws NiciraNvpApiException { String url; try { - url = new URL("https", _host, uri).toString(); + url = new URL(_protocol, _host, uri).toString(); } catch (MalformedURLException e) { s_logger.error("Unable to build Nicira API URL", e); throw new NiciraNvpApiException("Unable to build Nicira API URL", e); diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java index 13d352daba3..c97e40ecd81 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java @@ -30,12 +30,16 @@ public class NiciraNvpList { this.results = results; } - public int getResult_count() { + public int getResultCount() { return result_count; } - public void setResult_count(int result_count) { + public void setResultCount(int result_count) { this.result_count = result_count; - } + } + + public boolean isEmpty() { + return result_count == 0; + } } diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java index 81b752cc643..f8282b86d9c 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.nicira; public class NiciraNvpTag { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java new file mode 100644 index 00000000000..e57c2493f1c --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java @@ -0,0 +1,39 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +/** + * + */ +public class PatchAttachment extends Attachment { + private final String type = "PatchAttachment"; + private String peer_port_uuid; + + public PatchAttachment(String peerPortUuid) { + this.peer_port_uuid = peerPortUuid; + } + + public String getPeerPortUuid() { + return peer_port_uuid; + } + + public void setPeerPortUuid(String peerPortUuid) { + this.peer_port_uuid = peerPortUuid; + } + + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java new file mode 100644 index 00000000000..c018af37467 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +/** + * + */ +public class RouterNextHop { + private String gateway_ip_address; + private String type = "RouterNextHop"; + + public RouterNextHop(String gatewayIpAddress) { + this.gateway_ip_address = gatewayIpAddress; + } + + public String getGatewayIpAddress() { + return gateway_ip_address; + } + + public void setGatewayIpAddress(String gateway_ip_address) { + this.gateway_ip_address = gateway_ip_address; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java new file mode 100644 index 00000000000..c5eca5b9bc4 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java @@ -0,0 +1,21 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +public class RoutingConfig { + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java new file mode 100644 index 00000000000..b4eda447b13 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +/** + * + */ +public class SingleDefaultRouteImplictRoutingConfig extends RoutingConfig { + public RouterNextHop default_route_next_hop; + public String type = "SingleDefaultRouteImplicitRoutingConfig"; + + public SingleDefaultRouteImplictRoutingConfig(RouterNextHop routerNextHop) { + default_route_next_hop = routerNextHop; + } + + public RouterNextHop getDefaultRouteNextHop() { + return default_route_next_hop; + } + + public void setDefaultRouteNextHop(RouterNextHop default_route_next_hop) { + this.default_route_next_hop = default_route_next_hop; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java new file mode 100644 index 00000000000..acbf21e18af --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.network.nicira; + +/** + * + */ +public class SourceNatRule extends NatRule { + { + type = "SourceNatRule"; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java index f2e4b03a092..e55d759bdad 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.nicira; public class TransportZoneBinding { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java index b4dd0e71ba8..dc87a5a58ea 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java @@ -14,23 +14,6 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -/** Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 com.cloud.network.nicira; public class VifAttachment extends Attachment { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java index 31cac6f000c..c6359d37553 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java @@ -27,10 +27,20 @@ import org.apache.log4j.Logger; import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; +import com.cloud.agent.api.CreateLogicalRouterAnswer; +import com.cloud.agent.api.CreateLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalSwitchAnswer; import com.cloud.agent.api.CreateLogicalSwitchCommand; import com.cloud.agent.api.CreateLogicalSwitchPortAnswer; import com.cloud.agent.api.CreateLogicalSwitchPortCommand; +import com.cloud.agent.api.DeleteLogicalRouterAnswer; +import com.cloud.agent.api.DeleteLogicalRouterCommand; import com.cloud.agent.api.DeleteLogicalSwitchAnswer; import com.cloud.agent.api.DeleteLogicalSwitchCommand; import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer; @@ -46,19 +56,34 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer; import com.cloud.agent.api.UpdateLogicalSwitchPortCommand; +import com.cloud.agent.api.to.PortForwardingRuleTO; +import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.host.Host; import com.cloud.host.Host.Type; +import com.cloud.network.nicira.Attachment; import com.cloud.network.nicira.ControlClusterStatus; +import com.cloud.network.nicira.DestinationNatRule; +import com.cloud.network.nicira.L3GatewayAttachment; +import com.cloud.network.nicira.LogicalRouterConfig; +import com.cloud.network.nicira.LogicalRouterPort; import com.cloud.network.nicira.LogicalSwitch; import com.cloud.network.nicira.LogicalSwitchPort; +import com.cloud.network.nicira.Match; +import com.cloud.network.nicira.NatRule; import com.cloud.network.nicira.NiciraNvpApi; import com.cloud.network.nicira.NiciraNvpApiException; import com.cloud.network.nicira.NiciraNvpList; import com.cloud.network.nicira.NiciraNvpTag; +import com.cloud.network.nicira.PatchAttachment; +import com.cloud.network.nicira.RouterNextHop; +import com.cloud.network.nicira.SingleDefaultRouteImplictRoutingConfig; +import com.cloud.network.nicira.SourceNatRule; import com.cloud.network.nicira.TransportZoneBinding; import com.cloud.network.nicira.VifAttachment; import com.cloud.resource.ServerResource; +import edu.emory.mathcs.backport.java.util.Arrays; + public class NiciraNvpResource implements ServerResource { private static final Logger s_logger = Logger.getLogger(NiciraNvpResource.class); @@ -197,6 +222,21 @@ public class NiciraNvpResource implements ServerResource { else if (cmd instanceof FindLogicalSwitchPortCommand) { return executeRequest((FindLogicalSwitchPortCommand) cmd, numRetries); } + else if (cmd instanceof CreateLogicalRouterCommand) { + return executeRequest((CreateLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof DeleteLogicalRouterCommand) { + return executeRequest((DeleteLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof ConfigureStaticNatRulesOnLogicalRouterCommand) { + return executeRequest((ConfigureStaticNatRulesOnLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof ConfigurePortForwardingRulesOnLogicalRouterCommand) { + return executeRequest((ConfigurePortForwardingRulesOnLogicalRouterCommand) cmd, numRetries); + } + else if (cmd instanceof ConfigurePublicIpsOnLogicalRouterCommand) { + return executeRequest((ConfigurePublicIpsOnLogicalRouterCommand) cmd, numRetries); + } s_logger.debug("Received unsupported command " + cmd.toString()); return Answer.createUnsupportedCommandAnswer(cmd); } @@ -216,7 +256,7 @@ public class NiciraNvpResource implements ServerResource { private Answer executeRequest(CreateLogicalSwitchCommand cmd, int numRetries) { LogicalSwitch logicalSwitch = new LogicalSwitch(); - logicalSwitch.setDisplay_name("lswitch-" + cmd.getName()); + logicalSwitch.setDisplay_name(truncate("lswitch-" + cmd.getName(), 40)); logicalSwitch.setPort_isolation_enabled(false); // Set transport binding @@ -324,7 +364,7 @@ public class NiciraNvpResource implements ServerResource { try { NiciraNvpList ports = _niciraNvpApi.findLogicalSwitchPortsByUuid(logicalSwitchUuid, logicalSwitchPortUuid); - if (ports.getResult_count() == 0) { + if (ports.getResultCount() == 0) { return new FindLogicalSwitchPortAnswer(cmd, false, "Logical switchport " + logicalSwitchPortUuid + " not found", null); } else { @@ -340,6 +380,367 @@ public class NiciraNvpResource implements ServerResource { } } + private Answer executeRequest(CreateLogicalRouterCommand cmd, int numRetries) { + String routerName = cmd.getName(); + String gatewayServiceUuid = cmd.getGatewayServiceUuid(); + String logicalSwitchUuid = cmd.getLogicalSwitchUuid(); + + List tags = new ArrayList(); + tags.add(new NiciraNvpTag("cs_account",cmd.getOwnerName())); + + String publicNetworkNextHopIp = cmd.getPublicNextHop(); + String publicNetworkIpAddress = cmd.getPublicIpCidr(); + String internalNetworkAddress = cmd.getInternalIpCidr(); + + s_logger.debug("Creating a logical router with external ip " + + publicNetworkIpAddress + " and internal ip " + internalNetworkAddress + + "on gateway service " + gatewayServiceUuid); + + try { + // Create the Router + LogicalRouterConfig lrc = new LogicalRouterConfig(); + lrc.setDisplayName(truncate(routerName, 40)); + lrc.setTags(tags); + lrc.setRoutingConfig(new SingleDefaultRouteImplictRoutingConfig( + new RouterNextHop(publicNetworkNextHopIp))); + lrc = _niciraNvpApi.createLogicalRouter(lrc); + + try { + // Create the outside port for the router + LogicalRouterPort lrpo = new LogicalRouterPort(); + lrpo.setAdminStatusEnabled(true); + lrpo.setDisplayName(truncate(routerName + "-outside-port", 40)); + lrpo.setTags(tags); + List outsideIpAddresses = new ArrayList(); + outsideIpAddresses.add(publicNetworkIpAddress); + lrpo.setIpAddresses(outsideIpAddresses); + lrpo = _niciraNvpApi.createLogicalRouterPort(lrc.getUuid(),lrpo); + + // Attach the outside port to the gateway service on the correct VLAN + L3GatewayAttachment attachment = new L3GatewayAttachment(gatewayServiceUuid); + if (cmd.getVlanId() != 0) { + attachment.setVlanId(cmd.getVlanId()); + } + _niciraNvpApi.modifyLogicalRouterPortAttachment(lrc.getUuid(), lrpo.getUuid(), attachment); + + // Create the inside port for the router + LogicalRouterPort lrpi = new LogicalRouterPort(); + lrpi.setAdminStatusEnabled(true); + lrpi.setDisplayName(truncate(routerName + "-inside-port", 40)); + lrpi.setTags(tags); + List insideIpAddresses = new ArrayList(); + insideIpAddresses.add(internalNetworkAddress); + lrpi.setIpAddresses(insideIpAddresses); + lrpi = _niciraNvpApi.createLogicalRouterPort(lrc.getUuid(),lrpi); + + // Create the inside port on the lswitch + LogicalSwitchPort lsp = new LogicalSwitchPort(truncate(routerName + "-inside-port", 40), tags, true); + lsp = _niciraNvpApi.createLogicalSwitchPort(logicalSwitchUuid, lsp); + + // Attach the inside router port to the lswitch port with a PatchAttachment + _niciraNvpApi.modifyLogicalRouterPortAttachment(lrc.getUuid(), lrpi.getUuid(), + new PatchAttachment(lsp.getUuid())); + + // Attach the inside lswitch port to the router with a PatchAttachment + _niciraNvpApi.modifyLogicalSwitchPortAttachment(logicalSwitchUuid, lsp.getUuid(), + new PatchAttachment(lrpi.getUuid())); + + // Setup the source nat rule + SourceNatRule snr = new SourceNatRule(); + snr.setToSourceIpAddressMin(publicNetworkIpAddress.split("/")[0]); + snr.setToSourceIpAddressMax(publicNetworkIpAddress.split("/")[0]); + Match match = new Match(); + match.setSourceIpAddresses(internalNetworkAddress); + snr.setMatch(match); + _niciraNvpApi.createLogicalRouterNatRule(lrc.getUuid(), snr); + } catch (NiciraNvpApiException e) { + // We need to destroy the router if we already created it + // this will also take care of any router ports + // TODO Clean up the switchport + try { + _niciraNvpApi.deleteLogicalRouter(lrc.getUuid()); + } catch (NiciraNvpApiException ex) {} + + throw e; + } + + return new CreateLogicalRouterAnswer(cmd, true, "Logical Router created (uuid " + lrc.getUuid() + ")", lrc.getUuid()); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new CreateLogicalRouterAnswer(cmd, e); + } + } + } + + private Answer executeRequest(DeleteLogicalRouterCommand cmd, int numRetries) { + try { + _niciraNvpApi.deleteLogicalRouter(cmd.getLogicalRouterUuid()); + return new DeleteLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new DeleteLogicalRouterAnswer(cmd, e); + } + } + } + + private Answer executeRequest(ConfigurePublicIpsOnLogicalRouterCommand cmd, int numRetries) { + try { + NiciraNvpList ports = _niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(cmd.getLogicalRouterUuid(), cmd.getL3GatewayServiceUuid()); + if (ports.getResultCount() != 1) { + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, false, "No logical router ports found, unable to set ip addresses"); + } + LogicalRouterPort lrp = ports.getResults().get(0); + lrp.setIpAddresses(cmd.getPublicCidrs()); + _niciraNvpApi.modifyLogicalRouterPort(cmd.getLogicalRouterUuid(), lrp); + + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(ConfigureStaticNatRulesOnLogicalRouterCommand cmd, int numRetries) { + try { + NiciraNvpList existingRules = _niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); + // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) + // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule + // Any other SourceNat rule should have a corresponding DestinationNat rule + + for (StaticNatRuleTO rule : cmd.getRules()) { + // Find if a DestinationNat rule exists for this rule + String insideIp = rule.getDstIp(); + String insideCidr = rule.getDstIp() + "/32"; + String outsideIp = rule.getSrcIp(); + String outsideCidr = rule.getSrcIp() + "/32"; + + NatRule incoming = null; + NatRule outgoing = null; + + for (NatRule storedRule : existingRules.getResults()) { + if ("SourceNatRule".equals(storedRule.getType())) { + if (outsideIp.equals(storedRule.getToSourceIpAddressMin()) && + outsideIp.equals(storedRule.getToSourceIpAddressMax()) && + storedRule.getToSourcePortMin() == null) { + // The outgoing rule exists + outgoing = storedRule; + } + } + if ("DestinationNatRule".equals(storedRule.getType()) && + storedRule.getToDestinationPort() != null) { + // Skip PortForwarding rules + continue; + } + // Compare against Ip as it should be a /32 cidr and the /32 is omitted + if (outsideIp.equals(storedRule.getMatch().getDestinationIpAddresses())) { + // The incoming rule exists + incoming = storedRule; + } + } + if (incoming != null && outgoing != null) { + if (insideIp.equals(incoming.getToDestinationIpAddressMin())) { + if (rule.revoked()) { + s_logger.debug("Deleting incoming rule " + incoming.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming.getUuid()); + + s_logger.debug("Deleting outgoing rule " + outgoing.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing.getUuid()); + } + } + else { + s_logger.debug("Updating outgoing rule " + outgoing.getUuid()); + outgoing.setToDestinationIpAddressMin(insideIp); + outgoing.setToDestinationIpAddressMax(insideIp); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing); + + s_logger.debug("Updating incoming rule " + outgoing.getUuid()); + incoming.setToSourceIpAddressMin(insideIp); + incoming.setToSourceIpAddressMax(insideIp); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming); + break; + } + } + else { + if (rule.revoked()) { + s_logger.warn("Tried deleting a rule that does not exist, " + + rule.getSrcIp() + " -> " + rule.getDstIp()); + break; + } + + // api createLogicalRouterNatRule + // create the dnat rule + Match m = new Match(); + m.setDestinationIpAddresses(outsideCidr); + DestinationNatRule newDnatRule = new DestinationNatRule(); + newDnatRule.setMatch(m); + newDnatRule.setToDestinationIpAddressMin(insideIp); + newDnatRule.setToDestinationIpAddressMax(insideIp); + newDnatRule = (DestinationNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newDnatRule); + s_logger.debug("Created " + natRuleToString(newDnatRule)); + + // create matching snat rule + m = new Match(); + m.setSourceIpAddresses(insideIp + "/32"); + SourceNatRule newSnatRule = new SourceNatRule(); + newSnatRule.setMatch(m); + newSnatRule.setToSourceIpAddressMin(outsideIp); + newSnatRule.setToSourceIpAddressMax(outsideIp); + newSnatRule = (SourceNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newSnatRule); + s_logger.debug("Created " + natRuleToString(newSnatRule)); + + } + } + return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() +" StaticNat rules applied"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, e); + } + } + + } + + private Answer executeRequest(ConfigurePortForwardingRulesOnLogicalRouterCommand cmd, int numRetries) { + try { + NiciraNvpList existingRules = _niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); + // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) + // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule + // Any other SourceNat rule should have a corresponding DestinationNat rule + + for (PortForwardingRuleTO rule : cmd.getRules()) { + if (rule.isAlreadyAdded()) { + // Don't need to do anything + continue; + } + + // Find if a DestinationNat rule exists for this rule + String insideIp = rule.getDstIp(); + String insideCidr = rule.getDstIp() + "/32"; + String outsideIp = rule.getSrcIp(); + String outsideCidr = rule.getSrcIp() + "/32"; + + NatRule incoming = null; + NatRule outgoing = null; + + for (NatRule storedRule : existingRules.getResults()) { + if ("SourceNatRule".equals(storedRule.getType())) { + if (outsideIp.equals(storedRule.getToSourceIpAddressMin()) && + outsideIp.equals(storedRule.getToSourceIpAddressMax()) && + storedRule.getToSourcePortMin() == rule.getSrcPortRange()[0] && + storedRule.getToSourcePortMax() == rule.getSrcPortRange()[1]) { + // The outgoing rule exists + outgoing = storedRule; + } + } + else if ("DestinationNatRule".equals(storedRule.getType())) { + if (insideIp.equals(storedRule.getToDestinationIpAddressMin()) && + insideIp.equals(storedRule.getToDestinationIpAddressMax()) && + storedRule.getToDestinationPort() == rule.getDstPortRange()[0]) { + // The incoming rule exists + incoming = storedRule; + } + } + } + if (incoming != null && outgoing != null) { + if (insideIp.equals(incoming.getToDestinationIpAddressMin())) { + if (rule.revoked()) { + s_logger.debug("Deleting incoming rule " + incoming.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming.getUuid()); + + s_logger.debug("Deleting outgoing rule " + outgoing.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing.getUuid()); + } + } + else { + s_logger.debug("Updating outgoing rule " + outgoing.getUuid()); + outgoing.setToDestinationIpAddressMin(insideIp); + outgoing.setToDestinationIpAddressMax(insideIp); + outgoing.setToDestinationPort(rule.getDstPortRange()[0]); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing); + + s_logger.debug("Updating incoming rule " + outgoing.getUuid()); + incoming.setToSourceIpAddressMin(insideIp); + incoming.setToSourceIpAddressMax(insideIp); + incoming.setToSourcePortMin(rule.getSrcPortRange()[0]); + incoming.setToSourcePortMax(rule.getSrcPortRange()[1]); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming); + break; + } + } + else { + if (rule.revoked()) { + s_logger.warn("Tried deleting a rule that does not exist, " + + rule.getSrcIp() + " -> " + rule.getDstIp()); + break; + } + + // api createLogicalRouterNatRule + // create the dnat rule + Match m = new Match(); + m.setDestinationIpAddresses(outsideCidr); + if ("tcp".equals(rule.getProtocol())) { + m.setProtocol(6); + } + else if ("udp".equals(rule.getProtocol())) { + m.setProtocol(17); + } + m.setDestinationPortMin(rule.getSrcPortRange()[0]); + m.setDestinationPortMax(rule.getSrcPortRange()[1]); + DestinationNatRule newDnatRule = new DestinationNatRule(); + newDnatRule.setMatch(m); + newDnatRule.setToDestinationIpAddressMin(insideIp); + newDnatRule.setToDestinationIpAddressMax(insideIp); + newDnatRule.setToDestinationPort(rule.getDstPortRange()[0]); + newDnatRule = (DestinationNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newDnatRule); + s_logger.debug("Created " + natRuleToString(newDnatRule)); + + // create matching snat rule + m = new Match(); + m.setSourceIpAddresses(insideIp + "/32"); + if ("tcp".equals(rule.getProtocol())) { + m.setProtocol(6); + } + else if ("udp".equals(rule.getProtocol())) { + m.setProtocol(17); + } + m.setSourcePortMin(rule.getDstPortRange()[0]); + m.setSourcePortMax(rule.getDstPortRange()[1]); + SourceNatRule newSnatRule = new SourceNatRule(); + newSnatRule.setMatch(m); + newSnatRule.setToSourceIpAddressMin(outsideIp); + newSnatRule.setToSourceIpAddressMax(outsideIp); + newSnatRule.setToSourcePortMin(rule.getSrcPortRange()[0]); + newSnatRule.setToSourcePortMax(rule.getSrcPortRange()[1]); + newSnatRule = (SourceNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newSnatRule); + s_logger.debug("Created " + natRuleToString(newSnatRule)); + + } + } + return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() +" PortForwarding rules applied"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, e); + } + } + + } + private Answer executeRequest(ReadyCommand cmd) { return new ReadyAnswer(cmd); } @@ -354,4 +755,58 @@ public class NiciraNvpResource implements ServerResource { return executeRequest(cmd, numRetriesRemaining); } + private String natRuleToString(NatRule rule) { + + StringBuilder natRuleStr = new StringBuilder(); + natRuleStr.append("Rule "); + natRuleStr.append(rule.getUuid()); + natRuleStr.append(" ("); + natRuleStr.append(rule.getType()); + natRuleStr.append(") :"); + Match m = rule.getMatch(); + natRuleStr.append("match ("); + natRuleStr.append(m.getProtocol()); + natRuleStr.append(" "); + natRuleStr.append(m.getSourceIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getSource_port_min()); + natRuleStr.append("-"); + natRuleStr.append(m.getSourcePortMax()); + natRuleStr.append(" ] -> "); + natRuleStr.append(m.getDestinationIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getDestinationPortMin()); + natRuleStr.append("-"); + natRuleStr.append(m.getDestinationPortMax()); + natRuleStr.append(" ]) -->"); + if ("SourceNatRule".equals(rule.getType())) { + natRuleStr.append(rule.getToSourceIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToSourceIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(rule.getToSourcePortMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToSourcePortMax()); + natRuleStr.append(" ])"); + } + else { + natRuleStr.append(rule.getToDestinationIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToDestinationIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(rule.getToDestinationPort()); + natRuleStr.append(" ])"); + } + return natRuleStr.toString(); + } + + private String truncate(String string, int length) { + if (string.length() <= length) { + return string; + } + else { + return string.substring(0, length); + } + } + } diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index 02d455c2b54..ab7ffab8465 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-network-ovs Apache CloudStack Plugin - Open vSwitch org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java index bf785e6710c..b7a978e72d6 100644 --- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java +++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java @@ -47,7 +47,7 @@ public class OvsElement extends AdapterBase implements NetworkElement { OvsTunnelManager _ovsTunnelMgr; @Override - public boolean destroy(Network network) + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } diff --git a/plugins/pom.xml b/plugins/pom.xml index 206d4a1c1aa..dbdea24e17b 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -16,8 +16,7 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloudstack-plugins Apache CloudStack Plugin POM @@ -25,11 +24,12 @@ org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT install src + test deployment-planners/user-concentrated-pod diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index 6cb60cdf7ff..b476d1de49f 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-storage-allocator-random Apache CloudStack Plugin - Storage Allocator Random org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index 7facc3f3307..05e9466d825 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-user-authenticator-ldap Apache CloudStack Plugin - User Authenticator LDAP org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index 1dac92d7e3f..f358f8f1c21 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-user-authenticator-md5 Apache CloudStack Plugin - User Authenticator MD5 org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index a4280a37d26..6406fa92489 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-plugin-user-authenticator-plaintext Apache CloudStack Plugin - User Authenticator Plain Text org.apache.cloudstack cloudstack-plugins - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index dc23d5482e7..c90143c6d94 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT pom Apache CloudStack CloudStack is an IaaS (“Infrastracture as a Service”) cloud orchestration platform. @@ -74,11 +74,13 @@ 1.4 1.4 1.5.1 + 1.5.1 1.2.8 2.0.4 2.4 1.2 1.0-20081010.060147 + 4.1 true @@ -156,6 +158,7 @@ plugins awsapi patches + client test framework/events @@ -176,7 +179,7 @@ org.apache.tomcat.maven tomcat7-maven-plugin - 2.0-SNAPSHOT + 2.0 org.apache.rat @@ -184,20 +187,28 @@ 0.8 0 - true + false + CHANGES + INSTALL.md + **/.classpath + **/.project + **/.settings/** + .metadata/** .git/** .gitignore **/*.crt **/*.csr **/*.key **/authorized_keys + **/*.war **/*.mar **/*.jar **/*.iso **/*.tgz **/*.zip **/target/** + **/.vagrant build/build.number console-proxy/js/jquery.js debian/compat @@ -209,52 +220,6 @@ deps/XenServerJava/Makefile dist/console-proxy/js/jquery.js scripts/vm/systemvm/id_rsa.cloud - patches/systemvm/debian/xe/xen-vcpu-hotplug.rules - patches/systemvm/debian/xe/xe-linux-distribution.init - patches/systemvm/debian/systemvm.vmx - patches/systemvm/debian/config/etc/ssh/sshd_config - patches/systemvm/debian/config/etc/logrotate.d/haproxy - patches/systemvm/debian/config/etc/logrotate.d/dnsmasq - patches/systemvm/debian/config/etc/logrotate.d/apache2 - patches/systemvm/debian/config/etc/logrotate.d/ppp - patches/systemvm/debian/config/etc/logrotate.d/rsyslog - patches/systemvm/debian/config/etc/vpcdnsmasq.conf - patches/systemvm/debian/config/etc/httpd/conf/httpd.conf - patches/systemvm/debian/config/etc/haproxy/haproxy.cfg - patches/systemvm/debian/config/etc/apache2/vhostexample.conf - patches/systemvm/debian/config/etc/apache2/sites-available/default-ssl - patches/systemvm/debian/config/etc/apache2/sites-available/default - patches/systemvm/debian/config/etc/apache2/httpd.conf - patches/systemvm/debian/config/etc/apache2/ports.conf - patches/systemvm/debian/config/etc/rsyslog.conf - patches/systemvm/debian/config/etc/cloud-nic.rules - patches/systemvm/debian/config/etc/logrotate.conf - patches/systemvm/debian/config/etc/init.d/postinit - patches/systemvm/debian/config/etc/modprobe.d/aesni_intel - patches/systemvm/debian/config/etc/sysctl.conf - patches/systemvm/debian/config/etc/dnsmasq.conf - patches/systemvm/debian/config/etc/rc.local - patches/systemvm/debian/config/root/redundant_router/heartbeat.sh.templ - patches/systemvm/debian/config/root/redundant_router/keepalived.conf.templ - patches/systemvm/debian/config/root/redundant_router/check_heartbeat.sh.templ - patches/systemvm/debian/config/root/redundant_router/backup.sh.templ - patches/systemvm/debian/config/root/redundant_router/arping_gateways.sh.templ - patches/systemvm/debian/config/root/redundant_router/fault.sh.templ - patches/systemvm/debian/config/root/redundant_router/checkrouter.sh.templ - patches/systemvm/debian/config/root/redundant_router/master.sh.templ - patches/systemvm/debian/config/root/redundant_router/conntrackd.conf.templ - patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ - patches/systemvm/debian/config/var/lib/misc/dnsmasq.leases - patches/systemvm/debian/config/var/www/html/userdata/.htaccess - patches/systemvm/debian/config/var/www/html/latest/.htaccess - patches/systemvm/debian/vpn/etc/ipsec.conf.orig - patches/systemvm/debian/vpn/etc/ipsec.secrets.orig - patches/systemvm/debian/vpn/etc/ipsec.conf - patches/systemvm/debian/vpn/etc/ipsec.d/l2tp.conf - patches/systemvm/debian/vpn/etc/ppp/options.xl2tpd - patches/systemvm/debian/vpn/etc/xl2tpd/xl2tpd.conf - patches/systemvm/debian/vpn/etc/xl2tpd/xl2tpd.conf.orig - patches/systemvm/debian/vpn/etc/ipsec.secrets tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf tools/devcloud/devcloud.cfg ui/lib/flot/jquery.colorhelpers.js @@ -281,6 +246,38 @@ ui/lib/qunit/qunit.js ui/lib/reset.css waf + patches/systemvm/debian/systemvm.vmx + patches/systemvm/debian/config/root/.ssh/authorized_keys + patches/systemvm/debian/config/etc/apache2/httpd.conf + patches/systemvm/debian/config/etc/apache2/ports.conf + patches/systemvm/debian/config/etc/apache2/sites-available/default + patches/systemvm/debian/config/etc/apache2/sites-available/default-ssl + patches/systemvm/debian/config/etc/apache2/vhostexample.conf + patches/systemvm/debian/config/etc/dnsmasq.conf + patches/systemvm/debian/config/etc/vpcdnsmasq.conf + patches/systemvm/debian/config/etc/ssh/sshd_config + + patches/systemvm/debian/config/etc/rsyslog.conf + + patches/systemvm/debian/config/etc/logrotate.conf + patches/systemvm/debian/config/etc/logrotate.d/* + patches/systemvm/debian/config/etc/sysctl.conf + patches/systemvm/debian/config/root/redundant_router/keepalived.conf.templ + patches/systemvm/debian/config/root/redundant_router/arping_gateways.sh.templ + patches/systemvm/debian/config/root/redundant_router/conntrackd.conf.templ + + patches/systemvm/debian/vpn/etc/ipsec.conf + patches/systemvm/debian/vpn/etc/ppp/options.xl2tpd + patches/systemvm/debian/vpn/etc/xl2tpd/xl2tpd.conf + patches/systemvm/debian/vpn/etc/ipsec.secrets + patches/systemvm/debian/config/etc/haproxy/haproxy.cfg + patches/systemvm/debian/config/etc/cloud-nic.rules + patches/systemvm/debian/config/etc/modprobe.d/aesni_intel + patches/systemvm/debian/config/etc/rc.local + patches/systemvm/debian/config/var/www/html/userdata/.htaccess + patches/systemvm/debian/config/var/www/html/latest/.htaccess + patches/systemvm/debian/vpn/etc/ipsec.d/l2tp.conf + @@ -291,41 +288,78 @@ ${cs.jdk.version} ${cs.jdk.version} + true + 128m + 512m - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - remove-old-installers - - remove-project-artifact - - - true - - - - + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + true + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + remove-old-installers + + remove-project-artifact + + + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.5.1 + - - client - - client - - + deps deps + + developer + + developer + tools/apidoc + tools/devcloud + tools/marvin + + + + vmware + + + nonoss + + + + vmware-base + + + diff --git a/python/lib/cloudutils/serviceConfig.py b/python/lib/cloudutils/serviceConfig.py index 4c36038ff71..6b211eb5074 100755 --- a/python/lib/cloudutils/serviceConfig.py +++ b/python/lib/cloudutils/serviceConfig.py @@ -703,7 +703,7 @@ class firewallConfigServer(firewallConfigBase): if self.syscfg.env.svrMode == "myCloud": self.ports = "443 8080 8250 8443 9090".split() else: - self.ports = "8080 8250 9090".split() + self.ports = "8080 7080 8250 9090".split() class ubuntuFirewallConfigServer(firewallConfigServer): def allowPort(self, port): diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt index 188896e28f9..63a04d8cb07 100755 --- a/scripts/storage/secondary/cloud-install-sys-tmplt +++ b/scripts/storage/secondary/cloud-install-sys-tmplt @@ -33,7 +33,7 @@ failed() { mflag= fflag= ext="vhd" -templateId=1 +templateId= hyper= msKey=password DISKSPACE=5120000 #free disk space required in kilobytes @@ -143,21 +143,24 @@ else fi fi -if [ "$hyper" == "kvm" ] +if [ "$templateId" == "" ] then - ext="qcow2" - templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"KVM\" and removed is null"`) -elif [ "$hyper" == "xenserver" ] -then - ext="vhd" - templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"XenServer\" and removed is null"`) -elif [ "$hyper" == "vmware" ] -then - ext="ova" - templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"VMware\" and removed is null"`) -else - usage - failed 2 + if [ "$hyper" == "kvm" ] + then + ext="qcow2" + templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"KVM\" and removed is null"`) + elif [ "$hyper" == "xenserver" ] + then + ext="vhd" + templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"XenServer\" and removed is null"`) + elif [ "$hyper" == "vmware" ] + then + ext="ova" + templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"VMware\" and removed is null"`) + else + usage + failed 2 + fi fi if [ ! $templateId ] diff --git a/scripts/vm/hypervisor/xenserver/vhd-util b/scripts/vm/hypervisor/xenserver/vhd-util deleted file mode 100755 index 46d62dd44d9..00000000000 Binary files a/scripts/vm/hypervisor/xenserver/vhd-util and /dev/null differ diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index e3f3e336e92..21c73ac8dc2 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -360,6 +360,26 @@ def createFile(session, args): return txt +@echo +def createFileInDomr(session, args): + file_path = args['filepath'] + file_contents = args['filecontents'] + domrip = args['domrip'] + try: + tmpfile = util.pread2(['mktemp']).strip() + f = open(tmpfile, "w") + f.write(file_contents) + f.close() + target = "root@" + domrip + ":" + file_path + util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) + util.pread2(['rm',tmpfile]) + txt = 'success' + except: + util.SMlog(" failed to create HA proxy cfg file ") + txt = '' + + return txt + @echo def deleteFile(session, args): file_path = args["filepath"] @@ -1452,4 +1472,5 @@ if __name__ == "__main__": "setLinkLocalIP":setLinkLocalIP, "cleanup_rules":cleanup_rules, "bumpUpPriority":bumpUpPriority, + "createFileInDomr":createFileInDomr, "kill_copy_process":kill_copy_process}) diff --git a/scripts/vm/hypervisor/xenserver/xcposs/NFSSR.py b/scripts/vm/hypervisor/xenserver/xcposs/NFSSR.py index 7342aaf863e..627fed24043 100644 --- a/scripts/vm/hypervisor/xenserver/xcposs/NFSSR.py +++ b/scripts/vm/hypervisor/xenserver/xcposs/NFSSR.py @@ -40,8 +40,8 @@ CONFIGURATION = [ [ 'server', 'hostname or IP address of NFS server (required)' DRIVER_INFO = { 'name': 'NFS VHD', 'description': 'SR plugin which stores disks as VHD files on a remote NFS filesystem', - 'vendor': 'Citrix Systems Inc', - 'copyright': '(C) 2008 Citrix Systems Inc', + 'vendor': 'The Apache Software Foundation', + 'copyright': 'Copyright (c) 2012 The Apache Software Foundation', 'driver_version': '1.0', 'required_api_version': '1.0', 'capabilities': CAPABILITIES, diff --git a/scripts/vm/hypervisor/xenserver/xcposs/patch b/scripts/vm/hypervisor/xenserver/xcposs/patch index 2ab94219498..6dc3baae555 100644 --- a/scripts/vm/hypervisor/xenserver/xcposs/patch +++ b/scripts/vm/hypervisor/xenserver/xcposs/patch @@ -64,3 +64,4 @@ cloud-prepare-upgrade.sh=..,0755,/usr/lib/xcp/bin getRouterStatus.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin bumpUpPriority.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin getDomRVersion.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin +router_proxy.sh=../../../../network/domr/,0755,/usr/lib/xcp/bin diff --git a/scripts/vm/hypervisor/xenserver/xcposs/vmops b/scripts/vm/hypervisor/xenserver/xcposs/vmops index c8e6013f532..52625e181e1 100644 --- a/scripts/vm/hypervisor/xenserver/xcposs/vmops +++ b/scripts/vm/hypervisor/xenserver/xcposs/vmops @@ -1515,6 +1515,22 @@ def createISOVHD(session, args): session.xenapi.VBD.destroy(vbd) return vdi_uuid +@echo +def routerProxy(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/usr/lib/xcp/bin/router_proxy.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + if txt is None or len(txt) == 0 : + txt = 'success' + except: + util.SMlog("routerProxy command " + sargs + " failed " ) + txt = '' + + return txt + @echo def getDomRVersion(session, args): sargs = args['args'] @@ -1546,4 +1562,5 @@ if __name__ == "__main__": "bumpUpPriority":bumpUpPriority, "getDomRVersion":getDomRVersion, "kill_copy_process":kill_copy_process, "createISOVHD":createISOVHD, + "routerProxy":routerProxy, "setDNATRule":setDNATRule}) diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/NFSSR.py b/scripts/vm/hypervisor/xenserver/xcpserver/NFSSR.py index 3ed557d3259..11f0491572e 100755 --- a/scripts/vm/hypervisor/xenserver/xcpserver/NFSSR.py +++ b/scripts/vm/hypervisor/xenserver/xcpserver/NFSSR.py @@ -40,8 +40,8 @@ CONFIGURATION = [ [ 'server', 'hostname or IP address of NFS server (required)' DRIVER_INFO = { 'name': 'NFS VHD', 'description': 'SR plugin which stores disks as VHD files on a remote NFS filesystem', - 'vendor': 'Citrix Systems Inc', - 'copyright': '(C) 2008 Citrix Systems Inc', + 'vendor': 'The Apache Software Foundation', + 'copyright': 'Copyright (c) 2012 The Apache Software Foundation', 'driver_version': '1.0', 'required_api_version': '1.0', 'capabilities': CAPABILITIES, diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/NFSSR.py b/scripts/vm/hypervisor/xenserver/xenserver56/NFSSR.py index 75da34b8c79..a9cd58d9ca6 100755 --- a/scripts/vm/hypervisor/xenserver/xenserver56/NFSSR.py +++ b/scripts/vm/hypervisor/xenserver/xenserver56/NFSSR.py @@ -40,8 +40,8 @@ CONFIGURATION = [ [ 'server', 'hostname or IP address of NFS server (required)' DRIVER_INFO = { 'name': 'NFS VHD', 'description': 'SR plugin which stores disks as VHD files on a remote NFS filesystem', - 'vendor': 'Citrix Systems Inc', - 'copyright': '(C) 2008 Citrix Systems Inc', + 'vendor': 'The Apache Software Foundation', + 'copyright': 'Copyright (c) 2012 The Apache Software Foundation', 'driver_version': '1.0', 'required_api_version': '1.0', 'capabilities': CAPABILITIES, diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/NFSSR.py b/scripts/vm/hypervisor/xenserver/xenserver56fp1/NFSSR.py index e4139535517..290c587aac4 100755 --- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/NFSSR.py +++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/NFSSR.py @@ -41,8 +41,8 @@ CONFIGURATION = [ [ 'server', 'hostname or IP address of NFS server (required)' DRIVER_INFO = { 'name': 'NFS VHD', 'description': 'SR plugin which stores disks as VHD files on a remote NFS filesystem', - 'vendor': 'Citrix Systems Inc', - 'copyright': '(C) 2008 Citrix Systems Inc', + 'vendor': 'The Apache Software Foundation', + 'copyright': 'Copyright (c) 2012 The Apache Software Foundation', 'driver_version': '1.0', 'required_api_version': '1.0', 'capabilities': CAPABILITIES, diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py b/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py index 5838aceef64..0d6badb4098 100755 --- a/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py +++ b/scripts/vm/hypervisor/xenserver/xenserver60/NFSSR.py @@ -42,8 +42,8 @@ CONFIGURATION = [ [ 'server', 'hostname or IP address of NFS server (required)' DRIVER_INFO = { 'name': 'NFS VHD', 'description': 'SR plugin which stores disks as VHD files on a remote NFS filesystem', - 'vendor': 'Citrix Systems Inc', - 'copyright': '(C) 2008 Citrix Systems Inc', + 'vendor': 'The Apache Software Foundation', + 'copyright': 'Copyright (c) 2012 The Apache Software Foundation', 'driver_version': '1.0', 'required_api_version': '1.0', 'capabilities': CAPABILITIES, diff --git a/scripts/vm/network/vnet/modifyvlan.sh b/scripts/vm/network/vnet/modifyvlan.sh index 33d697a47bd..5577825ea54 100755 --- a/scripts/vm/network/vnet/modifyvlan.sh +++ b/scripts/vm/network/vnet/modifyvlan.sh @@ -22,15 +22,14 @@ # set -x usage() { - printf "Usage: %s: -o (add | delete) -v -p \n" + printf "Usage: %s: -o (add | delete) -v -p -b \n" } -VIRBR=cloudVirBr addVlan() { local vlanId=$1 local pif=$2 local vlanDev=$pif.$vlanId - local vlanBr=$VIRBR$vlanId + local vlanBr=$3 vconfig set_name_type DEV_PLUS_VID_NO_PAD @@ -99,7 +98,7 @@ deleteVlan() { local vlanId=$1 local pif=$2 local vlanDev=$pif.$vlanId - local vlanBr=$VIRBR$vlanId + local vlanBr=$3 vconfig rem $vlanDev > /dev/null @@ -132,7 +131,7 @@ op= vlanId= option=$@ -while getopts 'o:v:p:' OPTION +while getopts 'o:v:p:b:' OPTION do case $OPTION in o) oflag=1 @@ -144,6 +143,9 @@ do p) pflag=1 pif="$OPTARG" ;; + b) bflag=1 + brName="$OPTARG" + ;; ?) usage exit 2 ;; @@ -151,7 +153,7 @@ do done # Check that all arguments were passed in -if [ "$oflag$vflag$pflag" != "111" ] +if [ "$oflag$vflag$pflag$bflag" != "1111" ] then usage exit 2 @@ -167,7 +169,7 @@ fi if [ "$op" == "add" ] then # Add the vlan - addVlan $vlanId $pif + addVlan $vlanId $pif $brName # If the add fails then return failure if [ $? -gt 0 ] @@ -178,22 +180,9 @@ else if [ "$op" == "delete" ] then # Delete the vlan - deleteVlan $vlanId $pif + deleteVlan $vlanId $pif $brName # Always exit with success exit 0 fi fi - - - - - - - - - - - - - diff --git a/scripts/vm/systemvm/injectkeys.sh b/scripts/vm/systemvm/injectkeys.sh index e628b16a16f..e56eb85b356 100755 --- a/scripts/vm/systemvm/injectkeys.sh +++ b/scripts/vm/systemvm/injectkeys.sh @@ -23,7 +23,7 @@ #set -x -TMP=${HOME}/tmp +TMP=/tmp MOUNTPATH=${HOME}/systemvm_mnt TMPDIR=${TMP}/cloud/systemvm @@ -80,7 +80,6 @@ systemvmpath=$3 command -v mkisofs > /dev/null || (echo "$(basename $0): mkisofs not found, please install or ensure PATH is accurate" ; exit 4) inject_into_iso systemvm.iso $newpubkey -#inject_into_iso systemvm-premium.iso $newpubkey [ $? -ne 0 ] && exit 5 diff --git a/server/pom.xml b/server/pom.xml index d0099712254..00255414ba6 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-server Apache CloudStack Server org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT @@ -69,10 +68,34 @@ jstl ${cs.jstl.version} + + org.apache.cloudstack + cloud-utils + ${project.version} + tests + test + + install src - + test + + + test/resources + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + com/cloud/upgrade/* + + + + diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 712693185d1..418fe362fd4 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -322,11 +322,12 @@ public class ApiDBUtils { } public static List searchForUserVMs(Criteria c, List permittedAccounts) { - return _userVmMgr.searchForUserVMs(c, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), null, false, permittedAccounts, false, null, null); + return _userVmMgr.searchForUserVMs(c, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), + null, false, permittedAccounts, false, null, null).first(); } public static List searchForStoragePools(Criteria c) { - return _ms.searchForStoragePools(c); + return _ms.searchForStoragePools(c).first(); } // /////////////////////////////////////////////////////////// @@ -733,6 +734,10 @@ public class ApiDBUtils { return _projectMgr.findByProjectAccountId(projectAccountId); } + public static Project findProjectByProjectAccountIdIncludingRemoved(long projectAccountId) { + return _projectMgr.findByProjectAccountIdIncludingRemoved(projectAccountId); + } + public static Project findProjectById(long projectId) { return _projectMgr.getProject(projectId); } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 8eade00060a..dfe4a1fc789 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -33,6 +33,8 @@ import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.commands.ListEventsCmd; import com.cloud.async.AsyncCommandQueued; import com.cloud.async.AsyncJobManager; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.AccountLimitException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; @@ -44,6 +46,8 @@ import com.cloud.server.ManagementServer; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.DateUtil; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.PluggableService; import com.cloud.utils.exception.CSExceptionErrorCode; @@ -59,6 +63,7 @@ public class ApiDispatcher { ComponentLocator _locator; AsyncJobManager _asyncMgr; IdentityDao _identityDao; + Long _createSnapshotQueueSizeLimit; // singleton class private static ApiDispatcher s_instance = new ApiDispatcher(); @@ -71,6 +76,18 @@ public class ApiDispatcher { _locator = ComponentLocator.getLocator(ManagementServer.Name); _asyncMgr = _locator.getManager(AsyncJobManager.class); _identityDao = _locator.getDao(IdentityDao.class); + ConfigurationDao configDao = _locator.getDao(ConfigurationDao.class); + Map configs = configDao.getConfiguration(); + String strSnapshotLimit = configs.get(Config.ConcurrentSnapshotsThresholdPerHost.key()); + if (strSnapshotLimit != null) { + Long snapshotLimit = NumbersUtil.parseLong(strSnapshotLimit, 1L); + if (snapshotLimit <= 0) { + s_logger.debug("Global config parameter " + Config.ConcurrentSnapshotsThresholdPerHost.toString() + + " is less or equal 0; defaulting to unlimited"); + } else { + _createSnapshotQueueSizeLimit = snapshotLimit; + } + } } public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map params) { @@ -131,7 +148,19 @@ public class ApiDispatcher { // Synchronise job on the object if needed if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) { - _asyncMgr.syncAsyncJobExecution(asyncCmd.getJob(), asyncCmd.getSyncObjType(), asyncCmd.getSyncObjId().longValue()); + Long queueSizeLimit = null; + if (asyncCmd.getSyncObjType() != null && asyncCmd.getSyncObjType().equalsIgnoreCase(BaseAsyncCmd.snapshotHostSyncObject)) { + queueSizeLimit = _createSnapshotQueueSizeLimit; + } else { + queueSizeLimit = 1L; + } + + if (queueSizeLimit != null) { + _asyncMgr.syncAsyncJobExecution(asyncCmd.getJob(), asyncCmd.getSyncObjType(), + asyncCmd.getSyncObjId().longValue(), queueSizeLimit); + } else { + s_logger.trace("The queue size is unlimited, skipping the synchronizing"); + } } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index b20aede1f1e..caabd71cd10 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -833,7 +833,7 @@ public class ApiResponseHelper implements ResponseGenerator { // show this info to admin only Account account = UserContext.current().getCaller(); - if ((account == null) || account.getType() == Account.ACCOUNT_TYPE_ADMIN) { + if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) { ipResponse.setVlanId(ipAddr.getVlanId()); ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddr.getVlanId()).getVlanTag()); } @@ -2746,7 +2746,7 @@ public class ApiResponseHelper implements ResponseGenerator { regularAccounts.add(accountName); } else { // convert account to projectIds - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId()); if (project.getUuid() != null && !project.getUuid().isEmpty()) projectIds.add(project.getUuid()); @@ -2967,14 +2967,17 @@ public class ApiResponseHelper implements ResponseGenerator { response.setNetmask(NetUtils.cidr2Netmask(network.getCidr())); } - if (network.getBroadcastUri() != null) { + //return vlan information only to Root admin + if (network.getBroadcastUri() != null && UserContext.current().getCaller().getType() == Account.ACCOUNT_TYPE_ADMIN) { String broadcastUri = network.getBroadcastUri().toString(); response.setBroadcastUri(broadcastUri); String vlan="N/A"; if (broadcastUri.startsWith("vlan")) { vlan = broadcastUri.substring("vlan://".length(), broadcastUri.length()); } + //return vlan information only to Root admin response.setVlan(vlan); + } DataCenter zone = ApiDBUtils.findZoneById(network.getDataCenterId()); @@ -3343,7 +3346,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { // find the project - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId()); response.setProjectId(project.getId()); response.setProjectName(project.getName()); } else { @@ -3359,7 +3362,7 @@ public class ApiResponseHelper implements ResponseGenerator { Account account = ApiDBUtils.findAccountByIdIncludingRemoved(accountId); if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { // find the project - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId()); response.setProjectId(project.getId()); response.setProjectName(project.getName()); } else { @@ -3670,7 +3673,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { // find the project - Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId()); response.setProjectId(project.getId()); response.setProjectName(project.getName()); } else { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 74567de0225..16fc96b18d6 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -116,6 +116,7 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CSExceptionErrorCode; import com.cloud.uuididentity.dao.IdentityDao; + public class ApiServer implements HttpRequestHandler { private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); @@ -299,7 +300,7 @@ public class ApiServer implements HttpRequestHandler { if (apiPort != null) { ListenerThread listenerThread = new ListenerThread(this, apiPort); listenerThread.start(); - } + } } @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -515,14 +516,9 @@ public class ApiServer implements HttpRequestHandler { ctx.setAccountId(asyncCmd.getEntityOwnerId()); - AsyncJobVO job = new AsyncJobVO(); - job.setInstanceId((objectId == null) ? asyncCmd.getInstanceId() : objectId); - job.setInstanceType(asyncCmd.getInstanceType()); - job.setUserId(callerUserId); - job.setAccountId(caller.getId()); - - job.setCmd(cmdObj.getClass().getName()); - job.setCmdInfo(ApiGsonHelper.getBuilder().create().toJson(params)); + Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId; + AsyncJobVO job = new AsyncJobVO(callerUserId, caller.getId(), cmdObj.getClass().getName(), + ApiGsonHelper.getBuilder().create().toJson(params), instanceId, asyncCmd.getInstanceType()); long jobId = _asyncMgr.submitAsyncJob(job); diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 8a1d4de7525..b5c42725104 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -122,6 +122,13 @@ public class ApiServlet extends HttpServlet { // utf8Fixup(req, params); + // logging the request start and end in management log for easy debugging + String reqStr = ""; + if (s_logger.isDebugEnabled()) { + reqStr = auditTrailSb.toString() + " " + req.getQueryString(); + s_logger.debug("===START=== " + reqStr); + } + try { HttpSession session = req.getSession(false); Object[] responseTypeParam = params.get("response"); @@ -335,6 +342,9 @@ public class ApiServlet extends HttpServlet { } } finally { s_accessLogger.info(auditTrailSb.toString()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("===END=== " + reqStr); + } // cleanup user context to prevent from being peeked in other request context UserContext.unregisterContext(); } diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index 124bee1f2e3..1429d14ed58 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -80,9 +80,9 @@ public class ApiResponseSerializer { jsonStr = unescape(jsonStr); if (count != null && count != 0) { - sb.append("{ \"" + ApiConstants.COUNT + "\":" + ((ListResponse) result).getCount() + " ,\"" + responses.get(0).getObjectName() + "\" : [ " + jsonStr); + sb.append("{ \"" + ApiConstants.COUNT + "\":" + count + " ,\"" + responses.get(0).getObjectName() + "\" : [ " + jsonStr); } - for (int i = 1; i < count; i++) { + for (int i = 1; i < ((ListResponse) result).getResponses().size(); i++) { jsonStr = gson.toJson(responses.get(i)); jsonStr = unescape(jsonStr); sb.append(", " + jsonStr); diff --git a/server/src/com/cloud/async/AsyncJobManager.java b/server/src/com/cloud/async/AsyncJobManager.java index 4664e1b07c0..482499714c6 100644 --- a/server/src/com/cloud/async/AsyncJobManager.java +++ b/server/src/com/cloud/async/AsyncJobManager.java @@ -25,8 +25,9 @@ public interface AsyncJobManager extends Manager { public AsyncJobExecutorContext getExecutorContext(); - public AsyncJobVO getAsyncJob(long jobId); - public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId); + public AsyncJobVO getAsyncJob(long jobId); + public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId); + public List findInstancePendingAsyncJobs(AsyncJob.Type instanceType, Long accountId); public long submitAsyncJob(AsyncJobVO job); @@ -39,7 +40,7 @@ public interface AsyncJobManager extends Manager { public void releaseSyncSource(AsyncJobExecutor executor); - public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId); + public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit); /** * Queries for the status or final result of an async job. diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java index 585ba39b2da..6cf95feb977 100644 --- a/server/src/com/cloud/async/AsyncJobManagerImpl.java +++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java @@ -91,29 +91,30 @@ public class AsyncJobManagerImpl implements AsyncJobManager, ClusterManagerListe private AccountManager _accountMgr; private AccountDao _accountDao; private AsyncJobDao _jobDao; - private long _jobExpireSeconds = 86400; // 1 day - private long _jobCancelThresholdSeconds = 3600; // 1 hour - private ApiDispatcher _dispatcher; - - private final ScheduledExecutorService _heartbeatScheduler = - Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat")); - private ExecutorService _executor; - - @Override - public AsyncJobExecutorContext getExecutorContext() { - return _context; - } - - @Override - public AsyncJobVO getAsyncJob(long jobId) { - return _jobDao.findById(jobId); - } - - @Override - public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) { - return _jobDao.findInstancePendingAsyncJob(instanceType, instanceId); + private long _jobExpireSeconds = 86400; // 1 day + private long _jobCancelThresholdSeconds = 3600; // 1 hour (for cancelling the jobs blocking other jobs) + + private ApiDispatcher _dispatcher; + + private final ScheduledExecutorService _heartbeatScheduler = + Executors.newScheduledThreadPool(1, new NamedThreadFactory("AsyncJobMgr-Heartbeat")); + private ExecutorService _executor; + + @Override + public AsyncJobExecutorContext getExecutorContext() { + return _context; } + @Override + public AsyncJobVO getAsyncJob(long jobId) { + return _jobDao.findById(jobId); + } + + @Override + public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) { + return _jobDao.findInstancePendingAsyncJob(instanceType, instanceId); + } + @Override public List findInstancePendingAsyncJobs(AsyncJob.Type instanceType, Long accountId) { return _jobDao.findInstancePendingAsyncJobs(instanceType, accountId); @@ -213,47 +214,47 @@ public class AsyncJobManagerImpl implements AsyncJobManager, ClusterManagerListe job.setProcessStatus(processStatus); if(resultObject != null) { job.setResult(ApiSerializerHelper.toSerializedStringOld(resultObject)); - } - job.setLastUpdated(DateUtil.currentGMTTime()); - _jobDao.update(jobId, job); - txt.commit(); - } catch(Exception e) { - s_logger.error("Unexpected exception while updating async job-" + jobId + " status: ", e); - txt.rollback(); - } - } + } + job.setLastUpdated(DateUtil.currentGMTTime()); + _jobDao.update(jobId, job); + txt.commit(); + } catch(Exception e) { + s_logger.error("Unexpected exception while updating async job-" + jobId + " status: ", e); + txt.rollback(); + } + } - @Override @DB - public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId) { - if(s_logger.isDebugEnabled()) { - s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType + - ", instanceId: " + instanceId); - } - - Transaction txt = Transaction.currentTxn(); - try { - txt.start(); + @Override @DB + public void updateAsyncJobAttachment(long jobId, String instanceType, Long instanceId) { + if(s_logger.isDebugEnabled()) { + s_logger.debug("Update async-job attachment, job-" + jobId + ", instanceType: " + instanceType + + ", instanceId: " + instanceId); + } - AsyncJobVO job = _jobDao.createForUpdate(); - //job.setInstanceType(instanceType); - job.setInstanceId(instanceId); - job.setLastUpdated(DateUtil.currentGMTTime()); - _jobDao.update(jobId, job); + Transaction txt = Transaction.currentTxn(); + try { + txt.start(); - txt.commit(); - } catch(Exception e) { - s_logger.error("Unexpected exception while updating async job-" + jobId + " attachment: ", e); - txt.rollback(); - } - } + AsyncJobVO job = _jobDao.createForUpdate(); + //job.setInstanceType(instanceType); + job.setInstanceId(instanceId); + job.setLastUpdated(DateUtil.currentGMTTime()); + _jobDao.update(jobId, job); - @Override - public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId) { - // This method is re-entrant. If an API developer wants to synchronized on an object, e.g. the router, - // when executing business logic, they will call this method (actually a method in BaseAsyncCmd that calls this). - // This method will get called every time their business logic executes. The first time it exectues for a job - // there will be no sync source, but on subsequent execution there will be a sync souce. If this is the first - // time the job executes we queue the job, otherwise we just return so that the business logic can execute. + txt.commit(); + } catch(Exception e) { + s_logger.error("Unexpected exception while updating async job-" + jobId + " attachment: ", e); + txt.rollback(); + } + } + + @Override + public void syncAsyncJobExecution(AsyncJob job, String syncObjType, long syncObjId, long queueSizeLimit) { + // This method is re-entrant. If an API developer wants to synchronized on an object, e.g. the router, + // when executing business logic, they will call this method (actually a method in BaseAsyncCmd that calls this). + // This method will get called every time their business logic executes. The first time it exectues for a job + // there will be no sync source, but on subsequent execution there will be a sync souce. If this is the first + // time the job executes we queue the job, otherwise we just return so that the business logic can execute. if (job.getSyncSource() != null) { return; } @@ -268,9 +269,9 @@ public class AsyncJobManagerImpl implements AsyncJobManager, ClusterManagerListe // we retry five times until we throw an exception Random random = new Random(); - for(int i = 0; i < 5; i++) { - queue = _queueMgr.queue(syncObjType, syncObjId, "AsyncJob", job.getId()); - if(queue != null) { + for(int i = 0; i < 5; i++) { + queue = _queueMgr.queue(syncObjType, syncObjId, "AsyncJob", job.getId(), queueSizeLimit); + if(queue != null) { break; } @@ -663,41 +664,41 @@ public class AsyncJobManagerImpl implements AsyncJobManager, ClusterManagerListe if(s_logger.isInfoEnabled()) { s_logger.info("Discard left-over queue item: " + item.toString()); } - - String contentType = item.getContentType(); - if(contentType != null && contentType.equals("AsyncJob")) { - Long jobId = item.getContentId(); - if(jobId != null) { - s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId); - completeAsyncJob(jobId, AsyncJobResult.STATUS_FAILED, 0, getResetResultResponse("Execution was cancelled because of server shutdown")); - } - } - _queueMgr.purgeItem(item.getId()); - } - } - } - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - _name = name; - - ComponentLocator locator = ComponentLocator.getCurrentLocator(); - - ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); - if (configDao == null) { - throw new ConfigurationException("Unable to get the configuration dao."); - } - int expireMinutes = NumbersUtil.parseInt( - configDao.getValue(Config.JobExpireMinutes.key()), 24*60); - _jobExpireSeconds = (long)expireMinutes*60; - - _jobCancelThresholdSeconds = NumbersUtil.parseInt( - configDao.getValue(Config.JobCancelThresholdMinutes.key()), 60); - _jobCancelThresholdSeconds *= 60; + String contentType = item.getContentType(); + if(contentType != null && contentType.equals("AsyncJob")) { + Long jobId = item.getContentId(); + if(jobId != null) { + s_logger.warn("Mark job as failed as its correspoding queue-item has been discarded. job id: " + jobId); + completeAsyncJob(jobId, AsyncJobResult.STATUS_FAILED, 0, getResetResultResponse("Execution was cancelled because of server shutdown")); + } + } + _queueMgr.purgeItem(item.getId()); + } + } + } - _accountDao = locator.getDao(AccountDao.class); - if (_accountDao == null) { + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + + ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); + if (configDao == null) { + throw new ConfigurationException("Unable to get the configuration dao."); + } + + int expireMinutes = NumbersUtil.parseInt( + configDao.getValue(Config.JobExpireMinutes.key()), 24*60); + _jobExpireSeconds = (long)expireMinutes*60; + + _jobCancelThresholdSeconds = NumbersUtil.parseInt( + configDao.getValue(Config.JobCancelThresholdMinutes.key()), 60); + _jobCancelThresholdSeconds *= 60; + + _accountDao = locator.getDao(AccountDao.class); + if (_accountDao == null) { throw new ConfigurationException("Unable to get " + AccountDao.class.getName()); } _jobDao = locator.getDao(AsyncJobDao.class); @@ -748,23 +749,22 @@ public class AsyncJobManagerImpl implements AsyncJobManager, ClusterManagerListe } @Override - public void onManagementNodeLeft(List nodeList, long selfNodeId) { - for(ManagementServerHostVO msHost : nodeList) { - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - txn.start(); - List items = _queueMgr.getActiveQueueItems(msHost.getId(), true); - cleanupPendingJobs(items); - _queueMgr.resetQueueProcess(msHost.getId()); - _jobDao.resetJobProcess(msHost.getId(), BaseCmd.INTERNAL_ERROR, getSerializedErrorMessage("job cancelled because of management server restart")); - txn.commit(); - } catch(Throwable e) { - s_logger.warn("Unexpected exception ", e); - txn.rollback(); - } finally { - txn.close(); - } - } + public void onManagementNodeLeft(List nodeList, long selfNodeId) { + for(ManagementServerHostVO msHost : nodeList) { + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + txn.start(); + List items = _queueMgr.getActiveQueueItems(msHost.getId(), true); + cleanupPendingJobs(items); + _jobDao.resetJobProcess(msHost.getId(), BaseCmd.INTERNAL_ERROR, getSerializedErrorMessage("job cancelled because of management server restart")); + txn.commit(); + } catch(Throwable e) { + s_logger.warn("Unexpected exception ", e); + txn.rollback(); + } finally { + txn.close(); + } + } } @Override @@ -773,21 +773,20 @@ public class AsyncJobManagerImpl implements AsyncJobManager, ClusterManagerListe @Override public boolean start() { - try { - List l = _queueMgr.getActiveQueueItems(getMsid(), false); - cleanupPendingJobs(l); - _queueMgr.resetQueueProcess(getMsid()); - _jobDao.resetJobProcess(getMsid(), BaseCmd.INTERNAL_ERROR, getSerializedErrorMessage("job cancelled because of management server restart")); - } catch(Throwable e) { - s_logger.error("Unexpected exception " + e.getMessage(), e); - } - - _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL, - HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS); - _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL, - GC_INTERVAL, TimeUnit.MILLISECONDS); - - return true; + try { + List l = _queueMgr.getActiveQueueItems(getMsid(), false); + cleanupPendingJobs(l); + _jobDao.resetJobProcess(getMsid(), BaseCmd.INTERNAL_ERROR, getSerializedErrorMessage("job cancelled because of management server restart")); + } catch(Throwable e) { + s_logger.error("Unexpected exception " + e.getMessage(), e); + } + + _heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HEARTBEAT_INTERVAL, + HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS); + _heartbeatScheduler.scheduleAtFixedRate(getGCTask(), GC_INTERVAL, + GC_INTERVAL, TimeUnit.MILLISECONDS); + + return true; } private static ExceptionResponse getResetResultResponse(String errorMessage) { diff --git a/server/src/com/cloud/async/SyncQueueManager.java b/server/src/com/cloud/async/SyncQueueManager.java index 1dd82530c2a..b605f1b8670 100644 --- a/server/src/com/cloud/async/SyncQueueManager.java +++ b/server/src/com/cloud/async/SyncQueueManager.java @@ -20,14 +20,14 @@ import java.util.List; import com.cloud.utils.component.Manager; -public interface SyncQueueManager extends Manager { - public SyncQueueVO queue(String syncObjType, long syncObjId, String itemType, long itemId); - public SyncQueueItemVO dequeueFromOne(long queueId, Long msid); - public List dequeueFromAny(Long msid, int maxItems); - public void purgeItem(long queueItemId); + +public interface SyncQueueManager extends Manager { + public SyncQueueVO queue(String syncObjType, long syncObjId, String itemType, long itemId, long queueSizeLimit); + public SyncQueueItemVO dequeueFromOne(long queueId, Long msid); + public List dequeueFromAny(Long msid, int maxItems); + public void purgeItem(long queueItemId); public void returnItem(long queueItemId); public List getActiveQueueItems(Long msid, boolean exclusive); public List getBlockedQueueItems(long thresholdMs, boolean exclusive); - public void resetQueueProcess(long msid); -} +} diff --git a/server/src/com/cloud/async/SyncQueueManagerImpl.java b/server/src/com/cloud/async/SyncQueueManagerImpl.java index b5f3c4fd92e..c3f49557b00 100644 --- a/server/src/com/cloud/async/SyncQueueManagerImpl.java +++ b/server/src/com/cloud/async/SyncQueueManagerImpl.java @@ -34,165 +34,170 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; -@Local(value={SyncQueueManager.class}) -public class SyncQueueManagerImpl implements SyncQueueManager { - public static final Logger s_logger = Logger.getLogger(SyncQueueManagerImpl.class.getName()); - - private String _name; - - private SyncQueueDao _syncQueueDao; - private SyncQueueItemDao _syncQueueItemDao; + +@Local(value={SyncQueueManager.class}) +public class SyncQueueManagerImpl implements SyncQueueManager { + public static final Logger s_logger = Logger.getLogger(SyncQueueManagerImpl.class.getName()); + + private String _name; + + private SyncQueueDao _syncQueueDao; + private SyncQueueItemDao _syncQueueItemDao; + + @Override + @DB + public SyncQueueVO queue(String syncObjType, long syncObjId, String itemType, long itemId, long queueSizeLimit) { + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + + _syncQueueDao.ensureQueue(syncObjType, syncObjId); + SyncQueueVO queueVO = _syncQueueDao.find(syncObjType, syncObjId); + if(queueVO == null) + throw new CloudRuntimeException("Unable to queue item into DB, DB is full?"); - @Override - @DB - public SyncQueueVO queue(String syncObjType, long syncObjId, String itemType, long itemId) { - Transaction txn = Transaction.currentTxn(); - try { - txn.start(); - - _syncQueueDao.ensureQueue(syncObjType, syncObjId); - SyncQueueVO queueVO = _syncQueueDao.find(syncObjType, syncObjId); - if(queueVO == null) - throw new CloudRuntimeException("Unable to queue item into DB, DB is full?"); - - - Date dt = DateUtil.currentGMTTime(); - SyncQueueItemVO item = new SyncQueueItemVO(); - item.setQueueId(queueVO.getId()); - item.setContentType(itemType); - item.setContentId(itemId); - item.setCreated(dt); - - _syncQueueItemDao.persist(item); - txn.commit(); - - return queueVO; - } catch(Exception e) { - s_logger.error("Unexpected exception: ", e); - txn.rollback(); - } - return null; - } - - @Override - @DB - public SyncQueueItemVO dequeueFromOne(long queueId, Long msid) { - Transaction txt = Transaction.currentTxn(); - try { - txt.start(); - - SyncQueueVO queueVO = _syncQueueDao.lockRow(queueId, true); - if(queueVO == null) { - s_logger.error("Sync queue(id: " + queueId + ") does not exist"); - txt.commit(); - return null; - } - - if(queueVO.getLastProcessTime() == null) { - SyncQueueItemVO itemVO = _syncQueueItemDao.getNextQueueItem(queueVO.getId()); - if(itemVO != null) { - Long processNumber = queueVO.getLastProcessNumber(); - if(processNumber == null) - processNumber = new Long(1); - else - processNumber = processNumber + 1; - Date dt = DateUtil.currentGMTTime(); - queueVO.setLastProcessMsid(msid); - queueVO.setLastProcessNumber(processNumber); - queueVO.setLastProcessTime(dt); + queueVO.setQueueSizeLimit(queueSizeLimit); + _syncQueueDao.update(queueVO.getId(), queueVO); + + Date dt = DateUtil.currentGMTTime(); + SyncQueueItemVO item = new SyncQueueItemVO(); + item.setQueueId(queueVO.getId()); + item.setContentType(itemType); + item.setContentId(itemId); + item.setCreated(dt); + + _syncQueueItemDao.persist(item); + txn.commit(); + + return queueVO; + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + txn.rollback(); + } + return null; + } + + @Override + @DB + public SyncQueueItemVO dequeueFromOne(long queueId, Long msid) { + Transaction txt = Transaction.currentTxn(); + try { + txt.start(); + + SyncQueueVO queueVO = _syncQueueDao.lockRow(queueId, true); + if(queueVO == null) { + s_logger.error("Sync queue(id: " + queueId + ") does not exist"); + txt.commit(); + return null; + } + + if(queueReadyToProcess(queueVO)) { + SyncQueueItemVO itemVO = _syncQueueItemDao.getNextQueueItem(queueVO.getId()); + if(itemVO != null) { + Long processNumber = queueVO.getLastProcessNumber(); + if(processNumber == null) + processNumber = new Long(1); + else + processNumber = processNumber + 1; + Date dt = DateUtil.currentGMTTime(); + queueVO.setLastProcessNumber(processNumber); queueVO.setLastUpdated(dt); - _syncQueueDao.update(queueVO.getId(), queueVO); - - itemVO.setLastProcessMsid(msid); + queueVO.setQueueSize(queueVO.getQueueSize() + 1); + _syncQueueDao.update(queueVO.getId(), queueVO); + + itemVO.setLastProcessMsid(msid); itemVO.setLastProcessNumber(processNumber); - _syncQueueItemDao.update(itemVO.getId(), itemVO); - - txt.commit(); - return itemVO; - } else { - if(s_logger.isDebugEnabled()) - s_logger.debug("Sync queue (" + queueId + ") is currently empty"); - } - } else { - if(s_logger.isDebugEnabled()) - s_logger.debug("There is a pending process in sync queue(id: " + queueId + ")"); - } - txt.commit(); - } catch(Exception e) { - s_logger.error("Unexpected exception: ", e); - txt.rollback(); - } - - return null; - } - - @Override - @DB - public List dequeueFromAny(Long msid, int maxItems) { - - List resultList = new ArrayList(); - Transaction txt = Transaction.currentTxn(); - try { - txt.start(); - - List l = _syncQueueItemDao.getNextQueueItems(maxItems); - if(l != null && l.size() > 0) { - for(SyncQueueItemVO item : l) { - SyncQueueVO queueVO = _syncQueueDao.lockRow(item.getQueueId(), true); - SyncQueueItemVO itemVO = _syncQueueItemDao.lockRow(item.getId(), true); - if(queueVO.getLastProcessTime() == null && itemVO.getLastProcessNumber() == null) { - Long processNumber = queueVO.getLastProcessNumber(); - if(processNumber == null) - processNumber = new Long(1); - else - processNumber = processNumber + 1; - - Date dt = DateUtil.currentGMTTime(); - queueVO.setLastProcessMsid(msid); + itemVO.setLastProcessTime(dt); + _syncQueueItemDao.update(itemVO.getId(), itemVO); + + txt.commit(); + return itemVO; + } else { + if(s_logger.isDebugEnabled()) + s_logger.debug("Sync queue (" + queueId + ") is currently empty"); + } + } else { + if(s_logger.isDebugEnabled()) + s_logger.debug("There is a pending process in sync queue(id: " + queueId + ")"); + } + txt.commit(); + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + txt.rollback(); + } + + return null; + } + + @Override + @DB + public List dequeueFromAny(Long msid, int maxItems) { + + List resultList = new ArrayList(); + Transaction txt = Transaction.currentTxn(); + try { + txt.start(); + + List l = _syncQueueItemDao.getNextQueueItems(maxItems); + if(l != null && l.size() > 0) { + for(SyncQueueItemVO item : l) { + SyncQueueVO queueVO = _syncQueueDao.lockRow(item.getQueueId(), true); + SyncQueueItemVO itemVO = _syncQueueItemDao.lockRow(item.getId(), true); + if(queueReadyToProcess(queueVO) && itemVO.getLastProcessNumber() == null) { + Long processNumber = queueVO.getLastProcessNumber(); + if(processNumber == null) + processNumber = new Long(1); + else + processNumber = processNumber + 1; + + Date dt = DateUtil.currentGMTTime(); queueVO.setLastProcessNumber(processNumber); - queueVO.setLastProcessTime(dt); queueVO.setLastUpdated(dt); - _syncQueueDao.update(queueVO.getId(), queueVO); - - itemVO.setLastProcessMsid(msid); + queueVO.setQueueSize(queueVO.getQueueSize() + 1); + _syncQueueDao.update(queueVO.getId(), queueVO); + + itemVO.setLastProcessMsid(msid); itemVO.setLastProcessNumber(processNumber); - _syncQueueItemDao.update(item.getId(), itemVO); - - resultList.add(item); - } - } - } - txt.commit(); - return resultList; - } catch(Exception e) { - s_logger.error("Unexpected exception: ", e); - txt.rollback(); - } - return null; - } - - @Override - @DB - public void purgeItem(long queueItemId) { - Transaction txt = Transaction.currentTxn(); - try { - txt.start(); - - SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId); - if(itemVO != null) { - SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true); - - _syncQueueItemDao.expunge(itemVO.getId()); - - queueVO.setLastProcessTime(null); + itemVO.setLastProcessTime(dt); + _syncQueueItemDao.update(item.getId(), itemVO); + + resultList.add(item); + } + } + } + txt.commit(); + return resultList; + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + txt.rollback(); + } + return null; + } + + @Override + @DB + public void purgeItem(long queueItemId) { + Transaction txt = Transaction.currentTxn(); + try { + txt.start(); + + SyncQueueItemVO itemVO = _syncQueueItemDao.findById(queueItemId); + if(itemVO != null) { + SyncQueueVO queueVO = _syncQueueDao.lockRow(itemVO.getQueueId(), true); + + _syncQueueItemDao.expunge(itemVO.getId()); + queueVO.setLastUpdated(DateUtil.currentGMTTime()); - _syncQueueDao.update(queueVO.getId(), queueVO); - } - txt.commit(); - } catch(Exception e) { - s_logger.error("Unexpected exception: ", e); - txt.rollback(); - } + //decrement the count + assert (queueVO.getQueueSize() > 0) : "Count reduce happens when it's already <= 0!"; + queueVO.setQueueSize(queueVO.getQueueSize() - 1); + _syncQueueDao.update(queueVO.getId(), queueVO); + } + txt.commit(); + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + txt.rollback(); + } } @Override @@ -208,9 +213,9 @@ public class SyncQueueManagerImpl implements SyncQueueManager { itemVO.setLastProcessMsid(null); itemVO.setLastProcessNumber(null); + itemVO.setLastProcessTime(null); _syncQueueItemDao.update(queueItemId, itemVO); - queueVO.setLastProcessTime(null); queueVO.setLastUpdated(DateUtil.currentGMTTime()); _syncQueueDao.update(queueVO.getId(), queueVO); } @@ -231,44 +236,42 @@ public class SyncQueueManagerImpl implements SyncQueueManager { return _syncQueueItemDao.getBlockedQueueItems(thresholdMs, exclusive); } - @Override - public void resetQueueProcess(long msid) { - _syncQueueDao.resetQueueProcessing(msid); - } - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - _name = name; + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; ComponentLocator locator = ComponentLocator.getCurrentLocator(); - - _syncQueueDao = locator.getDao(SyncQueueDao.class); - if (_syncQueueDao == null) { - throw new ConfigurationException("Unable to get " - + SyncQueueDao.class.getName()); + + _syncQueueDao = locator.getDao(SyncQueueDao.class); + if (_syncQueueDao == null) { + throw new ConfigurationException("Unable to get " + + SyncQueueDao.class.getName()); + } + + _syncQueueItemDao = locator.getDao(SyncQueueItemDao.class); + if (_syncQueueItemDao == null) { + throw new ConfigurationException("Unable to get " + + SyncQueueDao.class.getName()); } - - _syncQueueItemDao = locator.getDao(SyncQueueItemDao.class); - if (_syncQueueItemDao == null) { - throw new ConfigurationException("Unable to get " - + SyncQueueDao.class.getName()); - } - - return true; + + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; } - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public String getName() { - return _name; - } -} - + private boolean queueReadyToProcess(SyncQueueVO queueVO) { + return queueVO.getQueueSize() < queueVO.getQueueSizeLimit(); + } +} \ No newline at end of file diff --git a/server/src/com/cloud/async/dao/SyncQueueDao.java b/server/src/com/cloud/async/dao/SyncQueueDao.java index 1b04973d6f9..816f9dd1c30 100644 --- a/server/src/com/cloud/async/dao/SyncQueueDao.java +++ b/server/src/com/cloud/async/dao/SyncQueueDao.java @@ -22,5 +22,4 @@ import com.cloud.utils.db.GenericDao; public interface SyncQueueDao extends GenericDao{ public void ensureQueue(String syncObjType, long syncObjId); public SyncQueueVO find(String syncObjType, long syncObjId); - public void resetQueueProcessing(long msid); -} +} diff --git a/server/src/com/cloud/async/dao/SyncQueueDaoImpl.java b/server/src/com/cloud/async/dao/SyncQueueDaoImpl.java index 49c6c4e49f8..bfe8c0fe451 100644 --- a/server/src/com/cloud/async/dao/SyncQueueDaoImpl.java +++ b/server/src/com/cloud/async/dao/SyncQueueDaoImpl.java @@ -14,6 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. + package com.cloud.async.dao; import java.sql.PreparedStatement; @@ -27,7 +28,6 @@ import org.apache.log4j.Logger; import com.cloud.async.SyncQueueVO; import com.cloud.utils.DateUtil; -import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -38,12 +38,13 @@ public class SyncQueueDaoImpl extends GenericDaoBase implemen private static final Logger s_logger = Logger.getLogger(SyncQueueDaoImpl.class.getName()); SearchBuilder TypeIdSearch = createSearchBuilder(); - - @Override - public void ensureQueue(String syncObjType, long syncObjId) { - Date dt = DateUtil.currentGMTTime(); - String sql = "INSERT IGNORE INTO sync_queue(sync_objtype, sync_objid, created, last_updated) values(?, ?, ?, ?)"; - + + @Override + public void ensureQueue(String syncObjType, long syncObjId) { + Date dt = DateUtil.currentGMTTime(); + String sql = "INSERT IGNORE INTO sync_queue(sync_objtype, sync_objid, created, last_updated)" + + " values(?, ?, ?, ?)"; + Transaction txn = Transaction.currentTxn(); PreparedStatement pstmt = null; try { @@ -54,42 +55,25 @@ public class SyncQueueDaoImpl extends GenericDaoBase implemen pstmt.setString(4, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), dt)); pstmt.execute(); } catch (SQLException e) { - s_logger.warn("Unable to create sync queue " + syncObjType + "-" + syncObjId + ":" + e.getMessage(), e); + s_logger.warn("Unable to create sync queue " + syncObjType + "-" + syncObjId + ":" + e.getMessage(), e); } catch (Throwable e) { - s_logger.warn("Unable to create sync queue " + syncObjType + "-" + syncObjId + ":" + e.getMessage(), e); + s_logger.warn("Unable to create sync queue " + syncObjType + "-" + syncObjId + ":" + e.getMessage(), e); } - } - - @Override - public SyncQueueVO find(String syncObjType, long syncObjId) { - SearchCriteria sc = TypeIdSearch.create(); - sc.setParameters("syncObjType", syncObjType); - sc.setParameters("syncObjId", syncObjId); - return findOneBy(sc); - } + } - @Override @DB - public void resetQueueProcessing(long msid) { - String sql = "UPDATE sync_queue set queue_proc_msid=NULL, queue_proc_time=NULL where queue_proc_msid=?"; - - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, msid); - pstmt.execute(); - } catch (SQLException e) { - s_logger.warn("Unable to reset sync queue for management server " + msid, e); - } catch (Throwable e) { - s_logger.warn("Unable to reset sync queue for management server " + msid, e); - } - } - - protected SyncQueueDaoImpl() { - super(); - TypeIdSearch = createSearchBuilder(); + @Override + public SyncQueueVO find(String syncObjType, long syncObjId) { + SearchCriteria sc = TypeIdSearch.create(); + sc.setParameters("syncObjType", syncObjType); + sc.setParameters("syncObjId", syncObjId); + return findOneBy(sc); + } + + protected SyncQueueDaoImpl() { + super(); + TypeIdSearch = createSearchBuilder(); TypeIdSearch.and("syncObjType", TypeIdSearch.entity().getSyncObjType(), SearchCriteria.Op.EQ); TypeIdSearch.and("syncObjId", TypeIdSearch.entity().getSyncObjId(), SearchCriteria.Op.EQ); TypeIdSearch.done(); - } + } } diff --git a/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java b/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java index 814777da797..ce212981d50 100644 --- a/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java +++ b/server/src/com/cloud/async/dao/SyncQueueItemDaoImpl.java @@ -14,6 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. + package com.cloud.async.dao; import java.sql.PreparedStatement; @@ -29,11 +30,9 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import com.cloud.async.SyncQueueItemVO; -import com.cloud.async.SyncQueueVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @@ -41,38 +40,37 @@ import com.cloud.utils.db.Transaction; @Local(value = { SyncQueueItemDao.class }) public class SyncQueueItemDaoImpl extends GenericDaoBase implements SyncQueueItemDao { private static final Logger s_logger = Logger.getLogger(SyncQueueItemDaoImpl.class); - - private final SyncQueueDao _syncQueueDao = new SyncQueueDaoImpl(); - @Override - public SyncQueueItemVO getNextQueueItem(long queueId) { - - SearchBuilder sb = createSearchBuilder(); + + @Override + public SyncQueueItemVO getNextQueueItem(long queueId) { + + SearchBuilder sb = createSearchBuilder(); sb.and("queueId", sb.entity().getQueueId(), SearchCriteria.Op.EQ); - sb.and("lastProcessNumber", sb.entity().getLastProcessNumber(), SearchCriteria.Op.NULL); + sb.and("lastProcessNumber", sb.entity().getLastProcessNumber(), SearchCriteria.Op.NULL); sb.done(); - SearchCriteria sc = sb.create(); - sc.setParameters("queueId", queueId); - - Filter filter = new Filter(SyncQueueItemVO.class, "created", true, 0L, 1L); + SearchCriteria sc = sb.create(); + sc.setParameters("queueId", queueId); + + Filter filter = new Filter(SyncQueueItemVO.class, "created", true, 0L, 1L); List l = listBy(sc, filter); if(l != null && l.size() > 0) - return l.get(0); - - return null; - } + return l.get(0); + + return null; + } - @Override - public List getNextQueueItems(int maxItems) { - List l = new ArrayList(); - - String sql = "SELECT i.id, i.queue_id, i.content_type, i.content_id, i.created " + - " FROM sync_queue AS q JOIN sync_queue_item AS i ON q.id = i.queue_id " + - " WHERE q.queue_proc_time IS NULL AND i.queue_proc_number IS NULL " + - " GROUP BY q.id " + - " ORDER BY i.id " + - " LIMIT 0, ?"; + @Override + public List getNextQueueItems(int maxItems) { + List l = new ArrayList(); + + String sql = "SELECT i.id, i.queue_id, i.content_type, i.content_id, i.created " + + " FROM sync_queue AS q JOIN sync_queue_item AS i ON q.id = i.queue_id " + + " WHERE q.queue_size < q.queue_size_limit AND i.queue_proc_number IS NULL " + + " GROUP BY q.id " + + " ORDER BY i.id " + + " LIMIT 0, ?"; Transaction txn = Transaction.currentTxn(); PreparedStatement pstmt = null; @@ -81,59 +79,55 @@ public class SyncQueueItemDaoImpl extends GenericDaoBase pstmt.setInt(1, maxItems); ResultSet rs = pstmt.executeQuery(); while(rs.next()) { - SyncQueueItemVO item = new SyncQueueItemVO(); - item.setId(rs.getLong(1)); - item.setQueueId(rs.getLong(2)); - item.setContentType(rs.getString(3)); - item.setContentId(rs.getLong(4)); - item.setCreated(DateUtil.parseDateString(TimeZone.getTimeZone("GMT"), rs.getString(5))); - l.add(item); + SyncQueueItemVO item = new SyncQueueItemVO(); + item.setId(rs.getLong(1)); + item.setQueueId(rs.getLong(2)); + item.setContentType(rs.getString(3)); + item.setContentId(rs.getLong(4)); + item.setCreated(DateUtil.parseDateString(TimeZone.getTimeZone("GMT"), rs.getString(5))); + l.add(item); } } catch (SQLException e) { - s_logger.error("Unexpected sql excetpion, ", e); + s_logger.error("Unexpected sql excetpion, ", e); } catch (Throwable e) { - s_logger.error("Unexpected excetpion, ", e); + s_logger.error("Unexpected excetpion, ", e); } - return l; - } - - @Override - public List getActiveQueueItems(Long msid, boolean exclusive) { - SearchBuilder sb = createSearchBuilder(); + return l; + } + + @Override + public List getActiveQueueItems(Long msid, boolean exclusive) { + SearchBuilder sb = createSearchBuilder(); sb.and("lastProcessMsid", sb.entity().getLastProcessMsid(), - SearchCriteria.Op.EQ); + SearchCriteria.Op.EQ); sb.done(); - SearchCriteria sc = sb.create(); - sc.setParameters("lastProcessMsid", msid); - - Filter filter = new Filter(SyncQueueItemVO.class, "created", true, null, null); - - if(exclusive) - return lockRows(sc, filter, true); + SearchCriteria sc = sb.create(); + sc.setParameters("lastProcessMsid", msid); + + Filter filter = new Filter(SyncQueueItemVO.class, "created", true, null, null); + + if(exclusive) + return lockRows(sc, filter, true); return listBy(sc, filter); - } - + } + + @Override public List getBlockedQueueItems(long thresholdMs, boolean exclusive) { Date cutTime = DateUtil.currentGMTTime(); - cutTime = new Date(cutTime.getTime() - thresholdMs); - - SearchBuilder sbQueue = _syncQueueDao.createSearchBuilder(); - sbQueue.and("lastProcessTime", sbQueue.entity().getLastProcessTime(), SearchCriteria.Op.NNULL); - sbQueue.and("lastProcessTime2", sbQueue.entity().getLastProcessTime(), SearchCriteria.Op.LT); SearchBuilder sbItem = createSearchBuilder(); - sbItem.join("queueItemJoinQueue", sbQueue, sbQueue.entity().getId(), sbItem.entity().getQueueId(), JoinBuilder.JoinType.INNER); sbItem.and("lastProcessMsid", sbItem.entity().getLastProcessMsid(), SearchCriteria.Op.NNULL); sbItem.and("lastProcessNumber", sbItem.entity().getLastProcessNumber(), SearchCriteria.Op.NNULL); - - sbQueue.done(); + sbItem.and("lastProcessNumber", sbItem.entity().getLastProcessTime(), SearchCriteria.Op.NNULL); + sbItem.and("lastProcessTime2", sbItem.entity().getLastProcessTime(), SearchCriteria.Op.LT); + sbItem.done(); - + SearchCriteria sc = sbItem.create(); - sc.setJoinParameters("queueItemJoinQueue", "lastProcessTime2", cutTime); - + sc.setParameters("lastProcessTime2", new Date(cutTime.getTime() - thresholdMs)); + if(exclusive) return lockRows(sc, null, true); return listBy(sc, null); diff --git a/server/src/com/cloud/cluster/ClusterManagerImpl.java b/server/src/com/cloud/cluster/ClusterManagerImpl.java index 4dbb16c93c2..e341b884c49 100755 --- a/server/src/com/cloud/cluster/ClusterManagerImpl.java +++ b/server/src/com/cloud/cluster/ClusterManagerImpl.java @@ -407,6 +407,23 @@ public class ClusterManagerImpl implements ClusterManager { Answer[] answers = new Answer[1]; answers[0] = new Answer(cmd, result, null); return _gson.toJson(answers); + } else if (cmds.length == 1 && cmds[0] instanceof PropagateResourceEventCommand ) { + PropagateResourceEventCommand cmd = (PropagateResourceEventCommand) cmds[0]; + + s_logger.debug("Intercepting command to propagate event " + cmd.getEvent().name() + " for host " + cmd.getHostId()); + + boolean result = false; + try { + result = executeResourceUserRequest(cmd.getHostId(), cmd.getEvent()); + s_logger.debug("Result is " + result); + } catch (AgentUnavailableException ex) { + s_logger.warn("Agent is unavailable", ex); + return null; + } + + Answer[] answers = new Answer[1]; + answers[0] = new Answer(cmd, result, null); + return _gson.toJson(answers); } try { @@ -794,7 +811,8 @@ public class ClusterManagerImpl implements ClusterManager { invalidHeartbeatConnection(); } finally { - txn.close("ClusterHeartBeat"); + txn.transitToAutoManagedConnection(Transaction.CLOUD_DB); + txn.close("ClusterHeartBeat"); } } }; diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 764e5ee9377..66ac2762de1 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -139,8 +139,7 @@ public enum Config { // Advanced JobExpireMinutes("Advanced", ManagementServer.class, String.class, "job.expire.minutes", "1440", "Time (in minutes) for async-jobs to be kept in system", null), JobCancelThresholdMinutes("Advanced", ManagementServer.class, String.class, "job.cancel.threshold.minutes", "60", "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", null), - SwiftEnable( - "Advanced", ManagementServer.class, Boolean.class, "swift.enable", "false", "enable swift ", null), + SwiftEnable("Advanced", ManagementServer.class, Boolean.class, "swift.enable", "false", "enable swift ", null), EventPurgeInterval("Advanced", ManagementServer.class, Integer.class, "event.purge.interval", "86400", "The interval (in seconds) to wait before running the event purge thread", null), AccountCleanupInterval("Advanced", ManagementServer.class, Integer.class, "account.cleanup.interval", "86400", "The interval (in seconds) between cleanup for removed accounts", null), @@ -345,11 +344,14 @@ public enum Config { EIPWithMultipleNetScalersEnabled("Advanced", ManagementServer.class, Boolean.class, "eip.use.multiple.netscalers", "false", "Should be set to true, if there will be multiple NetScaler devices providing EIP service in a zone", null), CustomDiskOfferingMinSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.min", "1", "Minimum size in GB for custom disk offering", null), CustomDiskOfferingMaxSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.max", "1024", "Maximum size in GB for custom disk offering", null), - ConsoleProxyServiceOffering("Advanced", ManagementServer.class, Long.class, "consoleproxy.service.offering", null, "Service offering used by console proxy; if NULL - system offering will be used", null), + ConsoleProxyServiceOffering("Advanced", ManagementServer.class, Long.class, "consoleproxy.service.offering", null, "Uuid of the service offering used by console proxy; if NULL - system offering will be used", null), SecondaryStorageServiceOffering("Advanced", ManagementServer.class, Long.class, "secstorage.service.offering", null, "Service offering used by secondary storage; if NULL - system offering will be used", null), HaTag("Advanced", ManagementServer.class, String.class, "ha.tag", null, "HA tag defining that the host marked with this tag can be used for HA purposes only", null), VpcCleanupInterval("Advanced", ManagementServer.class, Integer.class, "vpc.cleanup.interval", "3600", "The interval (in seconds) between cleanup for Inactive VPCs", null), - VpcMaxNetworks("Advanced", ManagementServer.class, Integer.class, "vpc.max.networks", "3", "Maximum number of networks per vpc", null); + VpcMaxNetworks("Advanced", ManagementServer.class, Integer.class, "vpc.max.networks", "3", "Maximum number of networks per vpc", null), + + ConcurrentSnapshotsThresholdPerHost("Advanced", ManagementServer.class, Long.class, "concurrent.snapshots.threshold.perhost", + null, "Limits number of snapshots that can be handled by the host concurrently; default is NULL - unlimited", null); private final String _category; diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 6de14632fc9..d7875f72ee5 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; @@ -28,6 +29,7 @@ import java.util.UUID; import javax.ejb.Local; import javax.naming.ConfigurationException; +import javax.persistence.Table; import org.apache.log4j.Logger; @@ -105,6 +107,7 @@ import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.servlet.ConsoleProxyServlet; +import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolVO; @@ -656,6 +659,13 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx assert (allocator != null); List runningList = _consoleProxyDao.getProxyListInStates(dataCenterId, State.Running); if (runningList != null && runningList.size() > 0) { + Iterator it = runningList.iterator(); + while (it.hasNext()) { + ConsoleProxyVO proxy = it.next(); + if(proxy.getActiveSession() >= _capacityPerProxy){ + it.remove(); + } + } if (s_logger.isTraceEnabled()) { s_logger.trace("Running proxy pool size : " + runningList.size()); for (ConsoleProxyVO proxy : runningList) { @@ -1184,7 +1194,11 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx } } else { if (s_logger.isDebugEnabled()) { - s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage: " + secondaryStorageHost.getId()); + if (secondaryStorageHost != null) { + s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage: " + secondaryStorageHost.getId()); + } else { + s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage."); + } } } } @@ -1511,14 +1525,20 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx //check if there is a default service offering configured String cpvmSrvcOffIdStr = configs.get(Config.ConsoleProxyServiceOffering.key()); if (cpvmSrvcOffIdStr != null) { - Long cpvmSrvcOffId = Long.parseLong(cpvmSrvcOffIdStr); - _serviceOffering = _offeringDao.findById(cpvmSrvcOffId); - if (_serviceOffering == null || !_serviceOffering.getSystemUse()) { - String msg = "Can't find system service offering id=" + cpvmSrvcOffId + " for console proxy vm"; - s_logger.error(msg); - throw new ConfigurationException(msg); + + Long cpvmSrvcOffId = null; + try { + cpvmSrvcOffId = _identityDao.getIdentityId(DiskOfferingVO.class.getAnnotation(Table.class).name(),cpvmSrvcOffIdStr); + } catch (Exception e) { + String msg = "Can't find system service offering specified by global config, uuid=" + cpvmSrvcOffIdStr + " for console proxy vm"; + s_logger.warn(msg); } - } else { + if(cpvmSrvcOffId != null){ + _serviceOffering = _offeringDao.findById(cpvmSrvcOffId); + } + } + + if(_serviceOffering == null || !_serviceOffering.getSystemUse()){ int ramSize = NumbersUtil.parseInt(_configDao.getValue("console.ram.size"), DEFAULT_PROXY_VM_RAMSIZE); int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("console.cpu.mhz"), DEFAULT_PROXY_VM_CPUMHZ); _serviceOffering = new ServiceOfferingVO("System Offering For Console Proxy", 1, ramSize, cpuFreq, 0, 0, false, null, useLocalStorage, true, null, true, VirtualMachine.Type.ConsoleProxy, true); diff --git a/server/src/com/cloud/dc/dao/HostPodDao.java b/server/src/com/cloud/dc/dao/HostPodDao.java index f031ac977e8..ced348425fd 100644 --- a/server/src/com/cloud/dc/dao/HostPodDao.java +++ b/server/src/com/cloud/dc/dao/HostPodDao.java @@ -21,11 +21,14 @@ import java.util.List; import com.cloud.dc.HostPodVO; import com.cloud.utils.db.GenericDao; +import com.cloud.vm.VirtualMachine; public interface HostPodDao extends GenericDao { public List listByDataCenterId(long id); - - public HostPodVO findByName(String name, long dcId); + + public List listByDataCenterIdVMTypeAndStates(long id, VirtualMachine.Type type, VirtualMachine.State... states); + + public HostPodVO findByName(String name, long dcId); public HashMap> getCurrentPodCidrSubnets(long zoneId, long podIdToSkip); diff --git a/server/src/com/cloud/dc/dao/HostPodDaoImpl.java b/server/src/com/cloud/dc/dao/HostPodDaoImpl.java index bec8c518cdf..fce308aaa77 100644 --- a/server/src/com/cloud/dc/dao/HostPodDaoImpl.java +++ b/server/src/com/cloud/dc/dao/HostPodDaoImpl.java @@ -31,10 +31,15 @@ import com.cloud.dc.HostPodVO; import com.cloud.org.Grouping; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.VMInstanceDaoImpl; @Local(value={HostPodDao.class}) public class HostPodDaoImpl extends GenericDaoBase implements HostPodDao { @@ -61,7 +66,28 @@ public class HostPodDaoImpl extends GenericDaoBase implements H return listBy(sc); } - + + @Override + public List listByDataCenterIdVMTypeAndStates(long id, VirtualMachine.Type type, VirtualMachine.State... states) { + final VMInstanceDaoImpl _vmDao = ComponentLocator.inject(VMInstanceDaoImpl.class); + SearchBuilder vmInstanceSearch = _vmDao.createSearchBuilder(); + vmInstanceSearch.and("type", vmInstanceSearch.entity().getType(), SearchCriteria.Op.EQ); + vmInstanceSearch.and("states", vmInstanceSearch.entity().getState(), SearchCriteria.Op.IN); + + SearchBuilder podIdSearch = createSearchBuilder(); + podIdSearch.and("dc", podIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + podIdSearch.select(null, SearchCriteria.Func.DISTINCT, podIdSearch.entity().getId()); + podIdSearch.join("vmInstanceSearch", vmInstanceSearch, podIdSearch.entity().getId(), + vmInstanceSearch.entity().getPodIdToDeployIn(), JoinBuilder.JoinType.INNER); + podIdSearch.done(); + + SearchCriteria sc = podIdSearch.create(); + sc.setParameters("dc", id); + sc.setJoinParameters("vmInstanceSearch", "type", type); + sc.setJoinParameters("vmInstanceSearch", "states", (Object[]) states); + return listBy(sc); + } + @Override public HostPodVO findByName(String name, long dcId) { SearchCriteria sc = DataCenterAndNameSearch.create(); diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java index 03746e7b35b..8ce6b8ad8ee 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java @@ -69,7 +69,6 @@ import com.cloud.utils.ssh.SSHCmdHelper; public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(KvmServerDiscoverer.class); - private String _setupAgentPath; private ConfigurationDao _configDao; private String _hostIp; private int _waitTime = 5; /*wait for 5 minutes*/ @@ -176,9 +175,9 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, } List netInfos = _networkMgr.getPhysicalNetworkInfo(dcId, HypervisorType.KVM); - String kvmPrivateNic = _kvmPrivateNic; - String kvmPublicNic = _kvmPublicNic; - String kvmGuestNic = _kvmGuestNic; + String kvmPrivateNic = null; + String kvmPublicNic = null; + String kvmGuestNic = null; for (PhysicalNetworkSetupInfo info : netInfos) { if (info.getPrivateNetworkName() != null) { @@ -191,21 +190,31 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, kvmGuestNic = info.getGuestNetworkName(); } } + + if (kvmPrivateNic == null && kvmPublicNic == null && kvmGuestNic == null) { + kvmPrivateNic = _kvmPrivateNic; + kvmPublicNic = _kvmPublicNic; + kvmGuestNic = _kvmGuestNic; + } + + if (kvmPublicNic == null) { + kvmPublicNic = (kvmGuestNic != null) ? kvmGuestNic : kvmPrivateNic; + } + + if (kvmPrivateNic == null) { + kvmPrivateNic = (kvmPublicNic != null) ? kvmPublicNic : kvmGuestNic; + } + + if (kvmGuestNic == null) { + kvmGuestNic = (kvmPublicNic != null) ? kvmPublicNic : kvmPrivateNic; + } + + String parameters = " -m " + _hostIp + " -z " + dcId + " -p " + podId + " -c " + clusterId + " -g " + guid + " -a"; + + parameters += " --pubNic=" + kvmPublicNic; + parameters += " --prvNic=" + kvmPrivateNic; + parameters += " --guestNic=" + kvmGuestNic; - String parameters = " -m " + _hostIp + " -z " + dcId + " -p " + podId + " -c " + clusterId + " -g " + guid + " -a"; - - if (kvmPublicNic != null) { - parameters += " --pubNic=" + kvmPublicNic; - } - - if (kvmPrivateNic != null) { - parameters += " --prvNic=" + kvmPrivateNic; - } - - if (kvmGuestNic != null) { - parameters += " --guestNic=" + kvmGuestNic; - } - SSHCmdHelper.sshExecuteCmd(sshConnection, "cloud-setup-agent " + parameters, 3); KvmDummyResourceBase kvmResource = new KvmDummyResourceBase(); @@ -278,7 +287,6 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, public boolean configure(String name, Map params) throws ConfigurationException { ComponentLocator locator = ComponentLocator.getCurrentLocator(); _configDao = locator.getDao(ConfigurationDao.class); - _setupAgentPath = Script.findScript(getPatchPath(), "setup_agent.sh"); _kvmPrivateNic = _configDao.getValue(Config.KvmPrivateNetwork.key()); if (_kvmPrivateNic == null) { _kvmPrivateNic = "cloudbr0"; @@ -294,9 +302,6 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, _kvmGuestNic = _kvmPrivateNic; } - if (_setupAgentPath == null) { - throw new ConfigurationException("Can't find setup_agent.sh"); - } _hostIp = _configDao.getValue("host"); if (_hostIp == null) { throw new ConfigurationException("Can't get host IP"); diff --git a/server/src/com/cloud/migration/Db21to22MigrationUtil.java b/server/src/com/cloud/migration/Db21to22MigrationUtil.java index 71cc6805e8c..7cd6d7ee7ab 100755 --- a/server/src/com/cloud/migration/Db21to22MigrationUtil.java +++ b/server/src/com/cloud/migration/Db21to22MigrationUtil.java @@ -52,9 +52,6 @@ import com.cloud.vm.InstanceGroupVMMapVO; import com.cloud.vm.InstanceGroupVO; import com.cloud.vm.dao.InstanceGroupDao; import com.cloud.vm.dao.InstanceGroupVMMapDao; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Pool; -import com.xensource.xenapi.Session; public class Db21to22MigrationUtil { private ClusterDao _clusterDao; diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 1e652b67556..398ce3acf0f 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -130,6 +130,7 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; import com.cloud.network.element.ConnectivityProvider; import com.cloud.network.element.DhcpServiceProvider; import com.cloud.network.element.FirewallServiceProvider; +import com.cloud.network.element.SourceNatServiceProvider; import com.cloud.network.element.IpDeployer; import com.cloud.network.element.LoadBalancingServiceProvider; import com.cloud.network.element.NetworkACLServiceProvider; @@ -137,7 +138,6 @@ import com.cloud.network.element.NetworkElement; import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.RemoteAccessVPNServiceProvider; import com.cloud.network.element.Site2SiteVpnServiceProvider; -import com.cloud.network.element.SourceNatServiceProvider; import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.element.VirtualRouterElement; @@ -221,7 +221,6 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; - import edu.emory.mathcs.backport.java.util.Collections; /** @@ -882,7 +881,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); if (!offering.isConserveMode()) { for (PublicIp ip : ipToServices.keySet()) { - Set services = ipToServices.get(ip); + Set services = new HashSet() ; + services.addAll(ipToServices.get(ip)); if (services != null && services.contains(Service.Firewall)) { services.remove(Service.Firewall); } @@ -1145,7 +1145,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Network network = _networksDao.findById(networkId); if (network != null) { - _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + _accountMgr.checkAccess(owner, AccessType.UseNetwork, false, network); } else { s_logger.debug("Unable to find ip address by id: " + ipId); return null; @@ -2737,8 +2737,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.warn("Only guest networks can be created using this method"); return null; } - - boolean updateResourceCount = (!ntwkOff.getSpecifyVlan() && aclType == ACLType.Account); + + boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType); //check resource limits if (updateResourceCount) { _resourceLimitMgr.checkResourceLimit(owner, ResourceType.network); @@ -3573,7 +3573,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.debug("Sending destroy to " + element); } - if (!element.destroy(network)) { + if (!element.destroy(network, context)) { success = false; s_logger.warn("Unable to complete destroy of the network: failed to destroy network element " + element.getName()); } @@ -3612,6 +3612,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.debug(e.getMessage()); } _networksDao.remove(network.getId()); + + NetworkOffering ntwkOff = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, network.getAclType()); + if (updateResourceCount) { + _resourceLimitMgr.decrementResourceCount(owner.getId(), ResourceType.network); + } txn.commit(); } } @@ -3619,6 +3625,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return success; } + private boolean resourceCountNeedsUpdate(NetworkOffering ntwkOff, ACLType aclType) { + boolean updateResourceCount = (!ntwkOff.getSpecifyVlan() && aclType == ACLType.Account); + return updateResourceCount; + } + protected boolean deleteVlansInNetwork(long networkId, long userId, Account callerAccount) { //cleanup Public vlans @@ -3831,11 +3842,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (!(network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup)) { throw new InvalidParameterValueException("Network is not in the right state to be restarted. Correct states are: " + Network.State.Implemented + ", " + Network.State.Setup); } - - // don't allow clenaup=true for the network in Basic zone - DataCenter zone = _configMgr.getZone(network.getDataCenterId()); - if (zone.getNetworkType() == NetworkType.Basic && cleanup) { - throw new InvalidParameterValueException("Cleanup can't be true when restart network in Basic zone"); + + if (network.getBroadcastDomainType() == BroadcastDomainType.Lswitch ) { + /** + * Unable to restart these networks now. + * TODO Restarting a SDN based network requires updating the nics and the configuration + * in the controller. This requires a non-trivial rewrite of the restart procedure. + */ + throw new InvalidParameterException("Unable to restart a running SDN network."); } _accountMgr.checkAccess(callerAccount, null, true, network); @@ -3882,10 +3896,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount); if (cleanup) { - if (network.getGuestType() != GuestType.Isolated) { - s_logger.warn("Only support clean up network for isolated network!"); - return false; - } // shutdown the network s_logger.debug("Shutting down the network id=" + networkId + " as a part of network restart"); @@ -4408,7 +4418,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // the code would be triggered s_logger.debug("Cleaning up remote access vpns as a part of public IP id=" + ipId + " release..."); try { - _vpnMgr.destroyRemoteAccessVpn(ipId); + _vpnMgr.destroyRemoteAccessVpn(ipId, caller); } catch (ResourceUnavailableException e) { s_logger.warn("Unable to destroy remote access vpn for ip id=" + ipId + " as a part of ip release", e); success = false; @@ -4868,11 +4878,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } private String getDomainNetworkDomain(long domainId, long zoneId) { - String networkDomain = _domainDao.findById(domainId).getNetworkDomain(); + String networkDomain = null; + Long searchDomainId = domainId; + while(searchDomainId != null){ + DomainVO domain = _domainDao.findById(searchDomainId); + if(domain.getNetworkDomain() != null){ + networkDomain = domain.getNetworkDomain(); + break; + } + searchDomainId = domain.getParent(); + } if (networkDomain == null) { return getZoneNetworkDomain(zoneId); } - return networkDomain; } @@ -5206,6 +5224,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } catch (NumberFormatException e) { throw new InvalidParameterValueException("Please specify valid integers for the vlan range."); } + + //check for vnet conflicts with other physical network(s) in the zone + checkGuestVnetsConflicts(zoneId, vnetStart, vnetEnd, null); if ((vnetStart > vnetEnd) || (vnetStart < 0) || (vnetEnd > 4096)) { s_logger.warn("Invalid vnet range: start range:" + vnetStart + " end range:" + vnetEnd); @@ -5271,7 +5292,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) { + public Pair, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) { Filter searchFilter = new Filter(PhysicalNetworkVO.class, "id", Boolean.TRUE, startIndex, pageSize); SearchCriteria sc = _physicalNetworkDao.createSearchCriteria(); @@ -5287,7 +5308,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); } - return _physicalNetworkDao.search(sc, searchFilter); + Pair, Integer> result = _physicalNetworkDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -5384,6 +5406,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new InvalidParameterValueException("Vnet range has to be" + rangeMessage + " and start range should be lesser than or equal to stop range"); } + //check if new vnet conflicts with vnet ranges of other physical networks + checkGuestVnetsConflicts(network.getDataCenterId(), newStartVnet, newEndVnet, network.getId()); + if (physicalNetworkHasAllocatedVnets(network.getDataCenterId(), network.getId())) { String[] existingRange = network.getVnet().split("-"); int existingStartVnet = Integer.parseInt(existingRange[0]); @@ -5428,6 +5453,24 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return network; } + protected void checkGuestVnetsConflicts(long zoneId, int newStartVnet, int newEndVnet, Long pNtwkIdToSkip) { + List pNtwks = _physicalNetworkDao.listByZone(zoneId); + for (PhysicalNetwork pNtwk : pNtwks) { + // skip my own network and networks that don't have vnet range set + if ((pNtwk.getVnet() == null || pNtwk.getVnet().isEmpty()) || (pNtwkIdToSkip != null && pNtwkIdToSkip == pNtwk.getId())) { + continue; + } + String[] existingRange = pNtwk.getVnet().split("-"); + int startVnet = Integer.parseInt(existingRange[0]); + int endVnet = Integer.parseInt(existingRange[1]); + if ((newStartVnet >= startVnet && newStartVnet <= endVnet) + || (newEndVnet <= endVnet && newEndVnet >= startVnet)) { + throw new InvalidParameterValueException("Vnet range for physical network conflicts with another " + + "physical network's vnet in the zone"); + } + } + } + private boolean physicalNetworkHasAllocatedVnets(long zoneId, long physicalNetworkId) { return !_dcDao.listAllocatedVnets(physicalNetworkId).isEmpty(); } @@ -5716,7 +5759,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize) { + public Pair, Integer> listNetworkServiceProviders(Long physicalNetworkId, + String name, String state, Long startIndex, Long pageSize) { Filter searchFilter = new Filter(PhysicalNetworkServiceProviderVO.class, "id", false, startIndex, pageSize); SearchBuilder sb = _pNSPDao.createSearchBuilder(); @@ -5734,7 +5778,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sc.addAnd("state", Op.EQ, state); } - return _pNSPDao.search(sc, searchFilter); + Pair, Integer> result = _pNSPDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -6328,7 +6373,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List listTrafficTypes(Long physicalNetworkId) { + public Pair, Integer> listTrafficTypes(Long physicalNetworkId) { PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId); if (network == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system"); @@ -6336,7 +6381,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw ex; } - return _pNTrafficTypeDao.listBy(physicalNetworkId); + Pair, Integer> result = _pNTrafficTypeDao.listAndCountBy(physicalNetworkId); + return new Pair, Integer>(result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java b/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java index 2efd904b7e0..42e5b4e0a35 100644 --- a/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java +++ b/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDao.java @@ -16,14 +16,16 @@ // under the License. package com.cloud.network.dao; + import java.util.List; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.TrafficType; +import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDao; public interface PhysicalNetworkTrafficTypeDao extends GenericDao { - List listBy(long physicalNetworkId); + Pair, Integer> listAndCountBy(long physicalNetworkId); boolean isTrafficTypeSupported(long physicalNetworkId, TrafficType trafficType); String getNetworkTag (long physicalNetworkId, TrafficType trafficType, HypervisorType hType); PhysicalNetworkTrafficTypeVO findBy(long physicalNetworkId, TrafficType trafficType); diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java b/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java index c89477db3a5..5a44cd54704 100755 --- a/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java +++ b/server/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java @@ -22,6 +22,7 @@ import javax.ejb.Local; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.TrafficType; +import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -77,10 +78,10 @@ public class PhysicalNetworkTrafficTypeDaoImpl extends GenericDaoBase listBy(long physicalNetworkId) { + public Pair, Integer> listAndCountBy(long physicalNetworkId) { SearchCriteria sc = physicalNetworkSearch.create(); sc.setParameters("physicalNetworkId", physicalNetworkId); - return search(sc, null); + return searchAndCount(sc, null); } @Override diff --git a/server/src/com/cloud/network/element/BareMetalElement.java b/server/src/com/cloud/network/element/BareMetalElement.java index 842af833b6b..6900e890f58 100644 --- a/server/src/com/cloud/network/element/BareMetalElement.java +++ b/server/src/com/cloud/network/element/BareMetalElement.java @@ -103,7 +103,7 @@ public class BareMetalElement extends AdapterBase implements NetworkElement { } @Override - public boolean destroy(Network network) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } diff --git a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java index ca88a72be7f..bb9ae8101fb 100644 --- a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java +++ b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java @@ -129,7 +129,7 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem } @Override - public boolean destroy(Network config) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroy(Network config, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return false; // assume that the agent will remove userdata etc } diff --git a/server/src/com/cloud/network/element/ExternalDhcpElement.java b/server/src/com/cloud/network/element/ExternalDhcpElement.java index 896cd85cd01..c5ad914e3ca 100755 --- a/server/src/com/cloud/network/element/ExternalDhcpElement.java +++ b/server/src/com/cloud/network/element/ExternalDhcpElement.java @@ -114,7 +114,7 @@ public class ExternalDhcpElement extends AdapterBase implements NetworkElement, } @Override - public boolean destroy(Network network) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } diff --git a/server/src/com/cloud/network/element/SecurityGroupElement.java b/server/src/com/cloud/network/element/SecurityGroupElement.java index 26b33c949e6..517aed90dc9 100644 --- a/server/src/com/cloud/network/element/SecurityGroupElement.java +++ b/server/src/com/cloud/network/element/SecurityGroupElement.java @@ -86,7 +86,7 @@ public class SecurityGroupElement extends AdapterBase implements NetworkElement } @Override - public boolean destroy(Network network) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index f3941b60996..07b182309db 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -621,7 +621,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (!result) { s_logger.warn("Failed to stop virtual router element " + router + ", but would try to process clean up anyway."); } - result = (_routerMgr.destroyRouter(router.getId()) != null); + result = (_routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null); if (!result) { s_logger.warn("Failed to clean up virtual router element " + router); } @@ -631,14 +631,14 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean destroy(Network config) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroy(Network config, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { return true; } boolean result = true; for (DomainRouterVO router : routers) { - result = result && (_routerMgr.destroyRouter(router.getId()) != null); + result = result && (_routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null); } return result; } @@ -736,7 +736,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByElementId(elementId); boolean result = true; for (DomainRouterVO router : routers) { - result = result && (_routerMgr.destroyRouter(router.getId()) != null); + result = result && (_routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null); } _vrProviderDao.remove(elementId); diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java index 77ae4d4d357..2a2d05a76ec 100644 --- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -121,14 +121,14 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc } @Override - public boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { List routers = _routerDao.listByVpcId(vpc.getId()); if (routers == null || routers.isEmpty()) { return true; } boolean result = true; for (DomainRouterVO router : routers) { - result = result && (_routerMgr.destroyRouter(router.getId()) != null); + result = result && (_routerMgr.destroyRouter(router.getId(), context.getAccount(), context.getCaller().getId()) != null); } return result; } @@ -251,7 +251,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc } @Override - public boolean destroy(Network config) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroy(Network config, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { boolean success = true; Long vpcId = config.getVpcId(); if (vpcId == null) { diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index 61607c55ad8..fff624620e6 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -65,6 +65,8 @@ import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; import com.cloud.user.UserContext; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -203,7 +205,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } @Override - public List listFirewallRules(ListFirewallRulesCmd cmd) { + public Pair, Integer> listFirewallRules(ListFirewallRulesCmd cmd) { Long ipId = cmd.getIpAddressId(); Long id = cmd.getId(); Map tags = cmd.getTags(); @@ -269,7 +271,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma sc.setParameters("purpose", Purpose.Firewall); - return _firewallDao.search(sc, filter); + Pair, Integer> result = _firewallDao.searchAndCount(sc, filter); + return new Pair, Integer>(result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index ff0375d094f..3fbe9d53ed9 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -95,6 +95,8 @@ import com.cloud.user.DomainService; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.uservm.UserVm; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -1235,7 +1237,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } @Override - public List searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) { + public Pair, Integer> searchForLoadBalancers(ListLoadBalancerRulesCmd cmd) { Long ipId = cmd.getPublicIpId(); Long zoneId = cmd.getZoneId(); Long id = cmd.getId(); @@ -1326,7 +1328,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } } - return _lbDao.search(sc, searchFilter); + Pair, Integer> result = _lbDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 943c85fb179..928ce0e0863 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.network.router; +import java.net.URI; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; @@ -66,6 +67,7 @@ import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; @@ -74,6 +76,7 @@ import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NetworkACLTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; @@ -363,11 +366,11 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return false; } } + + @Override - public VirtualRouter destroyRouter(final long routerId) throws ResourceUnavailableException, ConcurrentOperationException { - UserContext context = UserContext.current(); - User user = _accountMgr.getActiveUser(context.getCallerUserId()); + public VirtualRouter destroyRouter(final long routerId, Account caller, Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException { if (s_logger.isDebugEnabled()) { s_logger.debug("Attempting to destroy router " + routerId); @@ -378,9 +381,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return null; } - _accountMgr.checkAccess(context.getCaller(), null, true, router); + _accountMgr.checkAccess(caller, null, true, router); - boolean result = _itMgr.expunge(router, user, _accountMgr.getAccount(router.getAccountId())); + boolean result = _itMgr.expunge(router, _accountMgr.getActiveUser(callerUserId), _accountMgr.getAccount(router.getAccountId())); if (result) { return router; @@ -1263,7 +1266,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean isRedundant, Map params) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - List routers = new ArrayList(); Network lock = _networkDao.acquireInLockTable(guestNetwork.getId(), _networkMgr.getNetworkLockTimeout()); if (lock == null) { @@ -1285,73 +1287,111 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) && guestNetwork.getTrafficType() == TrafficType.Guest; - - Pair> planAndRouters = getDeploymentPlanAndRouters(isPodBased, dest, guestNetwork.getId()); - routers = planAndRouters.second(); - - // 2) Figure out required routers count - int routerCount = 1; - if (isRedundant) { - routerCount = 2; + + // dest has pod=null, for Basic Zone findOrDeployVRs for all Pods + List destinations = new ArrayList(); + + if (dest.getDataCenter().getNetworkType() == NetworkType.Basic) { + // Find all pods in the data center with running or starting user vms + long dcId = dest.getDataCenter().getId(); + List pods = _podDao.listByDataCenterIdVMTypeAndStates(dcId, VirtualMachine.Type.User, VirtualMachine.State.Starting, VirtualMachine.State.Running); + + // Loop through all the pods skip those with running or starting VRs + for (HostPodVO pod: pods) { + // Get list of VRs in starting or running state + long podId = pod.getId(); + List virtualRouters = _routerDao.listByPodIdAndStates(podId, VirtualMachine.State.Starting, VirtualMachine.State.Running); + + assert (virtualRouters.size() <= 1) : "Pod can have utmost one VR in Basic Zone, please check!"; + + // Add virtualRouters to the routers, this avoids the situation when + // all routers are skipped and VirtualRouterElement throws exception + routers.addAll(virtualRouters); + + // If List size is one, we already have a starting or running VR, skip deployment + if (virtualRouters.size() == 1) { + s_logger.debug("Skipping VR deployment: Found a running or starting VR in Pod " + + pod.getName() + " id=" + podId); + continue; + } + // Add new DeployDestination for this pod + destinations.add(new DeployDestination(dest.getDataCenter(), pod, null, null)); + } } - - /* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */ - if (routers.size() >= routerCount) { - return routers; - } - - if (routers.size() >= 5) { - s_logger.error("Too much redundant routers!"); + else { + // Else, just add the supplied dest + destinations.add(dest); } - // Check if providers are supported in the physical networks - VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; - Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(guestNetwork); - PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); - } - VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); - if (vrProvider == null) { - throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); - } + // Except for Basic Zone, the for loop will iterate only once + for (DeployDestination destination: destinations) { + Pair> planAndRouters = getDeploymentPlanAndRouters(isPodBased, destination, guestNetwork.getId()); + routers = planAndRouters.second(); - if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { - owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); - } + // 2) Figure out required routers count + int routerCount = 1; + if (isRedundant) { + routerCount = 2; + } - //Check if public network has to be set on VR - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { - publicNetwork = true; - } - if (isRedundant && !publicNetwork) { - s_logger.error("Didn't support redundant virtual router without public network!"); - return null; - } + // If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 + if (routers.size() >= routerCount) { + return routers; + } - Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); - if (offeringId == null) { - offeringId = _offering.getId(); - } + if (routers.size() >= 5) { + s_logger.error("Too much redundant routers!"); + } - PublicIp sourceNatIp = null; - if (publicNetwork) { - sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); - } + // Check if providers are supported in the physical networks + VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(guestNetwork); + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); + } + VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString() + " as service provider " + provider.getId()); + } - //3) deploy virtual router(s) - int count = routerCount - routers.size(); - DeploymentPlan plan = planAndRouters.first(); - for (int i = 0; i < count; i++) { - List> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, - new Pair(publicNetwork, sourceNatIp)); - //don't start the router as we are holding the network lock that needs to be released at the end of router allocation - DomainRouterVO router = deployRouter(owner, dest, plan, params, isRedundant, vrProvider, offeringId, - null, networks, false, null); + if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { + owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + } - _routerDao.addRouterToGuestNetwork(router, guestNetwork); - routers.add(router); + // Check if public network has to be set on VR + boolean publicNetwork = false; + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { + publicNetwork = true; + } + if (isRedundant && !publicNetwork) { + s_logger.error("Didn't support redundant virtual router without public network!"); + return null; + } + + Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); + } + + PublicIp sourceNatIp = null; + if (publicNetwork) { + sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); + } + + // 3) deploy virtual router(s) + int count = routerCount - routers.size(); + DeploymentPlan plan = planAndRouters.first(); + for (int i = 0; i < count; i++) { + List> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, + new Pair(publicNetwork, sourceNatIp)); + //don't start the router as we are holding the network lock that needs to be released at the end of router allocation + DomainRouterVO router = deployRouter(owner, destination, plan, params, isRedundant, vrProvider, offeringId, + null, networks, false, null); + + _routerDao.addRouterToGuestNetwork(router, guestNetwork); + routers.add(router); + } } } finally { if (lock != null) { @@ -1428,7 +1468,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian s_logger.debug("Failed to start the VR " + router + " with hypervisor type " + hType + ", " + "destroying it and recreating one more time"); // destroy the router - destroyRouter(router.getId()); + destroyRouter(router.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM); continue; } else { throw ex; @@ -1436,6 +1476,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } finally { startRetry++; } + } else { + //return stopped router + return router; } } @@ -1446,11 +1489,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian protected List getHypervisors(DeployDestination dest, DeploymentPlan plan, List supportedHypervisors) throws InsufficientServerCapacityException { List hypervisors = new ArrayList(); - HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); - if (defaults != HypervisorType.None) { - hypervisors.add(defaults); - } - + if (dest.getCluster() != null) { if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) { hypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId())); @@ -1458,8 +1497,14 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian hypervisors.add(dest.getCluster().getHypervisorType()); } } else { - hypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, - plan.getPodId()); + HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); + if (defaults != HypervisorType.None) { + hypervisors.add(defaults); + } else { + //if there is no default hypervisor, get it from the cluster + hypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, + plan.getPodId()); + } } //keep only elements defined in supported hypervisors diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 953959de694..9d9a6ab7b67 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -61,6 +61,8 @@ import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -244,6 +246,24 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } else { dstIp = new Ip(guestNic.getIp4Address()); } + + //if start port and end port are passed in, and they are not equal to each other, perform the validation + boolean validatePortRange = false; + if (rule.getSourcePortStart().intValue() != rule.getSourcePortEnd().intValue() + || rule.getDestinationPortStart() != rule.getDestinationPortEnd()) { + validatePortRange = true; + } + + if (validatePortRange) { + //source start port and source dest port should be the same. The same applies to dest ports + if (rule.getSourcePortStart().intValue() != rule.getDestinationPortStart()) { + throw new InvalidParameterValueException("Private port start should be equal to public port start"); + } + + if (rule.getSourcePortEnd().intValue() != rule.getDestinationPortEnd()) { + throw new InvalidParameterValueException("Private port end should be equal to public port end"); + } + } Transaction txn = Transaction.currentTxn(); txn.start(); @@ -666,7 +686,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } @Override - public List listPortForwardingRules(ListPortForwardingRulesCmd cmd) { + public Pair, Integer> listPortForwardingRules(ListPortForwardingRulesCmd cmd) { Long ipId = cmd.getIpAddressId(); Long id = cmd.getId(); Map tags = cmd.getTags(); @@ -732,7 +752,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { sc.setParameters("purpose", Purpose.PortForwarding); - return _portForwardingDao.search(sc, filter); + Pair, Integer> result = _portForwardingDao.searchAndCount(sc, filter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -882,7 +903,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } @Override - public List searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId, Long projectId, boolean isRecursive, boolean listAll) { + public Pair, Integer> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId, Long projectId, boolean isRecursive, boolean listAll) { Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -930,7 +951,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { sc.setJoinParameters("ipSearch", "associatedWithVmId", vmId); } - return _firewallDao.search(sc, filter); + Pair, Integer> result = _firewallDao.searchAndCount(sc, filter); + return new Pair, Integer>(result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index 33757148523..ce1b768e9f8 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -51,6 +51,8 @@ import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.UserContext; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -137,8 +139,11 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ Vpc vpc = _vpcMgr.getVpc(network.getVpcId()); Account aclOwner = _accountMgr.getAccount(vpc.getAccountId()); - _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + //check if the caller can access vpc + _accountMgr.checkAccess(caller, null, false, vpc); + //check if the acl can be created for this network + _accountMgr.checkAccess(aclOwner, AccessType.UseNetwork, false, network); if (!_networkMgr.areServicesSupportedInNetwork(networkId, Service.NetworkACL)) { throw new InvalidParameterValueException("Service " + Service.NetworkACL + " is not supported in network " + network); @@ -343,7 +348,7 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ @Override - public List listNetworkACLs(ListNetworkACLsCmd cmd) { + public Pair,Integer> listNetworkACLs(ListNetworkACLsCmd cmd) { Long networkId = cmd.getNetworkId(); Long id = cmd.getId(); String trafficType = cmd.getTrafficType(); @@ -408,7 +413,8 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ sc.setParameters("purpose", Purpose.NetworkACL); - return _firewallDao.search(sc, filter); + Pair, Integer> result = _firewallDao.searchAndCount(sc, filter); + return new Pair, Integer>(result.first(), result.second()); } diff --git a/server/src/com/cloud/network/vpc/VpcManager.java b/server/src/com/cloud/network/vpc/VpcManager.java index 14fdbe933af..9d7aaa8152b 100644 --- a/server/src/com/cloud/network/vpc/VpcManager.java +++ b/server/src/com/cloud/network/vpc/VpcManager.java @@ -55,11 +55,13 @@ public interface VpcManager extends VpcService{ /** * @param vpc + * @param caller TODO + * @param callerUserId TODO * @return * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException; + boolean destroyVpc(Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException; /** * @param vpcId diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 675ae593fa7..dbaecbbc3cb 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -95,6 +95,7 @@ import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; @@ -614,7 +615,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ @ActionEvent(eventType = EventTypes.EVENT_VPC_DELETE, eventDescription = "deleting VPC") public boolean deleteVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException { UserContext.current().setEventDetails(" Id: " + vpcId); - Account caller = UserContext.current().getCaller(); + UserContext ctx = UserContext.current(); // Verify vpc id Vpc vpc = getVpc(vpcId); @@ -623,15 +624,14 @@ public class VpcManagerImpl implements VpcManager, Manager{ } //verify permissions - _accountMgr.checkAccess(caller, null, false, vpc); - - return destroyVpc(vpc); + _accountMgr.checkAccess(ctx.getCaller(), null, false, vpc); + + return destroyVpc(vpc, ctx.getCaller(), ctx.getCallerUserId()); } @Override @DB - public boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { - UserContext ctx = UserContext.current(); + public boolean destroyVpc(Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Destroying vpc " + vpc); //don't allow to delete vpc if it's in use by existing networks @@ -662,7 +662,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ } //cleanup vpc resources - if (!cleanupVpcResources(vpc.getId(), ctx.getCaller(), ctx.getCallerUserId())) { + if (!cleanupVpcResources(vpc.getId(), caller, callerUserId)) { s_logger.warn("Failed to cleanup resources for vpc " + vpc); return false; } @@ -891,7 +891,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ //do cleanup if (!result && destroyOnFailure) { s_logger.debug("Destroying vpc " + vpc + " that failed to start"); - if (destroyVpc(vpc)) { + if (destroyVpc(vpc, caller, callerUser.getId())) { s_logger.warn("Successfully destroyed vpc " + vpc + " that failed to start"); } else { s_logger.warn("Failed to destroy vpc " + vpc + " that failed to start"); @@ -929,7 +929,8 @@ public class VpcManagerImpl implements VpcManager, Manager{ //shutdown provider s_logger.debug("Shutting down vpc " + vpc); - boolean success = getVpcElement().shutdownVpc(vpc); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(ctx.getCallerUserId()), caller); + boolean success = getVpcElement().shutdownVpc(vpc, context); //TODO - shutdown all vpc resources here (ACLs, gateways, etc) if (success) { @@ -1387,7 +1388,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ } @Override - public List listPrivateGateway(ListPrivateGatewaysCmd cmd) { + public Pair, Integer> listPrivateGateway(ListPrivateGatewaysCmd cmd) { String ipAddress = cmd.getIpAddress(); String vlan = cmd.getVlan(); Long vpcId = cmd.getVpcId(); @@ -1441,14 +1442,14 @@ public class VpcManagerImpl implements VpcManager, Manager{ if (vlan != null) { sc.setJoinParameters("networkSearch", "vlan", BroadcastDomainType.Vlan.toUri(vlan)); } - - List vos = _vpcGatewayDao.search(sc, searchFilter); - List privateGtws = new ArrayList(vos.size()); - for (VpcGateway vo : vos) { + + Pair, Integer> vos = _vpcGatewayDao.searchAndCount(sc, searchFilter); + List privateGtws = new ArrayList(vos.first().size()); + for (VpcGateway vo : vos.first()) { privateGtws.add(getPrivateGatewayProfile(vo)); } - - return privateGtws; + + return new Pair, Integer>(privateGtws, vos.second()); } @Override @@ -1608,7 +1609,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ } @Override - public List listStaticRoutes(ListStaticRoutesCmd cmd) { + public Pair, Integer> listStaticRoutes(ListStaticRoutesCmd cmd) { Long id = cmd.getId(); Long gatewayId = cmd.getGatewayId(); Long vpcId = cmd.getVpcId(); @@ -1673,10 +1674,11 @@ public class VpcManagerImpl implements VpcManager, Manager{ count++; } } - - return _staticRouteDao.search(sc, searchFilter); + + Pair, Integer> result = _staticRouteDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } - + protected void detectRoutesConflict(StaticRoute newRoute) throws NetworkRuleConflictException { List routes = _staticRouteDao.listByGatewayIdAndNotRevoked(newRoute.getVpcGatewayId()); assert (routes.size() >= 1) : "For static routes, we now always first persist the route and then check for " + @@ -1735,7 +1737,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup"); for (VpcVO vpc : inactiveVpcs) { s_logger.debug("Cleaning up " + vpc); - destroyVpc(vpc); + destroyVpc(vpc, _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM); } } catch (Exception e) { s_logger.error("Exception ", e); diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index a53605a1b65..6054e27f0b7 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -213,9 +213,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } @Override @DB - public void destroyRemoteAccessVpn(long ipId) throws ResourceUnavailableException { - Account caller = UserContext.current().getCaller(); - + public void destroyRemoteAccessVpn(long ipId, Account caller) throws ResourceUnavailableException { RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(ipId); if (vpn == null) { s_logger.debug("vpn id=" + ipId + " does not exists "); @@ -336,9 +334,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } @DB @Override - public boolean removeVpnUser(long vpnOwnerId, String username) { - Account caller = UserContext.current().getCaller(); - + public boolean removeVpnUser(long vpnOwnerId, String username, Account caller) { VpnUserVO user = _vpnUsersDao.findByAccountAndUsername(vpnOwnerId, username); if (user == null) { throw new InvalidParameterValueException("Could not find vpn user " + username); @@ -415,7 +411,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag @DB @Override - public boolean applyVpnUsers(long vpnOwnerId) { + public boolean applyVpnUsers(long vpnOwnerId, String userName) { Account caller = UserContext.current().getCaller(); Account owner = _accountDao.findById(vpnOwnerId); _accountMgr.checkAccess(caller, null, true, owner); @@ -478,7 +474,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag _vpnUsersDao.remove(user.getId()); } } else { - if (user.getState() == State.Add) { + if (user.getState() == State.Add && (user.getUsername()).equals(userName)) { Transaction txn = Transaction.currentTxn(); txn.start(); _vpnUsersDao.remove(user.getId()); @@ -493,10 +489,9 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } @Override - public List searchForVpnUsers(ListVpnUsersCmd cmd) { + public Pair, Integer> searchForVpnUsers(ListVpnUsersCmd cmd) { String username = cmd.getUsername(); Long id = cmd.getId(); - Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -528,11 +523,12 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag sc.setParameters("username", username); } - return _vpnUsersDao.search(sc, searchFilter); + Pair, Integer> result = _vpnUsersDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd) { + public Pair, Integer> searchForRemoteAccessVpns(ListRemoteAccessVpnsCmd cmd) { // do some parameter validation Account caller = UserContext.current().getCaller(); Long ipAddressId = cmd.getPublicIpId(); @@ -575,7 +571,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag sc.setParameters("serverAddressId", ipAddressId); } - return _remoteAccessVpnDao.search(sc, filter); + Pair, Integer> result = _remoteAccessVpnDao.searchAndCount(sc, filter); + return new Pair, Integer> (result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index db678ae694c..da993d0b754 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -67,6 +67,7 @@ import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserStatisticsDao; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; @@ -468,12 +469,14 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager { } checkCustomerGatewayCidrList(guestCidrList); - + long accountId = gw.getAccountId(); - if (_customerGatewayDao.findByGatewayIp(gatewayIp) != null) { + Site2SiteCustomerGatewayVO existedGw = _customerGatewayDao.findByGatewayIp(gatewayIp); + if (existedGw != null && existedGw.getId() != gw.getId()) { throw new InvalidParameterValueException("The customer gateway with ip " + gatewayIp + " already existed in the system!"); } - if (_customerGatewayDao.findByNameAndAccountId(name, accountId) != null) { + existedGw = _customerGatewayDao.findByNameAndAccountId(name, accountId); + if (existedGw != null && existedGw.getId() != gw.getId()) { throw new InvalidParameterValueException("The customer gateway with name " + name + " already existed!"); } @@ -566,7 +569,7 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager { } @Override - public List searchForCustomerGateways(ListVpnCustomerGatewaysCmd cmd) { + public Pair, Integer> searchForCustomerGateways(ListVpnCustomerGatewaysCmd cmd) { Long id = cmd.getId(); Long domainId = cmd.getDomainId(); boolean isRecursive = cmd.isRecursive(); @@ -598,13 +601,12 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager { sc.addAnd("id", SearchCriteria.Op.EQ, id); } - List results = new ArrayList(); - results.addAll(_customerGatewayDao.search(sc, searchFilter)); - return results; + Pair, Integer> result = _customerGatewayDao.searchAndCount(sc, searchFilter); + return new Pair, Integer> (result.first(), result.second()); } @Override - public List searchForVpnGateways(ListVpnGatewaysCmd cmd) { + public Pair, Integer> searchForVpnGateways(ListVpnGatewaysCmd cmd) { Long id = cmd.getId(); Long vpcId = cmd.getVpcId(); @@ -643,13 +645,12 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager { sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId); } - List results = new ArrayList(); - results.addAll(_vpnGatewayDao.search(sc, searchFilter)); - return results; + Pair, Integer> result = _vpnGatewayDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForVpnConnections(ListVpnConnectionsCmd cmd) { + public Pair, Integer> searchForVpnConnections(ListVpnConnectionsCmd cmd) { Long id = cmd.getId(); Long vpcId = cmd.getVpcId(); @@ -693,9 +694,8 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager { sc.setJoinParameters("gwSearch", "vpcId", vpcId); } - List results = new ArrayList(); - results.addAll(_vpnConnectionDao.search(sc, searchFilter)); - return results; + Pair, Integer> result = _vpnConnectionDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 73712018af2..c922ddb2c12 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -68,10 +68,12 @@ import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; import com.cloud.user.DomainManager; import com.cloud.user.ResourceLimitService; +import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -283,7 +285,8 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ txn.commit(); if (updateResult) { - if (!cleanupProject(project, _accountDao.findById(caller.getId()), callerUserId)) { + //pass system caller when clenaup projects account + if (!cleanupProject(project, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM)) { s_logger.warn("Failed to cleanup project's id=" + project.getId() + " resources, not removing the project yet"); return false; } else { @@ -352,7 +355,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } @Override - public List listProjects(Long id, String name, String displayText, String state, + public Pair, Integer> listProjects(Long id, String name, String displayText, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, boolean isRecursive, Map tags) { Account caller = UserContext.current().getCaller(); @@ -379,6 +382,12 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ accountId = owner.getId(); } } + else { //domainId == null + if (accountName != null) { + throw new InvalidParameterValueException("could not find account " + accountName + " because domain is not specified"); + } + + } } else { if (accountName != null && !accountName.equals(caller.getAccountName())) { throw new PermissionDeniedException("Can't list account " + accountName + " projects; unauthorized"); @@ -468,8 +477,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ count++; } } - - return _projectDao.search(sc, searchFilter); + + Pair, Integer> result = _projectDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -515,6 +525,11 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ return _projectDao.findByProjectAccountId(projectAccountId); } + @Override + public ProjectVO findByProjectAccountIdIncludingRemoved(long projectAccountId) { + return _projectDao.findByProjectAccountIdIncludingRemoved(projectAccountId); + } + @Override public Project findByNameAndDomainId(String name, long domainId) { return _projectDao.findByNameAndDomain(name, domainId); @@ -735,7 +750,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ @Override - public List listProjectAccounts(long projectId, String accountName, String role, Long startIndex, Long pageSizeVal) { + public Pair, Integer> listProjectAccounts(long projectId, String accountName, String role, Long startIndex, Long pageSizeVal) { Account caller = UserContext.current().getCaller(); //check that the project exists @@ -773,8 +788,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ if (accountName != null) { sc.setJoinParameters("accountSearch", "accountName", accountName); } - - return _projectAccountDao.search(sc, searchFilter); + + Pair, Integer> result = _projectAccountDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } public ProjectInvitation createAccountInvitation(Project project, Long accountId) { @@ -846,8 +862,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } @Override - public List listProjectInvitations(Long id, Long projectId, String accountName, Long domainId, String state, boolean activeOnly, Long startIndex, Long pageSizeVal, boolean isRecursive, boolean listAll) { - Account caller = UserContext.current().getCaller(); + public Pair, Integer> listProjectInvitations(Long id, Long projectId, + String accountName, Long domainId, String state, boolean activeOnly, Long startIndex, Long pageSizeVal, boolean isRecursive, boolean listAll) { + Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); @@ -885,8 +902,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ sc.setParameters("state", ProjectInvitation.State.Pending); sc.setParameters("created", new Date((DateUtil.currentGMTTime().getTime()) - _invitationTimeOut)); } - - return _projectInvitationDao.search(sc, searchFilter); + + Pair, Integer> result = _projectInvitationDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @DB diff --git a/server/src/com/cloud/projects/dao/ProjectDao.java b/server/src/com/cloud/projects/dao/ProjectDao.java index 045d6cab063..e741f2444b3 100644 --- a/server/src/com/cloud/projects/dao/ProjectDao.java +++ b/server/src/com/cloud/projects/dao/ProjectDao.java @@ -31,5 +31,7 @@ public interface ProjectDao extends GenericDao { ProjectVO findByProjectAccountId(long projectAccountId); List listByState(Project.State state); + + ProjectVO findByProjectAccountIdIncludingRemoved(long projectAccountId); } diff --git a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java index e194876a5ae..81e170a1822 100644 --- a/server/src/com/cloud/projects/dao/ProjectDaoImpl.java +++ b/server/src/com/cloud/projects/dao/ProjectDaoImpl.java @@ -108,4 +108,12 @@ public class ProjectDaoImpl extends GenericDaoBase implements P sc.setParameters("state", state); return listBy(sc); } + + @Override + public ProjectVO findByProjectAccountIdIncludingRemoved(long projectAccountId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("projectAccountId", projectAccountId); + + return findOneIncludingRemovedBy(sc); + } } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index a0d10b6d515..3368c9ba116 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -333,7 +333,8 @@ public class ConfigurationServerImpl implements ConfigurationServer { } catch (SQLException ex) { } // insert system user - insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created) VALUES (1, 'system', '', 1, 'system', 'cloud', now())"; + insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created)" + + " VALUES (1, 'system', RAND(), 1, 'system', 'cloud', now())"; txn = Transaction.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index 941d30cd6f0..473b0ee9b3a 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -92,7 +92,7 @@ public interface ManagementServer extends ManagementService { public long getMemoryOrCpuCapacityByHost(Long hostId, short capacityType); - List searchForStoragePools(Criteria c); + Pair, Integer> searchForStoragePools(Criteria c); String getHashKey(); } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index b18bd7efce1..451bdc0c984 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -98,6 +98,7 @@ import com.cloud.api.commands.UpdateVMGroupCmd; import com.cloud.api.commands.UpgradeSystemVMCmd; import com.cloud.api.commands.UploadCustomCertificateCmd; import com.cloud.api.response.ExtractResponse; +import com.cloud.async.AsyncJob; import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobResult; @@ -110,6 +111,7 @@ import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.Configuration; import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.consoleproxy.ConsoleProxyManagementState; @@ -118,7 +120,9 @@ import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; +import com.cloud.dc.Pod; import com.cloud.dc.PodVlanMapVO; +import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.AccountVlanMapDao; @@ -159,11 +163,13 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.info.ConsoleProxyInfo; import com.cloud.keystore.KeystoreManager; import com.cloud.network.IPAddressVO; +import com.cloud.network.IpAddress; import com.cloud.network.LoadBalancerVO; import com.cloud.network.NetworkVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.router.VirtualRouter; import com.cloud.org.Cluster; import com.cloud.org.Grouping.AllocationState; import com.cloud.projects.Project; @@ -174,11 +180,14 @@ import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSVO; +import com.cloud.storage.GuestOsCategory; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.Upload; import com.cloud.storage.Upload.Mode; @@ -234,6 +243,7 @@ import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SSHKeysHelper; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.InstanceGroup; import com.cloud.vm.InstanceGroupVO; import com.cloud.vm.NicVO; import com.cloud.vm.SecondaryStorageVmVO; @@ -819,7 +829,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForClusters(ListClustersCmd cmd) { + public Pair, Integer> searchForClusters(ListClustersCmd cmd) { Filter searchFilter = new Filter(ClusterVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchCriteria sc = _clusterDao.createSearchCriteria(); @@ -869,7 +879,8 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("name", SearchCriteria.Op.SC, ssc); } - return _clusterDao.search(sc, searchFilter); + Pair, Integer> result = _clusterDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -1062,7 +1073,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForPods(ListPodsByCmd cmd) { + public Pair, Integer> searchForPods(ListPodsByCmd cmd) { Filter searchFilter = new Filter(HostPodVO.class, "dataCenterId", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchCriteria sc = _hostPodDao.createSearchCriteria(); @@ -1098,11 +1109,12 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("allocationState", SearchCriteria.Op.EQ, allocationState); } - return _hostPodDao.search(sc, searchFilter); + Pair, Integer> result = _hostPodDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForVlans(ListVlanIpRangesCmd cmd) { + public Pair, Integer> searchForVlans(ListVlanIpRangesCmd cmd) { // If an account name and domain ID are specified, look up the account String accountName = cmd.getAccountName(); Long domainId = cmd.getDomainId(); @@ -1216,11 +1228,12 @@ public class ManagementServerImpl implements ManagementServer { } } - return _vlanDao.search(sc, searchFilter); + Pair, Integer> result = _vlanDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForConfigurations(ListCfgsByCmd cmd) { + public Pair, Integer> searchForConfigurations(ListCfgsByCmd cmd) { Filter searchFilter = new Filter(ConfigurationVO.class, "name", true, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchCriteria sc = _configDao.createSearchCriteria(); @@ -1251,7 +1264,8 @@ public class ManagementServerImpl implements ManagementServer { // hidden configurations are not displayed using the search API sc.addAnd("category", SearchCriteria.Op.NEQ, "Hidden"); - return _configDao.search(sc, searchFilter); + Pair, Integer> result = _configDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -1260,7 +1274,13 @@ public class ManagementServerImpl implements ManagementServer { Account caller = UserContext.current().getCaller(); Map tags = cmd.getTags(); - boolean listAll = (caller.getType() != Account.ACCOUNT_TYPE_NORMAL && (isoFilter != null && isoFilter == TemplateFilter.all)); + boolean listAll = false; + if (isoFilter != null && isoFilter == TemplateFilter.all) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); + } + listAll = true; + } List permittedAccountIds = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); _accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, listAll, false); @@ -1282,8 +1302,15 @@ public class ManagementServerImpl implements ManagementServer { Long id = cmd.getId(); Map tags = cmd.getTags(); Account caller = UserContext.current().getCaller(); - - boolean listAll = (caller.getType() != Account.ACCOUNT_TYPE_NORMAL && (templateFilter != null && templateFilter == TemplateFilter.all)); + + boolean listAll = false; + if (templateFilter != null && templateFilter == TemplateFilter.all) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); + } + listAll = true; + } + List permittedAccountIds = new ArrayList(); Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, listAll, false); @@ -1599,7 +1626,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForRouters(ListRoutersCmd cmd) { + public Pair, Integer> searchForRouters(ListRoutersCmd cmd) { Long id = cmd.getId(); String name = cmd.getRouterName(); String state = cmd.getState(); @@ -1694,11 +1721,12 @@ public class ManagementServerImpl implements ManagementServer { sc.setParameters("vpcId", vpcId); } - return _routerDao.search(sc, searchFilter); + Pair, Integer> result = _routerDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForIPAddresses(ListPublicIpAddressesCmd cmd) { + public Pair, Integer> searchForIPAddresses(ListPublicIpAddressesCmd cmd) { Object keyword = cmd.getKeyword(); Long physicalNetworkId = cmd.getPhysicalNetworkId(); Long associatedNetworkId = cmd.getAssociatedNetworkId(); @@ -1845,11 +1873,12 @@ public class ManagementServerImpl implements ManagementServer { sc.setParameters("associatedNetworkIdEq", associatedNetworkId); } - return _publicIpAddressDao.search(sc, searchFilter); + Pair, Integer> result = _publicIpAddressDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List listGuestOSByCriteria(ListGuestOsCmd cmd) { + public Pair, Integer> listGuestOSByCriteria(ListGuestOsCmd cmd) { Filter searchFilter = new Filter(GuestOSVO.class, "displayName", true, cmd.getStartIndex(), cmd.getPageSizeVal()); Long id = cmd.getId(); Long osCategoryId = cmd.getOsCategoryId(); @@ -1874,11 +1903,12 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("displayName", SearchCriteria.Op.LIKE, "%" + keyword + "%"); } - return _guestOSDao.search(sc, searchFilter); + Pair, Integer> result = _guestOSDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List listGuestOSCategoriesByCriteria(ListGuestOsCategoriesCmd cmd) { + public Pair, Integer> listGuestOSCategoriesByCriteria(ListGuestOsCategoriesCmd cmd) { Filter searchFilter = new Filter(GuestOSCategoryVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); Long id = cmd.getId(); String name = cmd.getName(); @@ -1898,7 +1928,8 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); } - return _guestOSCategoryDao.search(sc, searchFilter); + Pair, Integer> result = _guestOSCategoryDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -2063,7 +2094,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForAlerts(ListAlertsCmd cmd) { + public Pair, Integer> searchForAlerts(ListAlertsCmd cmd) { Filter searchFilter = new Filter(AlertVO.class, "lastSent", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchCriteria sc = _alertDao.createSearchCriteria(); @@ -2090,7 +2121,8 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("type", SearchCriteria.Op.EQ, type); } - return _alertDao.search(sc, searchFilter); + Pair, Integer> result =_alertDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -2457,7 +2489,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForStoragePools(ListStoragePoolsCmd cmd) { + public Pair, Integer> searchForStoragePools(ListStoragePoolsCmd cmd) { Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); Criteria c = new Criteria("id", Boolean.TRUE, cmd.getStartIndex(), cmd.getPageSizeVal()); @@ -2470,11 +2502,12 @@ public class ManagementServerImpl implements ManagementServer { c.addCriteria(Criteria.PODID, cmd.getPodId()); c.addCriteria(Criteria.DATACENTERID, zoneId); - return searchForStoragePools(c); + Pair, Integer> result = searchForStoragePools(c); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForStoragePools(Criteria c) { + public Pair, Integer> searchForStoragePools(Criteria c) { Filter searchFilter = new Filter(StoragePoolVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); SearchCriteria sc = _poolDao.createSearchCriteria(); @@ -2522,11 +2555,11 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("clusterId", SearchCriteria.Op.EQ, cluster); } - return _poolDao.search(sc, searchFilter); + return _poolDao.searchAndCount(sc, searchFilter); } @Override - public List searchForAsyncJobs(ListAsyncJobsCmd cmd) { + public Pair, Integer> searchForAsyncJobs(ListAsyncJobsCmd cmd) { Account caller = UserContext.current().getCaller(); @@ -2596,7 +2629,8 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("created", SearchCriteria.Op.GTEQ, startDate); } - return _jobDao.search(sc, searchFilter); + Pair, Integer> result = _jobDao.searchAndCount(sc, searchFilter); + return new Pair, Integer> (result.first(), result.second()); } @ActionEvent(eventType = EventTypes.EVENT_SSVM_START, eventDescription = "starting secondary storage Vm", async = true) @@ -2631,7 +2665,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForSystemVm(ListSystemVMsCmd cmd) { + public Pair, Integer> searchForSystemVm(ListSystemVMsCmd cmd) { String type = cmd.getSystemVmType(); Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); Long id = cmd.getId(); @@ -2700,7 +2734,8 @@ public class ManagementServerImpl implements ManagementServer { sc.setJoinParameters("volumeSearch", "poolId", storageId); } - return _vmInstanceDao.search(sc, searchFilter); + Pair, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -3091,7 +3126,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForVmGroups(ListVMGroupsCmd cmd) { + public Pair, Integer> searchForVmGroups(ListVMGroupsCmd cmd) { Long id = cmd.getId(); String name = cmd.getGroupName(); String keyword = cmd.getKeyword(); @@ -3158,7 +3193,8 @@ public class ManagementServerImpl implements ManagementServer { sc.setParameters("name", "%" + name + "%"); } - return _vmGroupDao.search(sc, searchFilter); + Pair, Integer> result = _vmGroupDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -3302,7 +3338,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List listSSHKeyPairs(ListSSHKeyPairsCmd cmd) { + public Pair, Integer> listSSHKeyPairs(ListSSHKeyPairsCmd cmd) { String name = cmd.getName(); String fingerPrint = cmd.getFingerprint(); @@ -3329,7 +3365,8 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("fingerprint", SearchCriteria.Op.EQ, fingerPrint); } - return _sshKeyPairDao.search(sc, searchFilter); + Pair, Integer> result = _sshKeyPairDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override @@ -3466,7 +3503,8 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List listHypervisorCapabilities(Long id, HypervisorType hypervisorType, String keyword, Long startIndex, Long pageSizeVal) { + public Pair, Integer> listHypervisorCapabilities(Long id, + HypervisorType hypervisorType, String keyword, Long startIndex, Long pageSizeVal) { Filter searchFilter = new Filter(HypervisorCapabilitiesVO.class, "id", true, startIndex, pageSizeVal); SearchCriteria sc = _hypervisorCapabilitiesDao.createSearchCriteria(); @@ -3484,8 +3522,8 @@ public class ManagementServerImpl implements ManagementServer { sc.addAnd("hypervisorType", SearchCriteria.Op.SC, ssc); } - return _hypervisorCapabilitiesDao.search(sc, searchFilter); - + Pair, Integer> result = _hypervisorCapabilitiesDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index d535af4bd7e..ce00cbf4e81 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -236,5 +236,7 @@ public interface StorageManager extends StorageService, Manager { HypervisorType getHypervisorTypeFromFormat(ImageFormat format); - boolean storagePoolHasEnoughSpace(List volume, StoragePool pool); -} + boolean storagePoolHasEnoughSpace(List volume, StoragePool pool); + + boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException; +} diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index e476a55c75a..7c49f66ea35 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1498,7 +1498,10 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag s_logger.warn("Unable to find pool:" + id); throw new InvalidParameterValueException("Unable to find pool by id " + id); } - + if(sPool.getStatus() != StoragePoolStatus.Maintenance){ + s_logger.warn("Unable to delete storage id: " + id +" due to it is not in Maintenance state"); + throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id); + } if (sPool.getPoolType().equals(StoragePoolType.LVM) || sPool.getPoolType().equals(StoragePoolType.EXT)) { s_logger.warn("Unable to delete local storage id:" + id); throw new InvalidParameterValueException("Unable to delete local storage id: " + id); @@ -1540,8 +1543,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag // mark storage pool as removed (so it can't be used for new volumes creation), release the lock boolean isLockReleased = false; - sPool.setStatus(StoragePoolStatus.Removed); - _storagePoolDao.update(id, sPool); isLockReleased = _storagePoolDao.releaseFromLockTable(lock.getId()); s_logger.trace("Released lock for storage pool " + id); @@ -2856,15 +2857,10 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } } - private boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); - } - @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume") - public boolean deleteVolume(long volumeId) throws ConcurrentOperationException { - Account caller = UserContext.current().getCaller(); + public boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException { // Check that the volume ID is valid VolumeVO volume = _volsDao.findById(volumeId); @@ -3813,7 +3809,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } @Override - public List searchForVolumes(ListVolumesCmd cmd) { + public Pair, Integer> searchForVolumes(ListVolumesCmd cmd) { Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -3925,8 +3921,10 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag // Only return volumes that are not destroyed sc.setParameters("state", Volume.State.Destroy); + + Pair, Integer> volumes = _volumeDao.searchAndCount(sc, searchFilter); - return _volumeDao.search(sc, searchFilter); + return new Pair, Integer>(volumes.first(), volumes.second()); } @Override diff --git a/server/src/com/cloud/storage/dao/SnapshotScheduleDao.java b/server/src/com/cloud/storage/dao/SnapshotScheduleDao.java index c42200c0a10..0419e2836a0 100644 --- a/server/src/com/cloud/storage/dao/SnapshotScheduleDao.java +++ b/server/src/com/cloud/storage/dao/SnapshotScheduleDao.java @@ -19,7 +19,6 @@ package com.cloud.storage.dao; import java.util.Date; import java.util.List; - import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotScheduleVO; import com.cloud.utils.db.GenericDao; diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java index 3bb002bb70f..264b93ee0c7 100755 --- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java +++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java @@ -34,6 +34,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.server.ManagementService; import com.cloud.storage.OCFS2Manager; import com.cloud.storage.StorageManagerImpl; +import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.StoragePoolDao; @@ -78,6 +79,9 @@ public class StoragePoolMonitor implements Listener { scCmd.getHypervisorType() == HypervisorType.VMware || scCmd.getHypervisorType() == HypervisorType.Simulator || scCmd.getHypervisorType() == HypervisorType.Ovm) { List pools = _poolDao.listBy(host.getDataCenterId(), host.getPodId(), host.getClusterId()); for (StoragePoolVO pool : pools) { + if (pool.getStatus() != StoragePoolStatus.Up) { + continue; + } if (!pool.getPoolType().isShared()) { continue; } @@ -92,7 +96,7 @@ public class StoragePoolMonitor implements Listener { _storageManager.connectHostToSharedPool(hostId, pool); _storageManager.createCapacityEntry(pool); } catch (Exception e) { - throw new ConnectionException(true, "Unable to connect to pool " + pool, e); + s_logger.warn("Unable to connect host " + hostId + " to pool " + pool + " due to " + e.toString(), e); } } } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index a32e5d895b1..5333da140c3 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -44,7 +44,6 @@ import com.cloud.api.commands.DeleteSnapshotPoliciesCmd; import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd; import com.cloud.api.commands.ListSnapshotPoliciesCmd; import com.cloud.api.commands.ListSnapshotsCmd; -import com.cloud.async.AsyncJobManager; import com.cloud.configuration.Config; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; @@ -69,7 +68,6 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; -import com.cloud.projects.ProjectManager; import com.cloud.resource.ResourceManager; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Snapshot; @@ -105,7 +103,6 @@ import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserDao; import com.cloud.utils.DateUtil; import com.cloud.utils.DateUtil.IntervalType; import com.cloud.utils.NumbersUtil; @@ -145,8 +142,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Inject protected DiskOfferingDao _diskOfferingDao; @Inject - protected UserDao _userDao; - @Inject protected SnapshotDao _snapshotDao; @Inject protected StoragePoolDao _storagePoolDao; @@ -165,8 +160,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Inject protected SnapshotScheduler _snapSchedMgr; @Inject - protected AsyncJobManager _asyncMgr; - @Inject protected AccountManager _accountMgr; @Inject private AlertManager _alertMgr; @@ -178,8 +171,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma private ResourceLimitService _resourceLimitMgr; @Inject private SwiftManager _swiftMgr; - @Inject - private ProjectManager _projectMgr; @Inject private SecondaryStorageVmManager _ssvmMgr; @Inject @@ -200,54 +191,17 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma protected SearchBuilder PolicySnapshotSearch; protected SearchBuilder PoliciesForSnapSearch; - private boolean isVolumeDirty(long volumeId, Long policy) { - VolumeVO volume = _volsDao.findById(volumeId); - boolean runSnap = true; - - if (volume.getInstanceId() == null) { - long lastSnapId = _snapshotDao.getLastSnapshot(volumeId, 0); - SnapshotVO lastSnap = _snapshotDao.findByIdIncludingRemoved(lastSnapId); - if (lastSnap != null) { - Date lastSnapTime = lastSnap.getCreated(); - if (lastSnapTime.after(volume.getUpdated())) { - runSnap = false; - s_logger.debug("Volume: " + volumeId + " is detached and last snap time is after Volume detach time. Skip snapshot for recurring policy"); - } - } - } else if (_storageMgr.volumeInactive(volume)) { - // Volume is attached to a VM which is in Stopped state. - long lastSnapId = _snapshotDao.getLastSnapshot(volumeId, 0); - SnapshotVO lastSnap = _snapshotDao.findByIdIncludingRemoved(lastSnapId); - if (lastSnap != null) { - Date lastSnapTime = lastSnap.getCreated(); - VMInstanceVO vmInstance = _vmDao.findById(volume.getInstanceId()); - if (vmInstance != null) { - if (lastSnapTime.after(vmInstance.getUpdateTime())) { - runSnap = false; - s_logger.debug("Volume: " + volumeId + " is inactive and last snap time is after VM update time. Skip snapshot for recurring policy"); - } - } - } - } - if (volume.getState() == Volume.State.Destroy || volume.getRemoved() != null) { - s_logger.debug("Volume: " + volumeId + " is destroyed/removed. Not taking snapshot"); - runSnap = false; - } - - return runSnap; - } - + + protected Answer sendToPool(Volume vol, Command cmd) { StoragePool pool = _storagePoolDao.findById(vol.getPoolId()); - VMInstanceVO vm = _vmDao.findById(vol.getInstanceId()); - + long[] hostIdsToTryFirst = null; - if (vm != null) { - if(vm.getHostId() != null) { - hostIdsToTryFirst = new long[] { vm.getHostId() }; - } else if(vm.getLastHostId() != null) { - hostIdsToTryFirst = new long[] { vm.getLastHostId() }; - } + + Long vmHostId = getHostIdForSnapshotOperation(vol); + + if (vmHostId != null) { + hostIdsToTryFirst = new long[] { vmHostId }; } List hostIdsToAvoid = new ArrayList(); @@ -279,6 +233,19 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma return null; } + @Override + public Long getHostIdForSnapshotOperation(Volume vol) { + VMInstanceVO vm = _vmDao.findById(vol.getInstanceId()); + if (vm != null) { + if(vm.getHostId() != null) { + return vm.getHostId(); + } else if(vm.getLastHostId() != null) { + return vm.getLastHostId(); + } + } + return null; + } + @Override public SnapshotVO createSnapshotOnPrimary(VolumeVO volume, Long policyId, Long snapshotId) { SnapshotVO snapshot = _snapshotDao.findById(snapshotId); @@ -443,20 +410,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } } - //when taking snapshot, make sure nobody can delete/move the volume - boolean stateTransit = false; - /* - try { - stateTransit = _storageMgr.stateTransitTo(volume, Volume.Event.SnapshotRequested); - } catch (NoTransitionException e) { - s_logger.debug("Failed transit volume state: " + e.toString()); - } finally { - if (!stateTransit) { - _snapshotDao.expunge(snapshotId); - throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volumeId + " is being used, try it later "); - } - }*/ - snapshot = createSnapshotOnPrimary(volume, policyId, snapshotId); if (snapshot != null) { if (snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary) { @@ -871,7 +824,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma Long dcId = snapshot.getDataCenterId(); Long accountId = snapshot.getAccountId(); Long volumeId = snapshot.getVolumeId(); - HypervisorType hvType = snapshot.getHypervisorType(); String backupOfSnapshot = snapshot.getBackupSnapshotId(); if (backupOfSnapshot == null) { @@ -899,7 +851,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } @Override - public List listSnapshots(ListSnapshotsCmd cmd) { + public Pair, Integer> listSnapshots(ListSnapshotsCmd cmd) { Long volumeId = cmd.getVolumeId(); String name = cmd.getSnapshotName(); Long id = cmd.getId(); @@ -1000,7 +952,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma sc.setParameters("snapshotTypeNEQ", Snapshot.Type.TEMPLATE.ordinal()); } - return _snapshotDao.search(sc, searchFilter); + Pair, Integer> result = _snapshotDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index 5a9889b78b5..be423ae1e44 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -28,13 +28,16 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import com.cloud.api.ApiConstants; import com.cloud.api.ApiDispatcher; import com.cloud.api.ApiGsonHelper; import com.cloud.api.commands.CreateSnapshotCmd; +import com.cloud.user.Account; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobResult; import com.cloud.async.AsyncJobVO; import com.cloud.async.dao.AsyncJobDao; +import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; @@ -46,9 +49,7 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.SnapshotScheduleDao; -import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.DateUtil; import com.cloud.utils.DateUtil.IntervalType; @@ -60,9 +61,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.SearchCriteria; -/** - * - */ + @Local(value={SnapshotScheduler.class}) public class SnapshotSchedulerImpl implements SnapshotScheduler { private static final Logger s_logger = Logger.getLogger(SnapshotSchedulerImpl.class); @@ -73,8 +72,6 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler { @Inject protected SnapshotScheduleDao _snapshotScheduleDao; @Inject protected SnapshotPolicyDao _snapshotPolicyDao; @Inject protected AsyncJobManager _asyncMgr; - @Inject protected SnapshotManager _snapshotManager; - @Inject protected StoragePoolHostDao _poolHostDao; @Inject protected VolumeDao _volsDao; private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds @@ -240,10 +237,10 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler { EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:"+volumeId,0); Map params = new HashMap(); - params.put("volumeid", ""+volumeId); - params.put("policyid", ""+policyId); + params.put(ApiConstants.VOLUME_ID, "" + volumeId); + params.put(ApiConstants.POLICY_ID, "" + policyId); params.put("ctxUserId", "1"); - params.put("ctxAccountId", "1"); + params.put("ctxAccountId", "" + volume.getAccountId()); params.put("ctxStartEventId", String.valueOf(eventId)); CreateSnapshotCmd cmd = new CreateSnapshotCmd(); @@ -251,15 +248,10 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler { params.put("id", ""+cmd.getEntityId()); params.put("ctxStartEventId", "1"); - AsyncJobVO job = new AsyncJobVO(); - job.setUserId(userId); - // Just have SYSTEM own the job for now. Users won't be able to see this job, but - // it's an internal job so probably not a huge deal. - job.setAccountId(1L); - job.setCmd(CreateSnapshotCmd.class.getName()); - job.setInstanceId(cmd.getEntityId()); - job.setCmdInfo(ApiGsonHelper.getBuilder().create().toJson(params)); - + AsyncJobVO job = new AsyncJobVO(User.UID_SYSTEM, volume.getAccountId(), CreateSnapshotCmd.class.getName(), + ApiGsonHelper.getBuilder().create().toJson(params), cmd.getEntityId(), + cmd.getInstanceType()); + long jobId = _asyncMgr.submitAsyncJob(job); tmpSnapshotScheduleVO.setAsyncJobId(jobId); @@ -364,6 +356,7 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler { _testTimerTask = new TestClock(this, minutesPerHour, hoursPerDay, daysPerWeek, daysPerMonth, weeksPerMonth, monthsPerYear); } _currentTimestamp = new Date(); + s_logger.info("Snapshot Scheduler is configured."); return true; diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index db32f2cd41f..237a6774675 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -322,7 +322,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager } @Override - public List listTags(ListTagsCmd cmd) { + public Pair, Integer> listTags(ListTagsCmd cmd) { Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); String key = cmd.getKey(); @@ -334,54 +334,56 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager Ternary domainIdRecursiveListProject = new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), - cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); - Long domainId = domainIdRecursiveListProject.first(); - Boolean isRecursive = domainIdRecursiveListProject.second(); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - Filter searchFilter = new Filter(ResourceTagVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal()); - - SearchBuilder sb = _resourceTagDao.createSearchBuilder(); - _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ); - sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ); - - if (resourceId != null) { - sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); - sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ); - sb.cp(); - } - - sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ); - - // now set the SC criteria... - SearchCriteria sc = sb.create(); - _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - - if (key != null) { - sc.setParameters("key", key); - } - - if (value != null) { - sc.setParameters("value", value); - } - - if (resourceId != null) { - sc.setParameters("resourceId", resourceId); - sc.setParameters("resourceUuid", resourceId); - } - - if (resourceType != null) { - sc.setParameters("resourceType", resourceType); - } - - if (customerName != null) { - sc.setParameters("customer", customerName); - } - - return _resourceTagDao.search(sc, searchFilter); + _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), + cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); + Long domainId = domainIdRecursiveListProject.first(); + Boolean isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + Filter searchFilter = new Filter(ResourceTagVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + + SearchBuilder sb = _resourceTagDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ); + sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ); + + if (resourceId != null) { + sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ); + sb.cp(); + } + + sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ); + + // now set the SC criteria... + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (key != null) { + sc.setParameters("key", key); + } + + if (value != null) { + sc.setParameters("value", value); + } + + if (resourceId != null) { + sc.setParameters("resourceId", resourceId); + sc.setParameters("resourceUuid", resourceId); + } + + if (resourceType != null) { + sc.setParameters("resourceType", resourceType); + } + + if (customerName != null) { + sc.setParameters("customer", customerName); + } + + Pair, Integer> result = _resourceTagDao.searchAndCount(sc, searchFilter); + return new Pair, Integer> (result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index 4e218701744..5668a33fbc0 100755 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -1090,7 +1090,8 @@ public class DatabaseConfig { } // insert system user - insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created) VALUES (1, 'system', '', 1, 'system', 'cloud', now())"; + insertSql = "INSERT INTO `cloud`.`user` (id, username, password, account_id, firstname, lastname, created)" + + " VALUES (1, 'system', RAND(), 1, 'system', 'cloud', now())"; txn = Transaction.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql); diff --git a/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java index 047bb3eec21..a84e6dbb081 100755 --- a/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -55,6 +55,7 @@ import com.cloud.upgrade.dao.Upgrade229to2210; import com.cloud.upgrade.dao.Upgrade301to302; import com.cloud.upgrade.dao.Upgrade302to40; import com.cloud.upgrade.dao.Upgrade30to301; +import com.cloud.upgrade.dao.Upgrade40to41; import com.cloud.upgrade.dao.UpgradeSnapshot217to224; import com.cloud.upgrade.dao.UpgradeSnapshot223to224; import com.cloud.upgrade.dao.VersionDao; @@ -157,6 +158,8 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { _upgradeMap.put("3.0.1", new DbUpgrade[] { new Upgrade301to302(), new Upgrade302to40() }); _upgradeMap.put("3.0.2", new DbUpgrade[] { new Upgrade302to40() }); + + _upgradeMap.put("4.0.0", new DbUpgrade[] { new Upgrade40to41() }); } protected void runScript(Connection conn, File file) { diff --git a/server/src/com/cloud/upgrade/dao/Upgrade302to40.java b/server/src/com/cloud/upgrade/dao/Upgrade302to40.java index 0a836e92620..753f64ec682 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade302to40.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade302to40.java @@ -31,6 +31,7 @@ import org.apache.log4j.Logger; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.cloud.dc.DataCenter.NetworkType; public class Upgrade302to40 extends Upgrade30xBase implements DbUpgrade { final static Logger s_logger = Logger.getLogger(Upgrade302to40.class); @@ -68,6 +69,8 @@ public class Upgrade302to40 extends Upgrade30xBase implements DbUpgrade { addVpcProvider(conn); updateRouterNetworkRef(conn); fixForeignKeys(conn); + setupExternalNetworkDevices(conn); + fixZoneUsingExternalDevices(conn); } @Override @@ -681,4 +684,350 @@ public class Upgrade302to40 extends Upgrade30xBase implements DbUpgrade { throw new CloudRuntimeException("Unable to execute ssh_keypairs table update for adding domain_id foreign key", e); } } + + // upgrades deployment with F5 and SRX devices, to 3.0's Network offerings & service providers paradigm + private void setupExternalNetworkDevices(Connection conn) { + PreparedStatement zoneSearchStmt = null, pNetworkStmt = null, f5DevicesStmt = null, srxDevicesStmt = null; + ResultSet zoneResults = null, pNetworksResults = null, f5DevicesResult = null, srxDevicesResult = null; + + try { + zoneSearchStmt = conn.prepareStatement("SELECT id, networktype FROM `cloud`.`data_center`"); + zoneResults = zoneSearchStmt.executeQuery(); + while (zoneResults.next()) { + long zoneId = zoneResults.getLong(1); + String networkType = zoneResults.getString(2); + + if (!NetworkType.Advanced.toString().equalsIgnoreCase(networkType)) { + continue; + } + + pNetworkStmt = conn.prepareStatement("SELECT id FROM `cloud`.`physical_network` where data_center_id=?"); + pNetworkStmt.setLong(1, zoneId); + pNetworksResults = pNetworkStmt.executeQuery(); + while (pNetworksResults.next()) { + long physicalNetworkId = pNetworksResults.getLong(1); + PreparedStatement fetchF5NspStmt = conn.prepareStatement("SELECT id from `cloud`.`physical_network_service_providers` where physical_network_id=" + physicalNetworkId + + " and provider_name = 'F5BigIp'"); + ResultSet rsF5NSP = fetchF5NspStmt.executeQuery(); + boolean hasF5Nsp = rsF5NSP.next(); + fetchF5NspStmt.close(); + + if (!hasF5Nsp) { + f5DevicesStmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalLoadBalancer' AND removed IS NULL"); + f5DevicesStmt.setLong(1, zoneId); + f5DevicesResult = f5DevicesStmt.executeQuery(); + + while (f5DevicesResult.next()) { + long f5HostId = f5DevicesResult.getLong(1);; + // add F5BigIP provider and provider instance to physical network + addF5ServiceProvider(conn, physicalNetworkId, zoneId); + addF5LoadBalancer(conn, f5HostId, physicalNetworkId); + } + } + + PreparedStatement fetchSRXNspStmt = conn.prepareStatement("SELECT id from `cloud`.`physical_network_service_providers` where physical_network_id=" + physicalNetworkId + + " and provider_name = 'JuniperSRX'"); + ResultSet rsSRXNSP = fetchSRXNspStmt.executeQuery(); + boolean hasSrxNsp = rsSRXNSP.next(); + fetchSRXNspStmt.close(); + + if (!hasSrxNsp) { + srxDevicesStmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalFirewall' AND removed IS NULL"); + srxDevicesStmt.setLong(1, zoneId); + srxDevicesResult = srxDevicesStmt.executeQuery(); + + while (srxDevicesResult.next()) { + long srxHostId = srxDevicesResult.getLong(1); + // add SRX provider and provider instance to physical network + addSrxServiceProvider(conn, physicalNetworkId, zoneId); + addSrxFirewall(conn, srxHostId, physicalNetworkId); + } + } + } + } + + if (zoneResults != null) { + try { + zoneResults.close(); + } catch (SQLException e) { + } + } + if (zoneSearchStmt != null) { + try { + zoneSearchStmt.close(); + } catch (SQLException e) { + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Exception while adding PhysicalNetworks", e); + } finally { + + } + } + + private void addF5LoadBalancer(Connection conn, long hostId, long physicalNetworkId){ + PreparedStatement pstmtUpdate = null; + try{ + s_logger.debug("Adding F5 Big IP load balancer with host id " + hostId + " in to physical network" + physicalNetworkId); + String insertF5 = "INSERT INTO `cloud`.`external_load_balancer_devices` (physical_network_id, host_id, provider_name, " + + "device_name, capacity, is_dedicated, device_state, allocation_state, is_inline, is_managed, uuid) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + pstmtUpdate = conn.prepareStatement(insertF5); + pstmtUpdate.setLong(1, physicalNetworkId); + pstmtUpdate.setLong(2, hostId); + pstmtUpdate.setString(3, "F5BigIp"); + pstmtUpdate.setString(4, "F5BigIpLoadBalancer"); + pstmtUpdate.setLong(5, 0); + pstmtUpdate.setBoolean(6, false); + pstmtUpdate.setString(7, "Enabled"); + pstmtUpdate.setString(8, "Shared"); + pstmtUpdate.setBoolean(9, false); + pstmtUpdate.setBoolean(10, false); + pstmtUpdate.setString(11, UUID.randomUUID().toString()); + pstmtUpdate.executeUpdate(); + }catch (SQLException e) { + throw new CloudRuntimeException("Exception while adding F5 load balancer device" , e); + } finally { + if (pstmtUpdate != null) { + try { + pstmtUpdate.close(); + } catch (SQLException e) { + } + } + } + } + + private void addSrxFirewall(Connection conn, long hostId, long physicalNetworkId){ + PreparedStatement pstmtUpdate = null; + try{ + s_logger.debug("Adding SRX firewall device with host id " + hostId + " in to physical network" + physicalNetworkId); + String insertSrx = "INSERT INTO `cloud`.`external_firewall_devices` (physical_network_id, host_id, provider_name, " + + "device_name, capacity, is_dedicated, device_state, allocation_state, uuid) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + pstmtUpdate = conn.prepareStatement(insertSrx); + pstmtUpdate.setLong(1, physicalNetworkId); + pstmtUpdate.setLong(2, hostId); + pstmtUpdate.setString(3, "JuniperSRX"); + pstmtUpdate.setString(4, "JuniperSRXFirewall"); + pstmtUpdate.setLong(5, 0); + pstmtUpdate.setBoolean(6, false); + pstmtUpdate.setString(7, "Enabled"); + pstmtUpdate.setString(8, "Shared"); + pstmtUpdate.setString(9, UUID.randomUUID().toString()); + pstmtUpdate.executeUpdate(); + }catch (SQLException e) { + throw new CloudRuntimeException("Exception while adding SRX firewall device ", e); + } finally { + if (pstmtUpdate != null) { + try { + pstmtUpdate.close(); + } catch (SQLException e) { + } + } + } + } + + private void addF5ServiceProvider(Connection conn, long physicalNetworkId, long zoneId){ + PreparedStatement pstmtUpdate = null; + try{ + // add physical network service provider - F5BigIp + s_logger.debug("Adding PhysicalNetworkServiceProvider F5BigIp" + " in to physical network" + physicalNetworkId); + String insertPNSP = "INSERT INTO `cloud`.`physical_network_service_providers` (`uuid`, `physical_network_id` , `provider_name`, `state` ," + + "`destination_physical_network_id`, `vpn_service_provided`, `dhcp_service_provided`, `dns_service_provided`, `gateway_service_provided`," + + "`firewall_service_provided`, `source_nat_service_provided`, `load_balance_service_provided`, `static_nat_service_provided`," + + "`port_forwarding_service_provided`, `user_data_service_provided`, `security_group_service_provided`) VALUES (?,?,?,?,0,0,0,0,0,0,0,1,0,0,0,0)"; + + pstmtUpdate = conn.prepareStatement(insertPNSP); + pstmtUpdate.setString(1, UUID.randomUUID().toString()); + pstmtUpdate.setLong(2, physicalNetworkId); + pstmtUpdate.setString(3, "F5BigIp"); + pstmtUpdate.setString(4, "Enabled"); + pstmtUpdate.executeUpdate(); + }catch (SQLException e) { + throw new CloudRuntimeException("Exception while adding PhysicalNetworkServiceProvider F5BigIp", e); + } finally { + if (pstmtUpdate != null) { + try { + pstmtUpdate.close(); + } catch (SQLException e) { + } + } + } + } + + private void addSrxServiceProvider(Connection conn, long physicalNetworkId, long zoneId){ + PreparedStatement pstmtUpdate = null; + try{ + // add physical network service provider - JuniperSRX + s_logger.debug("Adding PhysicalNetworkServiceProvider JuniperSRX"); + String insertPNSP = "INSERT INTO `cloud`.`physical_network_service_providers` (`uuid`, `physical_network_id` , `provider_name`, `state` ," + + "`destination_physical_network_id`, `vpn_service_provided`, `dhcp_service_provided`, `dns_service_provided`, `gateway_service_provided`," + + "`firewall_service_provided`, `source_nat_service_provided`, `load_balance_service_provided`, `static_nat_service_provided`," + + "`port_forwarding_service_provided`, `user_data_service_provided`, `security_group_service_provided`) VALUES (?,?,?,?,0,0,0,0,1,1,1,0,1,1,0,0)"; + + pstmtUpdate = conn.prepareStatement(insertPNSP); + pstmtUpdate.setString(1, UUID.randomUUID().toString()); + pstmtUpdate.setLong(2, physicalNetworkId); + pstmtUpdate.setString(3, "JuniperSRX"); + pstmtUpdate.setString(4, "Enabled"); + pstmtUpdate.executeUpdate(); + }catch (SQLException e) { + throw new CloudRuntimeException("Exception while adding PhysicalNetworkServiceProvider JuniperSRX" , e); + } finally { + if (pstmtUpdate != null) { + try { + pstmtUpdate.close(); + } catch (SQLException e) { + } + } + } + } + + // 1) ensure that networks using external load balancer/firewall in 2.2.14 or prior releases deployments + // has entry in network_external_lb_device_map and network_external_firewall_device_map + // + // 2) Some keys of host details for F5 and SRX devices were stored in Camel Case in 2.x releases. From 3.0 + // they are made in lowercase. On upgrade change the host details name to lower case + private void fixZoneUsingExternalDevices(Connection conn) { + //Get zones to upgrade + List zoneIds = new ArrayList(); + PreparedStatement pstmt = null; + PreparedStatement pstmtUpdate = null; + ResultSet rs = null; + long networkOfferingId, networkId; + long f5DeviceId, f5HostId; + long srxDevivceId, srxHostId; + + try { + pstmt = conn.prepareStatement("select id from `cloud`.`data_center` where lb_provider='F5BigIp' or firewall_provider='JuniperSRX' or gateway_provider='JuniperSRX'"); + rs = pstmt.executeQuery(); + while (rs.next()) { + zoneIds.add(rs.getLong(1)); + } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to create network to LB & firewalla device mapping for networks that use them", e); + } + + if (zoneIds.size() == 0) { + return; // no zones using F5 and SRX devices so return + } + + // find the default network offering created for external devices during upgrade from 2.2.14 + try { + pstmt = conn.prepareStatement("select id from `cloud`.`network_offerings` where unique_name='Isolated with external providers' "); + rs = pstmt.executeQuery(); + if (rs.first()) { + networkOfferingId = rs.getLong(1); + } else { + throw new CloudRuntimeException("Cannot upgrade as there is no 'Isolated with external providers' network offering crearted ."); + } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to create network to LB & firewalla device mapping for networks that use them", e); + } + + for (Long zoneId : zoneIds) { + try { + // find the F5 device id in the zone + pstmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalLoadBalancer' AND removed IS NULL"); + pstmt.setLong(1, zoneId); + rs = pstmt.executeQuery(); + if (rs.first()) { + f5HostId = rs.getLong(1); + } else { + throw new CloudRuntimeException("Cannot upgrade as there is no F5 load balancer device found in data center " + zoneId); + } + pstmt = conn.prepareStatement("SELECT id FROM external_load_balancer_devices WHERE host_id=?"); + pstmt.setLong(1, f5HostId); + rs = pstmt.executeQuery(); + if (rs.first()) { + f5DeviceId = rs.getLong(1); + } else { + throw new CloudRuntimeException("Cannot upgrade as there is no F5 load balancer device with host ID " + f5HostId + " found in external_load_balancer_device"); + } + + // find the SRX device id in the zone + pstmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalFirewall' AND removed IS NULL"); + pstmt.setLong(1, zoneId); + rs = pstmt.executeQuery(); + if (rs.first()) { + srxHostId = rs.getLong(1); + } else { + throw new CloudRuntimeException("Cannot upgrade as there is no SRX firewall device found in data center " + zoneId); + } + pstmt = conn.prepareStatement("SELECT id FROM external_firewall_devices WHERE host_id=?"); + pstmt.setLong(1, srxHostId); + rs = pstmt.executeQuery(); + if (rs.first()) { + srxDevivceId = rs.getLong(1); + } else { + throw new CloudRuntimeException("Cannot upgrade as there is no SRX firewall device found with host ID " + srxHostId + " found in external_firewall_devices"); + } + + // check if network any uses F5 or SRX devices in the zone + pstmt = conn.prepareStatement("select id from `cloud`.`networks` where guest_type='Virtual' and data_center_id=? and network_offering_id=? and removed IS NULL"); + pstmt.setLong(1, zoneId); + pstmt.setLong(2, networkOfferingId); + rs = pstmt.executeQuery(); + while (rs.next()) { + // get the network Id + networkId = rs.getLong(1); + + // add mapping for the network in network_external_lb_device_map + String insertLbMapping = "INSERT INTO `cloud`.`network_external_lb_device_map` (uuid, network_id, external_load_balancer_device_id, created) VALUES ( ?, ?, ?, now())"; + pstmtUpdate = conn.prepareStatement(insertLbMapping); + pstmtUpdate.setString(1, UUID.randomUUID().toString()); + pstmtUpdate.setLong(2, networkId); + pstmtUpdate.setLong(3, f5DeviceId); + pstmtUpdate.executeUpdate(); + s_logger.debug("Successfully added entry in network_external_lb_device_map for network " + networkId + " and F5 device ID " + f5DeviceId); + + // add mapping for the network in network_external_firewall_device_map + String insertFwMapping = "INSERT INTO `cloud`.`network_external_firewall_device_map` (uuid, network_id, external_firewall_device_id, created) VALUES ( ?, ?, ?, now())"; + pstmtUpdate = conn.prepareStatement(insertFwMapping); + pstmtUpdate.setString(1, UUID.randomUUID().toString()); + pstmtUpdate.setLong(2, networkId); + pstmtUpdate.setLong(3, srxDevivceId); + pstmtUpdate.executeUpdate(); + s_logger.debug("Successfully added entry in network_external_firewall_device_map for network " + networkId + " and SRX device ID " + srxDevivceId); + } + + // update host details for F5 and SRX devices + s_logger.debug("Updating the host details for F5 and SRX devices"); + pstmt = conn.prepareStatement("SELECT host_id, name FROM `cloud`.`host_details` WHERE host_id=? OR host_id=?"); + pstmt.setLong(1, f5HostId); + pstmt.setLong(2, srxHostId); + rs = pstmt.executeQuery(); + while (rs.next()) { + long hostId = rs.getLong(1); + String camlCaseName = rs.getString(2); + if (!(camlCaseName.equalsIgnoreCase("numRetries") || + camlCaseName.equalsIgnoreCase("publicZone") || + camlCaseName.equalsIgnoreCase("privateZone") || + camlCaseName.equalsIgnoreCase("publicInterface") || + camlCaseName.equalsIgnoreCase("privateInterface") || + camlCaseName.equalsIgnoreCase("usageInterface") )) { + continue; + } + String lowerCaseName = camlCaseName.toLowerCase(); + pstmt = conn.prepareStatement("update `cloud`.`host_details` set name=? where host_id=? AND name=?"); + pstmt.setString(1, lowerCaseName); + pstmt.setLong(2, hostId); + pstmt.setString(3, camlCaseName); + pstmt.executeUpdate(); + } + s_logger.debug("Successfully updated host details for F5 and SRX devices"); + } catch (SQLException e) { + throw new CloudRuntimeException("Unable create a mapping for the networks in network_external_lb_device_map and network_external_firewall_device_map", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + s_logger.info("Successfully upgraded networks using F5 and SRX devices to have a entry in the network_external_lb_device_map and network_external_firewall_device_map"); + } + } } diff --git a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java new file mode 100644 index 00000000000..5067f39d011 --- /dev/null +++ b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java @@ -0,0 +1,83 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.upgrade.dao; + +import java.io.File; +import java.sql.Connection; + +/** + * @author htrippaers + * + */ +public class Upgrade40to41 extends Upgrade30xBase implements DbUpgrade { + + /** + * + */ + public Upgrade40to41() { + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see com.cloud.upgrade.dao.DbUpgrade#getUpgradableVersionRange() + */ + @Override + public String[] getUpgradableVersionRange() { + return new String[] { "4.0.0", "4.1.0" }; + } + + /* (non-Javadoc) + * @see com.cloud.upgrade.dao.DbUpgrade#getUpgradedVersion() + */ + @Override + public String getUpgradedVersion() { + return "4.1.0"; + } + + /* (non-Javadoc) + * @see com.cloud.upgrade.dao.DbUpgrade#supportsRollingUpgrade() + */ + @Override + public boolean supportsRollingUpgrade() { + return false; + } + + /* (non-Javadoc) + * @see com.cloud.upgrade.dao.DbUpgrade#getPrepareScripts() + */ + @Override + public File[] getPrepareScripts() { + return new File[0]; + } + + /* (non-Javadoc) + * @see com.cloud.upgrade.dao.DbUpgrade#performDataMigration(java.sql.Connection) + */ + @Override + public void performDataMigration(Connection conn) { + } + + /* (non-Javadoc) + * @see com.cloud.upgrade.dao.DbUpgrade#getCleanupScripts() + */ + @Override + public File[] getCleanupScripts() { + return new File[0]; + } + +} diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 1fc690ff6d5..9d6dd76dc27 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -74,15 +74,10 @@ import com.cloud.network.IpAddress; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.network.RemoteAccessVpnVO; -import com.cloud.network.Site2SiteCustomerGatewayVO; -import com.cloud.network.Site2SiteVpnConnectionVO; import com.cloud.network.VpnUserVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.RemoteAccessVpnDao; -import com.cloud.network.dao.Site2SiteCustomerGatewayDao; -import com.cloud.network.dao.Site2SiteVpnConnectionDao; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.dao.SecurityGroupDao; @@ -577,7 +572,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag for (VolumeVO volume : volumes) { if (!volume.getState().equals(Volume.State.Destroy)) { try { - _storageMgr.deleteVolume(volume.getId()); + _storageMgr.deleteVolume(volume.getId(), caller); } catch (Exception ex) { s_logger.warn("Failed to cleanup volumes as a part of account id=" + accountId + " cleanup due to Exception: ", ex); accountCleanupNeeded = true; @@ -590,12 +585,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag List vpnUsers = _vpnUser.listByAccount(accountId); for (VpnUserVO vpnUser : vpnUsers) { - _remoteAccessVpnMgr.removeVpnUser(accountId, vpnUser.getUsername()); + _remoteAccessVpnMgr.removeVpnUser(accountId, vpnUser.getUsername(), caller); } try { for (RemoteAccessVpnVO vpn : remoteAccessVpns) { - _remoteAccessVpnMgr.destroyRemoteAccessVpn(vpn.getServerAddressId()); + _remoteAccessVpnMgr.destroyRemoteAccessVpn(vpn.getServerAddressId(), caller); } } catch (ResourceUnavailableException ex) { s_logger.warn("Failed to cleanup remote access vpn resources as a part of account id=" + accountId + " cleanup due to Exception: ", ex); @@ -613,7 +608,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (networks != null) { for (NetworkVO network : networks) { - ReservationContext context = new ReservationContextImpl(null, null, getActiveUser(callerUserId), account); + ReservationContext context = new ReservationContextImpl(null, null, getActiveUser(callerUserId), caller); if (!_networkMgr.destroyNetwork(network.getId(), context)) { s_logger.warn("Unable to destroy network " + network + " as a part of account id=" + accountId + " cleanup."); @@ -631,7 +626,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag List vpcs = _vpcMgr.getVpcsForAccount(account.getId()); for (Vpc vpc : vpcs) { - if (!_vpcMgr.destroyVpc(vpc)) { + if (!_vpcMgr.destroyVpc(vpc, caller, callerUserId)) { s_logger.warn("Unable to destroy VPC " + vpc + " as a part of account id=" + accountId + " cleanup."); accountCleanupNeeded = true; vpcsDeleted = false; @@ -839,6 +834,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain id=" + domainId + " to create user"); } + + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { + throw new PermissionDeniedException("Account id : " + account.getId() + " is a system account, can't add a user to it"); + } if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) { throw new CloudRuntimeException("The user " + userName + " already exists in domain " + domainId); @@ -881,6 +880,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag throw new InvalidParameterValueException("unable to find user by id"); } + //don't allow updating system account if (account != null && (account.getId() == Account.ACCOUNT_ID_SYSTEM)) { throw new PermissionDeniedException("user id : " + id + " is system account, update is not allowed"); } @@ -1159,9 +1159,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); } - // Don't allow to modify system account if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { - throw new InvalidParameterValueException("Can not modify system account"); + throw new PermissionDeniedException("Account id : " + accountId + " is a system account, enable is not allowed"); } // Check if user performing the action is allowed to modify this account @@ -1191,14 +1190,13 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Unable to find active account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); } + + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { + throw new PermissionDeniedException("Account id : " + accountId + " is a system account, lock is not allowed"); + } checkAccess(caller, null, true, account); - // don't allow modify system account - if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { - throw new InvalidParameterValueException("can not lock system account"); - } - if (lockAccount(account.getId())) { return _accountDao.findById(account.getId()); } else { @@ -1221,6 +1219,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); } + + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { + throw new PermissionDeniedException("Account id : " + accountId + " is a system account, disable is not allowed"); + } checkAccess(caller, null, true, account); @@ -1713,7 +1715,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag String singleSignOnTolerance = _configDao.getValue("security.singlesignon.tolerance.millis"); if (singleSignOnTolerance == null) { // the SSO tolerance is gone (how much time before/after system time we'll allow the login request to be -// valid), + // valid), // don't authenticate return null; } @@ -1798,6 +1800,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } if (user != null) { + //don't allow to authenticate system user + if (user.getId() == User.UID_SYSTEM) { + s_logger.error("Failed to authenticate user: " + username + " in domain " + domainId); + return null; + } + if (s_logger.isDebugEnabled()) { s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in"); } @@ -1862,24 +1870,25 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId); - UserAccountVO user = _userAccountDao.findById(userAccount.getId()); - if (user != null) { - if ((user.getState().toString()).equals("enabled")) { - if (!isInternalAccount(user.getType())) { + if (userAccount != null) { + if (userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString())) { + if (!isInternalAccount(userAccount.getType())) { //Internal accounts are not disabled - int attemptsMade = user.getLoginAttempts() + 1; + int attemptsMade = userAccount.getLoginAttempts() + 1; if (attemptsMade < _allowedLoginAttempts) { updateLoginAttempts(userAccount.getId(), attemptsMade, false); s_logger.warn("Login attempt failed. You have " + ( _allowedLoginAttempts - attemptsMade ) + " attempt(s) remaining"); } else { updateLoginAttempts(userAccount.getId(), _allowedLoginAttempts, true); - s_logger.warn("User " + user.getUsername() + " has been disabled due to multiple failed login attempts." + + s_logger.warn("User " + userAccount.getUsername() + " has been disabled due to multiple failed login attempts." + " Please contact admin."); } } } else { - s_logger.info("User " + user.getUsername() + " is disabled/locked"); + s_logger.info("User " + userAccount.getUsername() + " is disabled/locked"); } + } else { + s_logger.warn("Authentication failure: No user with name " + username + " for domainId " + domainId); } return null; } @@ -1894,8 +1903,14 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag public String[] createApiKeyAndSecretKey(RegisterCmd cmd) { Long userId = cmd.getId(); - if (getUserIncludingRemoved(userId) == null) { - throw new InvalidParameterValueException("unable to find user for id : " + userId); + User user = getUserIncludingRemoved(userId); + if (user == null) { + throw new InvalidParameterValueException("unable to find user by id"); + } + + //don't allow updating system user + if (user.getId() == User.UID_SYSTEM) { + throw new PermissionDeniedException("user id : " + user.getId() + " is system account, update is not allowed"); } // generate both an api key and a secret key, update the user table with the keys, return the keys to the user @@ -1965,7 +1980,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } @Override - public List searchForAccounts(ListAccountsCmd cmd) { + public Pair, Integer> searchForAccounts(ListAccountsCmd cmd) { Account caller = UserContext.current().getCaller(); Long domainId = cmd.getDomainId(); Long accountId = cmd.getId(); @@ -2007,7 +2022,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (domainId == null) { domainId = caller.getDomainId(); } - } else if (domainId != null) { + } else if (isAdmin(caller.getType()) && domainId != null) { listForDomain = true; } else { accountId = caller.getAccountId(); @@ -2080,11 +2095,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } - return _accountDao.search(sc, searchFilter); + Pair, Integer> result = _accountDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { + public Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { Account caller = UserContext.current().getCaller(); Long domainId = cmd.getDomainId(); @@ -2114,7 +2130,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (id != null && id == 1) { // system user should NOT be searchable List emptyList = new ArrayList(); - return emptyList; + return new Pair, Integer>(emptyList, 0); } else if (id != null) { sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); } else { @@ -2177,7 +2193,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag sc.setParameters("state", state); } - return _userAccountDao.search(sc, searchFilter); + Pair, Integer> result = _userAccountDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index 8905be0b722..c2346162028 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -47,6 +47,7 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.user.dao.AccountDao; +import com.cloud.utils.Pair; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; @@ -349,7 +350,7 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager } @Override - public List searchForDomains(ListDomainsCmd cmd) { + public Pair, Integer> searchForDomains(ListDomainsCmd cmd) { Account caller = UserContext.current().getCaller(); Long domainId = cmd.getId(); boolean listAll = cmd.listAll(); @@ -407,11 +408,12 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager // return only Active domains to the API sc.setParameters("state", Domain.State.Active); - return _domainDao.search(sc, searchFilter); + Pair, Integer> result = _domainDao.searchAndCount(sc, searchFilter); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForDomainChildren(ListDomainChildrenCmd cmd) throws PermissionDeniedException { + public Pair, Integer> searchForDomainChildren(ListDomainChildrenCmd cmd) throws PermissionDeniedException { Long domainId = cmd.getId(); String domainName = cmd.getDomainName(); Boolean isRecursive = cmd.isRecursive(); @@ -433,12 +435,12 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager } Filter searchFilter = new Filter(DomainVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - List domainList = searchForDomainChildren(searchFilter, domainId, domainName, keyword, path, true); + Pair, Integer> result = searchForDomainChildren(searchFilter, domainId, domainName, keyword, path, true); - return domainList; + return new Pair, Integer>(result.first(), result.second()); } - private List searchForDomainChildren(Filter searchFilter, Long domainId, String domainName, Object keyword, String path, boolean listActiveOnly) { + private Pair, Integer> searchForDomainChildren(Filter searchFilter, Long domainId, String domainName, Object keyword, String path, boolean listActiveOnly) { SearchCriteria sc = _domainDao.createSearchCriteria(); if (keyword != null) { @@ -465,7 +467,7 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager sc.addAnd("state", SearchCriteria.Op.EQ, Domain.State.Active); } - return _domainDao.search(sc, searchFilter); + return _domainDao.searchAndCount(sc, searchFilter); } } diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 11d2c64016f..4ce9bfee86d 100755 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -96,9 +96,9 @@ public interface UserVmManager extends VirtualMachineGuru, UserVmServi * @param listAll TODO * @param listProjectResourcesCriteria TODO * @param tags TODO - * @return List of UserVMs. + * @return List of UserVMs + count */ - List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags); + Pair, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags); String getChecksum(Long hostId, String templatePath); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 6488fa64410..585b346ec28 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2250,12 +2250,17 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue()); } if (network.getVpcId() != null) { - //Only XenServer, KVM, and VmWare hypervisors are supported for vpc networks - if (!vpcSupportedHTypes.contains(template.getHypervisorType())) { + //Only ISOs, XenServer, KVM, and VmWare template types are supported for vpc networks + if (template.getFormat() != ImageFormat.ISO && !vpcSupportedHTypes.contains(template.getHypervisorType())) { throw new InvalidParameterValueException("Can't create vm from template with hypervisor " + template.getHypervisorType() + " in vpc network " + network); } + //Only XenServer, KVM, and VMware hypervisors are supported for vpc networks + if (!vpcSupportedHTypes.contains(hypervisor)) { + throw new InvalidParameterValueException("Can't create vm of hypervisor type " + hypervisor + " in vpc network"); + } + } _networkMgr.checkNetworkPermissions(owner, network); @@ -2985,7 +2990,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } @Override - public List searchForUserVMs(ListVMsCmd cmd) { + public Pair, Integer> searchForUserVMs(ListVMsCmd cmd) { Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); String hypervisor = cmd.getHypervisor(); @@ -3034,11 +3039,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } c.addCriteria(Criteria.ISADMIN, _accountMgr.isAdmin(caller.getType())); - return searchForUserVMs(c, caller, domainId, isRecursive, permittedAccounts, listAll, listProjectResourcesCriteria, tags); + Pair, Integer> result = searchForUserVMs(c, caller, domainId, isRecursive, + permittedAccounts, listAll, listProjectResourcesCriteria, tags); + return new Pair, Integer>(result.first(), result.second()); } @Override - public List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, + public Pair, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { Filter searchFilter = new Filter(UserVmVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit()); @@ -3229,7 +3236,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } sc.setParameters("hostIdIN", (Object[]) hostIds); } else { - return new ArrayList(); + return new Pair, Integer>(new ArrayList(), 0); } } } @@ -3237,8 +3244,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (storageId != null) { sc.setJoinParameters("volumeSearch", "poolId", storageId); } - s_logger.debug("THE WHERE CLAUSE IS:" + sc.getWhereClause()); - return _vmDao.search(sc, searchFilter); + + return _vmDao.searchAndCount(sc, searchFilter); } @Override diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index b20817792dd..9230f4ae729 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1995,7 +1995,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } if (vm.getHostId() == null || hostId != vm.getHostId()) { try { - stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); + ItWorkVO workItem = _workDao.findByOutstandingWork(vm.getId(), State.Migrating); + if(workItem == null){ + stateTransitTo(vm, VirtualMachine.Event.AgentReportMigrated, hostId); + } } catch (NoTransitionException e) { } } diff --git a/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java b/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java index 8713a3d3af3..e0d113d3be5 100644 --- a/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java +++ b/server/src/com/cloud/vm/dao/ConsoleProxyDaoImpl.java @@ -90,7 +90,7 @@ public class ConsoleProxyDaoImpl extends GenericDaoBase im private static final String GET_PROXY_ACTIVE_LOAD = "SELECT active_session AS count" + " FROM console_proxy" + - " WHERE proxy_id=?"; + " WHERE id=?"; private static final String STORAGE_POOL_HOST_INFO = "SELECT p.data_center_id, count(ph.host_id) " + diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/server/src/com/cloud/vm/dao/DomainRouterDao.java index 01e32588007..95d1ea6ca14 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDao.java @@ -61,7 +61,24 @@ public interface DomainRouterDao extends GenericDao { */ public List listByHostId(Long hostId); public List listByLastHostId(Long hostId); - + + /** + * list virtual machine routers by pod id. pass in null to get all + * virtual machine routers. + * @param podId id of the pod. null if to get all. + * @return list of DomainRouterVO + */ + public List listByPodId(Long podId); + + /** + * list virtual machine routers by pod id. pass in null to get all + * virtual machine routers. + * @param podId id of the pod. null if to get all. + * @param state state of the domain router. null if to get all. + * @return list of DomainRouterVO + */ + public List listByPodIdAndStates(Long podId, State... states); + /** * list virtual machine routers by host id. * pass in null to get all diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 175d3f28d04..9ab3ad0f465 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -41,6 +41,7 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @Local(value = { DomainRouterDao.class }) @@ -66,6 +67,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ); AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ); AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("states", AllFieldsSearch.entity().getState(), Op.IN); SearchBuilder joinRouterNetwork = _routerNetworkDao.createSearchBuilder(); joinRouterNetwork.and("networkId", joinRouterNetwork.entity().getNetworkId(), Op.EQ); AllFieldsSearch.join("networkRouter", joinRouterNetwork, joinRouterNetwork.entity().getRouterId(), AllFieldsSearch.entity().getId(), JoinType.INNER); @@ -177,6 +179,21 @@ public class DomainRouterDaoImpl extends GenericDaoBase im return listBy(sc); } + @Override + public List listByPodId(Long podId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("podId", podId); + return listBy(sc); + } + + @Override + public List listByPodIdAndStates(Long podId, State... states) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("podId", podId); + sc.setParameters("states", (Object[]) states); + return listBy(sc); + } + @Override public List listIsolatedByHostId(Long hostId) { SearchCriteria sc = HostUpSearch.create(); diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/server/src/com/cloud/vm/dao/VMInstanceDao.java index 2cf3d75018c..8b0a523f56c 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDao.java @@ -46,7 +46,14 @@ public interface VMInstanceDao extends GenericDao, StateDao< * @return list of VMInstanceVO in the specified zone */ List listByZoneId(long zoneId); - + + /** + * List VMs by pod ID + * @param podId + * @return list of VMInstanceVO in the specified pod + */ + List listByPodId(long podId); + /** * Lists non-expunged VMs by zone ID and templateId * @param zoneId @@ -76,8 +83,8 @@ public interface VMInstanceDao extends GenericDao, StateDao< List listByZoneIdAndType(long zoneId, VirtualMachine.Type type); List listUpByHostId(Long hostId); List listByLastHostId(Long hostId); - - List listByTypeAndState(State state, VirtualMachine.Type type); + + List listByTypeAndState(VirtualMachine.Type type, State state); List listByAccountId(long accountId); public Long countAllocatedVirtualRoutersForAccount(long accountId); diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 571b5d1841c..85ad5d02e87 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -230,14 +230,20 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem return listBy(sc); } - + + @Override + public List listByPodId(long podId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("pod", podId); + return listBy(sc); + } + @Override public List listByClusterId(long clusterId) { SearchCriteria sc = VMClusterSearch.create(); sc.setJoinParameters("hostSearch", "clusterId", clusterId); return listBy(sc); } - @Override public List listLHByClusterId(long clusterId) { @@ -309,7 +315,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem } @Override - public List listByTypeAndState(State state, VirtualMachine.Type type) { + public List listByTypeAndState(VirtualMachine.Type type, State state) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("type", type); sc.setParameters("state", state); diff --git a/server/test/com/cloud/async/TestSyncQueueManager.java b/server/test/com/cloud/async/TestSyncQueueManager.java index f8be9b696b6..2bbf7bcc8bd 100644 --- a/server/test/com/cloud/async/TestSyncQueueManager.java +++ b/server/test/com/cloud/async/TestSyncQueueManager.java @@ -32,178 +32,178 @@ public class TestSyncQueueManager extends ComponentTestCase { private volatile int count = 0; private volatile long expectingCurrent = 1; - public void leftOverItems() { - SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( - SyncQueueManager.class); - - List l = mgr.getActiveQueueItems(1L, false); - if(l != null && l.size() > 0) { - for(SyncQueueItemVO item : l) { - s_logger.info("Left over item: " + item.toString()); - mgr.purgeItem(item.getId()); - } - } - } - - public void dequeueFromOneQueue() { - final SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( - SyncQueueManager.class); - - final int totalRuns = 5000; - final SyncQueueVO queue = mgr.queue("vm_instance", 1L, "Async-job", 1); - for(int i = 1; i < totalRuns; i++) - mgr.queue("vm_instance", 1L, "Async-job", i+1); - - count = 0; - expectingCurrent = 1; - Thread thread1 = new Thread(new Runnable() { - public void run() { - while(count < totalRuns) { - SyncQueueItemVO item = mgr.dequeueFromOne(queue.getId(), 1L); - if(item != null) { - s_logger.info("Thread 1 process item: " + item.toString()); - - Assert.assertEquals(expectingCurrent, item.getContentId().longValue()); - expectingCurrent++; - count++; - - mgr.purgeItem(item.getId()); - } - try { - Thread.sleep(getRandomMilliseconds(1, 10)); - } catch (InterruptedException e) { - } - } - } - } - ); - - Thread thread2 = new Thread(new Runnable() { - public void run() { - while(count < totalRuns) { - SyncQueueItemVO item = mgr.dequeueFromOne(queue.getId(), 1L); - if(item != null) { - s_logger.info("Thread 2 process item: " + item.toString()); - - Assert.assertEquals(expectingCurrent, item.getContentId().longValue()); - expectingCurrent++; - count++; - mgr.purgeItem(item.getId()); - } - - try { - Thread.sleep(getRandomMilliseconds(1, 10)); - } catch (InterruptedException e) { - } - } - } - } - ); - - thread1.start(); - thread2.start(); - try { - thread1.join(); - } catch (InterruptedException e) { - } - try { - thread2.join(); - } catch (InterruptedException e) { - } - - Assert.assertEquals(totalRuns, count); - } - - public void dequeueFromAnyQueue() { - final SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( - SyncQueueManager.class); - - // simulate 30 queues - final int queues = 30; - final int totalRuns = 100; - final int itemsPerRun = 20; - for(int q = 1; q <= queues; q++) - for(int i = 0; i < totalRuns; i++) - mgr.queue("vm_instance", q, "Async-job", i+1); - - count = 0; - Thread thread1 = new Thread(new Runnable() { - public void run() { - while(count < totalRuns*queues) { - List l = mgr.dequeueFromAny(1L, itemsPerRun); - if(l != null && l.size() > 0) { - s_logger.info("Thread 1 get " + l.size() + " dequeued items"); - - for(SyncQueueItemVO item : l) { - s_logger.info("Thread 1 process item: " + item.toString()); - count++; - - mgr.purgeItem(item.getId()); - } - } - try { - Thread.sleep(getRandomMilliseconds(1, 10)); - } catch (InterruptedException e) { - } - } - } - } - ); - - Thread thread2 = new Thread(new Runnable() { - public void run() { - while(count < totalRuns*queues) { - List l = mgr.dequeueFromAny(1L, itemsPerRun); - if(l != null && l.size() > 0) { - s_logger.info("Thread 2 get " + l.size() + " dequeued items"); - - for(SyncQueueItemVO item : l) { - s_logger.info("Thread 2 process item: " + item.toString()); - count++; - mgr.purgeItem(item.getId()); - } - } - - try { - Thread.sleep(getRandomMilliseconds(1, 10)); - } catch (InterruptedException e) { - } - } - } - } - ); - - thread1.start(); - thread2.start(); - try { - thread1.join(); - } catch (InterruptedException e) { - } - try { - thread2.join(); - } catch (InterruptedException e) { - } - Assert.assertEquals(queues*totalRuns, count); - } - - public void testPopulateQueueData() { - final int queues = 30000; - final int totalRuns = 100; - - final SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( - SyncQueueManager.class); - for(int q = 1; q <= queues; q++) - for(int i = 0; i < totalRuns; i++) - mgr.queue("vm_instance", q, "Async-job", i+1); + public void leftOverItems() { + SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( + SyncQueueManager.class); + + List l = mgr.getActiveQueueItems(1L, false); + if(l != null && l.size() > 0) { + for(SyncQueueItemVO item : l) { + s_logger.info("Left over item: " + item.toString()); + mgr.purgeItem(item.getId()); + } + } + } + + public void dequeueFromOneQueue() { + final SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( + SyncQueueManager.class); + + final int totalRuns = 5000; + final SyncQueueVO queue = mgr.queue("vm_instance", 1L, "Async-job", 1, 1); + for(int i = 1; i < totalRuns; i++) + mgr.queue("vm_instance", 1L, "Async-job", i+1, 1); + + count = 0; + expectingCurrent = 1; + Thread thread1 = new Thread(new Runnable() { + public void run() { + while(count < totalRuns) { + SyncQueueItemVO item = mgr.dequeueFromOne(queue.getId(), 1L); + if(item != null) { + s_logger.info("Thread 1 process item: " + item.toString()); + + Assert.assertEquals(expectingCurrent, item.getContentId().longValue()); + expectingCurrent++; + count++; + + mgr.purgeItem(item.getId()); + } + try { + Thread.sleep(getRandomMilliseconds(1, 10)); + } catch (InterruptedException e) { + } + } + } + } + ); + + Thread thread2 = new Thread(new Runnable() { + public void run() { + while(count < totalRuns) { + SyncQueueItemVO item = mgr.dequeueFromOne(queue.getId(), 1L); + if(item != null) { + s_logger.info("Thread 2 process item: " + item.toString()); + + Assert.assertEquals(expectingCurrent, item.getContentId().longValue()); + expectingCurrent++; + count++; + mgr.purgeItem(item.getId()); + } + + try { + Thread.sleep(getRandomMilliseconds(1, 10)); + } catch (InterruptedException e) { + } + } + } + } + ); + + thread1.start(); + thread2.start(); + try { + thread1.join(); + } catch (InterruptedException e) { + } + try { + thread2.join(); + } catch (InterruptedException e) { + } + + Assert.assertEquals(totalRuns, count); + } + + public void dequeueFromAnyQueue() { + final SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( + SyncQueueManager.class); + + // simulate 30 queues + final int queues = 30; + final int totalRuns = 100; + final int itemsPerRun = 20; + for(int q = 1; q <= queues; q++) + for(int i = 0; i < totalRuns; i++) + mgr.queue("vm_instance", q, "Async-job", i+1, 1); + + count = 0; + Thread thread1 = new Thread(new Runnable() { + public void run() { + while(count < totalRuns*queues) { + List l = mgr.dequeueFromAny(1L, itemsPerRun); + if(l != null && l.size() > 0) { + s_logger.info("Thread 1 get " + l.size() + " dequeued items"); + + for(SyncQueueItemVO item : l) { + s_logger.info("Thread 1 process item: " + item.toString()); + count++; + + mgr.purgeItem(item.getId()); + } + } + try { + Thread.sleep(getRandomMilliseconds(1, 10)); + } catch (InterruptedException e) { + } + } + } + } + ); + + Thread thread2 = new Thread(new Runnable() { + public void run() { + while(count < totalRuns*queues) { + List l = mgr.dequeueFromAny(1L, itemsPerRun); + if(l != null && l.size() > 0) { + s_logger.info("Thread 2 get " + l.size() + " dequeued items"); + + for(SyncQueueItemVO item : l) { + s_logger.info("Thread 2 process item: " + item.toString()); + count++; + mgr.purgeItem(item.getId()); + } + } + + try { + Thread.sleep(getRandomMilliseconds(1, 10)); + } catch (InterruptedException e) { + } + } + } + } + ); + + thread1.start(); + thread2.start(); + try { + thread1.join(); + } catch (InterruptedException e) { + } + try { + thread2.join(); + } catch (InterruptedException e) { + } + Assert.assertEquals(queues*totalRuns, count); + } + + public void testPopulateQueueData() { + final int queues = 30000; + final int totalRuns = 100; + + final SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( + SyncQueueManager.class); + for(int q = 1; q <= queues; q++) + for(int i = 0; i < totalRuns; i++) + mgr.queue("vm_instance", q, "Async-job", i+1, 1); } public void testSyncQueue() { final SyncQueueManager mgr = ComponentLocator.getCurrentLocator().getManager( SyncQueueManager.class); - mgr.queue("vm_instance", 1, "Async-job", 1); - mgr.queue("vm_instance", 1, "Async-job", 2); - mgr.queue("vm_instance", 1, "Async-job", 3); + mgr.queue("vm_instance", 1, "Async-job", 1, 1); + mgr.queue("vm_instance", 1, "Async-job", 2, 1); + mgr.queue("vm_instance", 1, "Async-job", 3, 1); mgr.dequeueFromAny(100L, 1); List l = mgr.getBlockedQueueItems(100000, false); diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index c2ae1bfd29c..8c7b67f7bf0 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -441,7 +441,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public List searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) { + public Pair, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) { // TODO Auto-generated method stub return null; } @@ -477,7 +477,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public List listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize) { + public Pair, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize) { // TODO Auto-generated method stub return null; } @@ -537,7 +537,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public List listTrafficTypes(Long physicalNetworkId) { + public Pair, Integer> listTrafficTypes(Long physicalNetworkId) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/projects/MockProjectManagerImpl.java b/server/test/com/cloud/projects/MockProjectManagerImpl.java index af81c8651a1..d8bce2fcf81 100644 --- a/server/test/com/cloud/projects/MockProjectManagerImpl.java +++ b/server/test/com/cloud/projects/MockProjectManagerImpl.java @@ -28,6 +28,8 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.projects.ProjectAccount.Role; import com.cloud.user.Account; import com.cloud.utils.component.Manager; +import com.cloud.utils.Pair; + @Local(value = { ProjectManager.class }) public class MockProjectManagerImpl implements ProjectManager, Manager { @@ -104,14 +106,14 @@ public class MockProjectManagerImpl implements ProjectManager, Manager { } @Override - public List listProjectAccounts(long projectId, + public Pair, Integer> listProjectAccounts(long projectId, String accountName, String role, Long startIndex, Long pageSizeVal) { // TODO Auto-generated method stub return null; } @Override - public List listProjectInvitations(Long id, + public Pair, Integer> listProjectInvitations(Long id, Long projectId, String accountName, Long domainId, String state, boolean activeOnly, Long startIndex, Long pageSizeVal, boolean isRecursive, boolean listAll) { @@ -223,10 +225,16 @@ public class MockProjectManagerImpl implements ProjectManager, Manager { * @see com.cloud.projects.ProjectService#listProjects(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Long, java.lang.String, java.lang.Long, java.lang.Long, boolean, boolean, java.util.Map) */ @Override - public List listProjects(Long id, String name, String displayText, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, + public Pair, Integer> listProjects(Long id, String name, String displayText, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSize, boolean listAll, boolean isRecursive, Map tags) { // TODO Auto-generated method stub return null; } + + @Override + public Project findByProjectAccountIdIncludingRemoved(long projectAccountId) { + return null; + } + } diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index 0d15cd7de0a..08234fda0a0 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -298,13 +298,13 @@ public class MockAccountManagerImpl implements Manager, AccountManager, AccountS } @Override - public List searchForAccounts(ListAccountsCmd cmd) { + public Pair, Integer> searchForAccounts(ListAccountsCmd cmd) { // TODO Auto-generated method stub return null; } @Override - public List searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { + public Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/user/MockDomainManagerImpl.java b/server/test/com/cloud/user/MockDomainManagerImpl.java index e99e4d94265..4266f3553e5 100644 --- a/server/test/com/cloud/user/MockDomainManagerImpl.java +++ b/server/test/com/cloud/user/MockDomainManagerImpl.java @@ -29,6 +29,7 @@ import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.exception.PermissionDeniedException; import com.cloud.utils.component.Manager; +import com.cloud.utils.Pair; @Local(value = { DomainManager.class }) public class MockDomainManagerImpl implements Manager, DomainManager { @@ -58,14 +59,14 @@ public class MockDomainManagerImpl implements Manager, DomainManager { } @Override - public List searchForDomains(ListDomainsCmd cmd) + public Pair, Integer> searchForDomains(ListDomainsCmd cmd) throws PermissionDeniedException { // TODO Auto-generated method stub return null; } @Override - public List searchForDomainChildren( + public Pair, Integer> searchForDomainChildren( ListDomainChildrenCmd cmd) throws PermissionDeniedException { // TODO Auto-generated method stub return null; diff --git a/server/test/com/cloud/vm/MockUserVmManagerImpl.java b/server/test/com/cloud/vm/MockUserVmManagerImpl.java index efc6916ab40..35ee1396504 100644 --- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java +++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java @@ -192,7 +192,7 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana } @Override - public List searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { + public Pair, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { // TODO Auto-generated method stub return null; } @@ -401,7 +401,7 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana } @Override - public List searchForUserVMs(ListVMsCmd cmd) { + public Pair, Integer> searchForUserVMs(ListVMsCmd cmd) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index dfd4f7e839f..e1b6ad429a9 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -268,7 +268,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager{ * @see com.cloud.network.NetworkService#searchPhysicalNetworks(java.lang.Long, java.lang.Long, java.lang.String, java.lang.Long, java.lang.Long, java.lang.String) */ @Override - public List searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) { + public Pair, Integer> searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name) { // TODO Auto-generated method stub return null; } @@ -322,7 +322,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager{ * @see com.cloud.network.NetworkService#listNetworkServiceProviders(java.lang.Long, java.lang.String, java.lang.String, java.lang.Long, java.lang.Long) */ @Override - public List listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize) { + public Pair, Integer> listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize) { // TODO Auto-generated method stub return null; } @@ -430,7 +430,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager{ * @see com.cloud.network.NetworkService#listTrafficTypes(java.lang.Long) */ @Override - public List listTrafficTypes(Long physicalNetworkId) { + public Pair, Integer> listTrafficTypes(Long physicalNetworkId) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java b/server/test/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java index 4cd742ca4a3..64db5bbfb79 100644 --- a/server/test/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java +++ b/server/test/com/cloud/vpc/MockSite2SiteVpnManagerImpl.java @@ -41,6 +41,7 @@ import com.cloud.network.Site2SiteVpnConnectionVO; import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.vpn.Site2SiteVpnManager; import com.cloud.network.vpn.Site2SiteVpnService; +import com.cloud.utils.Pair; import com.cloud.utils.component.Manager; import com.cloud.vm.DomainRouterVO; @@ -132,7 +133,7 @@ public class MockSite2SiteVpnManagerImpl implements Site2SiteVpnManager, Site2Si * @see com.cloud.network.vpn.Site2SiteVpnService#searchForCustomerGateways(com.cloud.api.commands.ListVpnCustomerGatewaysCmd) */ @Override - public List searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd) { + public Pair, Integer> searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd) { // TODO Auto-generated method stub return null; } @@ -141,7 +142,7 @@ public class MockSite2SiteVpnManagerImpl implements Site2SiteVpnManager, Site2Si * @see com.cloud.network.vpn.Site2SiteVpnService#searchForVpnGateways(com.cloud.api.commands.ListVpnGatewaysCmd) */ @Override - public List searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd) { + public Pair, Integer> searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd) { // TODO Auto-generated method stub return null; } @@ -150,7 +151,7 @@ public class MockSite2SiteVpnManagerImpl implements Site2SiteVpnManager, Site2Si * @see com.cloud.network.vpn.Site2SiteVpnService#searchForVpnConnections(com.cloud.api.commands.ListVpnConnectionsCmd) */ @Override - public List searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd) { + public Pair, Integer> searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/MockVpcManagerImpl.java b/server/test/com/cloud/vpc/MockVpcManagerImpl.java index fc10a466087..1f41395b16a 100644 --- a/server/test/com/cloud/vpc/MockVpcManagerImpl.java +++ b/server/test/com/cloud/vpc/MockVpcManagerImpl.java @@ -49,6 +49,7 @@ import com.cloud.network.vpc.VpcService; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.user.User; +import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Manager; import com.cloud.vm.DomainRouterVO; @@ -244,7 +245,7 @@ public class MockVpcManagerImpl implements VpcManager, Manager{ * @see com.cloud.network.vpc.VpcService#listPrivateGateway(com.cloud.api.commands.ListPrivateGatewaysCmd) */ @Override - public List listPrivateGateway(ListPrivateGatewaysCmd listPrivateGatewaysCmd) { + public Pair, Integer> listPrivateGateway(ListPrivateGatewaysCmd listPrivateGatewaysCmd) { // TODO Auto-generated method stub return null; } @@ -289,7 +290,7 @@ public class MockVpcManagerImpl implements VpcManager, Manager{ * @see com.cloud.network.vpc.VpcService#listStaticRoutes(com.cloud.api.commands.ListStaticRoutesCmd) */ @Override - public List listStaticRoutes(ListStaticRoutesCmd cmd) { + public Pair, Integer> listStaticRoutes(ListStaticRoutesCmd cmd) { // TODO Auto-generated method stub return null; } @@ -343,7 +344,7 @@ public class MockVpcManagerImpl implements VpcManager, Manager{ * @see com.cloud.network.vpc.VpcManager#destroyVpc(com.cloud.network.vpc.Vpc) */ @Override - public boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean destroyVpc(Vpc vpc, Account caller, Long callerUserId) throws ConcurrentOperationException, ResourceUnavailableException { // TODO Auto-generated method stub return false; } diff --git a/server/test/com/cloud/vpc/VpcApiUnitTest.java b/server/test/com/cloud/vpc/VpcApiUnitTest.java index ad323d29e5b..5cc325ffac0 100644 --- a/server/test/com/cloud/vpc/VpcApiUnitTest.java +++ b/server/test/com/cloud/vpc/VpcApiUnitTest.java @@ -193,7 +193,7 @@ public class VpcApiUnitTest extends TestCase{ protected void destroyVpc() { try { - _vpcService.destroyVpc(_vpcService.getVpc(1)); + _vpcService.destroyVpc(_vpcService.getVpc(1), new AccountVO(), 1L); } catch (Exception ex) { s_logger.error("Destroy VPC TEST FAILED due to exc ", ex); } diff --git a/server/test/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java b/server/test/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java index 5d759b8aa3a..8b9d362276d 100644 --- a/server/test/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java +++ b/server/test/com/cloud/vpc/dao/MockVpcVirtualRouterElement.java @@ -20,10 +20,11 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.element.VpcVirtualRouterElement; import com.cloud.network.vpc.Vpc; +import com.cloud.vm.ReservationContext; public class MockVpcVirtualRouterElement extends VpcVirtualRouterElement{ @Override - public boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } diff --git a/setup/bindir/cloud-set-guest-password.in b/setup/bindir/cloud-set-guest-password.in index 97e6e3d7bee..321589466c4 100755 --- a/setup/bindir/cloud-set-guest-password.in +++ b/setup/bindir/cloud-set-guest-password.in @@ -27,7 +27,7 @@ user=root # Add your DHCP lease folders here -DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/*" +DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/* /var/lib/dhcp/*" password_received=0 file_count=0 error_count=0 @@ -39,7 +39,7 @@ do file_count=$((file_count+1)) PASSWORD_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;') - if [ -n $PASSWORD_SERVER_IP ] + if [ -n "$PASSWORD_SERVER_IP" ] then logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $DHCP_FILE" logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP" @@ -95,7 +95,7 @@ then fi logger -t "cloud" "Changing password ..." -echo $password | passwd --stdin $user +echo $user:$password | chpasswd if [ $? -gt 0 ] then diff --git a/setup/bindir/cloud-set-guest-sshkey.in b/setup/bindir/cloud-set-guest-sshkey.in index 69124dca4c1..15008b8d514 100755 --- a/setup/bindir/cloud-set-guest-sshkey.in +++ b/setup/bindir/cloud-set-guest-sshkey.in @@ -40,7 +40,7 @@ do file_count=$((file_count+1)) SSHKEY_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;') - if [ -n $SSHKEY_SERVER_IP ] + if [ -n "$SSHKEY_SERVER_IP" ] then logger -t "cloud" "Sending request to ssh key server at $SSHKEY_SERVER_IP" diff --git a/setup/bindir/cloud-setup-databases.in b/setup/bindir/cloud-setup-databases.in index 54c411d7f7b..bd5a0ba11f3 100755 --- a/setup/bindir/cloud-setup-databases.in +++ b/setup/bindir/cloud-setup-databases.in @@ -8,9 +8,9 @@ # to you 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 @@ -18,7 +18,6 @@ # specific language governing permissions and limitations # under the License. - import os import sys import subprocess @@ -78,12 +77,12 @@ class DBDeployer(object): def backUpDbDotProperties(): dbpPath = os.path.join(self.dbConfPath, 'db.properties') copyPath = os.path.join(self.dbConfPath, 'db.properties.origin') - + if os.path.isfile(dbpPath): shutil.copy2(dbpPath, copyPath) - + backUpDbDotProperties() - + def postRun(self): def cleanOrRecoverDbDotProperties(): dbpPath = os.path.join(self.dbConfPath, 'db.properties') @@ -92,24 +91,24 @@ class DBDeployer(object): if not self.success: shutil.copy2(copyPath, dbpPath) os.remove(copyPath) - + cleanOrRecoverDbDotProperties() if os.path.exists(self.tmpMysqlFile): os.remove(self.tmpMysqlFile) - - + + def info(self, msg, result=None): output = "" if msg is not None: output = "%-80s"%msg - + if result is True: output += "[ \033[92m%-2s\033[0m ]\n"%"OK" elif result is False: output += "[ \033[91m%-6s\033[0m ]\n"%"FAILED" sys.stdout.write(output) sys.stdout.flush() - + def debug(self, msg): msg = "DEBUG:%s"%msg sys.stdout.write(msg) @@ -122,13 +121,13 @@ class DBDeployer(object): else: self.dbDotProperties[key] = (value, self.dbDotPropertiesIndex) self.dbDotPropertiesIndex += 1 - + def getDbProperty(self, key): if not self.dbDotProperties.has_key(key): return None (value, index) = self.dbDotProperties[key] return value - + def runMysql(self, text, table, isRoot=False): kwargs = {} if not isRoot: @@ -137,7 +136,7 @@ class DBDeployer(object): else: kwargs['user'] = self.rootuser if self.rootpassword != '': kwargs['passwd'] = self.rootpassword - + kwargs['port'] = self.port kwargs['host'] = self.host @@ -149,6 +148,7 @@ class DBDeployer(object): mysqlCmds.append('<') mysqlCmds.append(self.tmpMysqlFile) runCmd(mysqlCmds) + except Exception, e: err = '''Encountering an error when executing mysql script ---------------------------------------------------------------------- @@ -163,13 +163,13 @@ Sql parameters: ---------------------------------------------------------------------- '''%(table, e.__str__(), kwargs) self.errorAndExit(err) - + def errorAndExit(self, msg): self.postRun() err = '''\n\nWe apologize for below error: -*************************************************************** +*************************************************************** %s -*************************************************************** +*************************************************************** Please run: cloud-setup-database -h @@ -184,7 +184,7 @@ for full help if not self.rootuser: self.info("No mysql root user specified, will not create Cloud DB schema\n", None) return - + replacements = ( ("CREATE USER cloud identified by 'cloud';", "CREATE USER %s@`localhost` identified by '%s'; CREATE USER %s@`%%` identified by '%s';"%( @@ -211,7 +211,7 @@ for full help ("CALL `test`.`drop_user_if_exists`() ;", ""), ) - + for f in ["create-database","create-schema","create-database-premium","create-schema-premium"]: p = os.path.join(self.dbFilesPath,"%s.sql"%f) if not os.path.exists(p): continue @@ -220,7 +220,7 @@ for full help self.info("Applying %s"%p) self.runMysql(text, p, True) self.info(None, True) - + if self.serversetup: conf = os.path.join(self.dbConfPath, 'db.properties') pcp = os.path.pathsep.join( glob.glob( os.path.join ( r"@PREMIUMJAVADIR@" , "*" ) ) ) @@ -243,21 +243,41 @@ for full help self.info("Applying %s"%p) self.runMysql(text, p, True) self.info(None, True) - + for f in ["templates","create-index-fk"]: p = os.path.join(self.dbFilesPath,"%s.sql"%f) text = file(p).read() self.info("Applying %s"%p) self.runMysql(text, p, True) self.info(None, True) - + p = os.path.join(self.dbFilesPath,"schema-level.sql") if os.path.isfile(p): text = file(p).read() self.info("Applying %s"%p) self.runMysql(text, p, True) self.info(None, True) - + + awsApiDbDir = '/usr/share/cloud/setup/bridge/db' + for f in ["cloudbridge_db.sql"]: + p = os.path.join(awsApiDbDir,f) + if not os.path.exists(p): continue + text = file(p).read() + for t, r in replacements: text = text.replace(t,r) + self.info("Applying %s"%p) + self.runMysql(text, p, True) + self.info(None, True) + + for f in ["cloudbridge_schema", "cloudbridge_multipart", "cloudbridge_index", "cloudbridge_multipart_alter", "cloudbridge_bucketpolicy", "cloudbridge_policy_alter", + "cloudbridge_offering", "cloudbridge_offering_alter"]: + if os.path.isfile(p): + p = os.path.join(awsApiDbDir,"%s.sql"%f) + if not os.path.exists(p): continue + text = file(p).read() + self.info("Applying %s"%p) + self.runMysql(text, p, True) + self.info(None, True) + def prepareDBFiles(self): def prepareDBDotProperties(): dbpPath = os.path.join(self.dbConfPath, 'db.properties') @@ -269,7 +289,7 @@ for full help line = line.strip() if line.startswith("#"): key = line; value = ''; passed = True if line == '' or line == '\n': key = self.magicString + str(emptyLine); value = ''; emptyLine += 1; passed = True - + try: if not passed: (key, value) = line.split('=', 1) @@ -292,9 +312,9 @@ for example: self.errorAndExit(err) self.putDbProperty(key, value) self.info("Preparing %s"%dbpPath, True) - + prepareDBDotProperties() - + def finalize(self): def finalizeDbProperties(): entries = [] @@ -307,12 +327,12 @@ for example: else: entries.insert(index, "%s=%s"%(key, value)) file(os.path.join(self.dbConfPath, 'db.properties'), 'w').write('\n'.join(entries)) - + self.info("Finalizing setup ...", None) finalizeDbProperties() self.info(None, True) self.success = True # At here, we have done successfully and nothing more after this flag is set - + def grabSystemInfo(self): def getIpAddr(): try: @@ -326,10 +346,11 @@ for example: return '127.0.0.1' except Exception, e: return "127.0.0.1" - - self.ip = getIpAddr() - self.info("Detected local IP address as %s, will use as cluster management server node IP"%self.ip, True) - + + if not self.ip: + self.ip = getIpAddr() + self.info("Detected local IP address as %s, will use as cluster management server node IP" % self.ip, True) + def checkSystemSetup(self): def checkCloudDbFiles(): self.info("Checking Cloud database files ...", None) @@ -337,25 +358,25 @@ for example: for dbf in dbfpaths: if not os.path.exists(dbf): self.errorAndExit("Cannot find %s"%dbf) - + coreSchemas = ['create-database.sql', 'create-schema.sql', 'templates.sql', 'create-index-fk.sql'] if not self.serversetup: coreSchemas.append('server-setup.sql') - + checkingList = [os.path.join(self.dbFilesPath, x) for x in coreSchemas] checkingList.append(self.encryptionJarPath) for f in checkingList: if not os.path.isfile(f): self.errorAndExit("Cloud DB required file %s was not found"%f) self.info(None, True) - + def checkDbserverHostname(): self.info("Checking mysql server hostname ...", None) if resolves_to_ipv6(self, self.port): err = "%s resolves to an IPv6 address. The CloudStack does not support IPv6 yet.\nPlease fix this issue in either /etc/hosts or your DNS configuration.\n"%self.host self.errorAndExit(err) self.info(None, True) - + def checkHostName(): self.info("Checking local machine hostname ...", None) try: @@ -364,7 +385,7 @@ for example: err = "The host name of this computer does not resolve to an IP address.\nPlease use your operating system's network setup tools to fix this ('hostname --fqdn' %s).\n"%e.__str__() self.errorAndExit(err) self.info(None, True) - + def checkSELinux(): self.info("Checking SELinux setup ...", None) try: @@ -375,54 +396,54 @@ for example: if e.errno == 2: pass else: self.errorAndExit(e.__str__()) self.info(None, True) - + checkCloudDbFiles() checkHostName() checkSELinux() - + def processEncryptionStuff(self): def encrypt(input): cmd = ['java','-classpath',self.encryptionJarPath,'org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI', 'encrypt.sh', 'input=%s'%input, 'password=%s'%self.mgmtsecretkey,'verbose=false'] return runCmd(cmd).strip('\n') - + def saveMgmtServerSecretKey(): if self.encryptiontype == 'file': file(self.encryptionKeyFile, 'w').write(self.mgmtsecretkey) - + def formatEncryptResult(value): return 'ENC(%s)'%value - + def encryptDBSecretKey(): self.putDbProperty('db.cloud.encrypt.secret', formatEncryptResult(encrypt(self.dbsecretkey))) - + def encryptDBPassword(): dbPassword = self.getDbProperty('db.cloud.password') if dbPassword == '': return # Don't encrypt empty password if dbPassword == None: self.errorAndExit('Cannot find db.cloud.password in %s'%os.path.join(self.dbConfPath, 'db.properties')) self.putDbProperty('db.cloud.password', formatEncryptResult(encrypt(dbPassword))) - + usagePassword = self.getDbProperty('db.usage.password') if usagePassword == '': return # Don't encrypt empty password if usagePassword == None: self.errorAndExit('Cannot find db.usage.password in %s'%os.path.join(self.dbConfPath, 'db.properties')) self.putDbProperty('db.usage.password', formatEncryptResult(encrypt(usagePassword))) - + self.info("Processing encryption ...", None) self.putDbProperty("db.cloud.encryption.type", self.encryptiontype) saveMgmtServerSecretKey() encryptDBSecretKey() encryptDBPassword() self.info(None, True) - + def parseOptions(self): def parseOtherOptions(): if self.options.rootcreds: self.rootuser,self.rootpassword = parseUserAndPassword(self.options.rootcreds) if self.rootuser == self.user: self.errorAndExit("--deploy-as= user name cannot be the user name supplied for the connection credentials") - + self.info("Mysql root user name:%s"%self.rootuser, True) self.info("Mysql root user password:%s"%self.rootpassword, True) - + if self.options.serversetup: if not self.options.rootcreds: self.errorAndExit("--auto= requires valid --deploy-as= credentials") @@ -430,12 +451,16 @@ for example: self.errorAndExit("%s is not a valid file"%self.options.serversetup) self.serversetup = self.options.serversetup self.info("User specified server-setup.sql file at %s"%self.serversetup, True) - + + if self.options.mshostip: + self.ip = self.options.mshostip + self.info("Using specified cluster management server node IP %s" % self.options.mshostip, True) + self.encryptiontype = self.options.encryptiontype self.mgmtsecretkey = self.options.mgmtsecretkey self.dbsecretkey = self.options.dbsecretkey self.isDebug = self.options.debug - + def parseUserAndPassword(cred): stuff = cred.split(':') if len(stuff) != 1 and len(stuff) != 2: @@ -447,13 +472,13 @@ for example: password = '' else: password = stuff[1] - + forbidden = "' \\`" for f in forbidden: if f in user: self.errorAndExit("User name cannot have the %r characters"%f) if f in password: self.errorAndExit("Password cannot have the %r characters"%f) return user, password - + def parseCasualCredit(): def parseHostInfo(info): stuff = info.split(":") @@ -468,18 +493,26 @@ for example: else: self.errorAndExit("Invalid host and port format, it must be in format of host:port (%s)"%info) return host, port - + if len(self.args) == 0: self.errorAndExit("Please specify user:password@hostname") if len(self.args) > 1: self.errorAndExit("There are more than one parameters for user:password@hostname (%s)"%self.args) - + arg = self.args[0] - stuff = arg.split("@", 1) - if len(stuff) == 1: stuff.append("localhost") + try: + try: + splitIndex = arg.rindex('@') + except ValueError: + # If it failed to find @, use host=localhost + splitIndex = len(arg) + arg += "@localhost" + finally: + stuff = [arg[:splitIndex], arg[splitIndex+1:]] + self.user,self.password = parseUserAndPassword(stuff[0]) self.host,self.port = parseHostInfo(stuff[1]) - + self.info("Mysql user name:%s"%self.user, True) if self.password: self.info("Mysql user password:%s"%self.password, True) @@ -487,32 +520,32 @@ for example: self.info("Mysql user password:", True) self.info("Mysql server ip:%s"%self.host, True) self.info("Mysql server port:%s"%self.port, True) - + def validateParameters(): if self.encryptiontype != 'file' and self.encryptiontype != 'web': self.errorAndExit('Wrong encryption type %s, --encrypt-type can only be "file" or "web'%self.encryptiontype) - + #---------------------- option parsing and command line checks ------------------------ usage = """%prog user:[password]@mysqlhost:[port] [--deploy-as=rootuser:[rootpassword]] [--auto=/path/to/server-setup.xml] [-e ENCRYPTIONTYPE] [-m MGMTSECRETKEY] [-k DBSECRETKEY] [--debug] - + This command sets up the CloudStack Management Server and CloudStack Usage Server database configuration (connection credentials and host information) based on the first argument. - + If the the --deploy-as option is present, this command will also connect to the database using the administrative credentials specified as the value for the --deploy-as argument, construct the database environment needed to run the CloudStack Management Server, and alter the password specified for the user in the first argument. In this case, the user name specified in --deploy-as= cannot be the same as the user name specified for the connection credentials that the CloudStack Management Server will be set up with. - + If a server-setup.xml cloud setup information file is specified with the --auto option, this command will also construct a customized database environment according to the cloud setup information in the file. - + The port and the password are optional and can be left out.. If host is omitted altogether, it will default to localhost. - + Examples: - - %prog cloud:secret + + %prog cloud:secret sets user cloud and password 'secret' up in @MSCONF@/db.properties, using localhost as the database server - - %prog sheng:rules@192.168.1.1 + + %prog sheng:rules@192.168.1.1 sets these credentials up in @MSCONF@/db.properties - + %prog alex:founder@1.2.3.4 --deploy-as=root:nonsense sets alex up as the MySQL user, then connects as the root user with password 'nonsense', and recreates the databases, creating @@ -522,7 +555,7 @@ for example: In addition actions performing in above example, using 'password' as management server encryption key and 'dbpassword' as database encryption key, saving management server encryption key to a file as the encryption type specified by -e is file. - + %prog alena:tests@5.6.7.8 --deploy-as=root:nonsense --auto=/root/server-setup.xml sets alena up as the MySQL user, then connects as the root user with password 'nonsense' to server 5.6.7.8, then recreates the @@ -542,12 +575,14 @@ for example: help="Secret key used to encrypt confidential parameters in db.properties. A string, default is password") self.parser.add_option("-k", "--database-secretkey", action="store", type="string", dest="dbsecretkey", default="password", help="Secret key used to encrypt sensitive database values. A string, default is password") - + self.parser.add_option("-i", "--mshost", action="store", type="string", dest="mshostip", default="", + help="Cluster management server host IP. A string, by default it will try to detect a local IP") + (self.options, self.args) = self.parser.parse_args() parseCasualCredit() parseOtherOptions() validateParameters() - + def run(self): try: self.preRun() @@ -560,7 +595,7 @@ for example: self.finalize() finally: self.postRun() - + print '' print "CloudStack has successfully initialized database, you can check your database configuration in %s"%os.path.join(self.dbConfPath, 'db.properties') print '' @@ -568,4 +603,4 @@ for example: if __name__ == "__main__": o = DBDeployer() o.run() - + diff --git a/setup/bindir/cloud-setup-encryption.in b/setup/bindir/cloud-setup-encryption.in index f2de2ec7b99..19ad721ccbe 100755 --- a/setup/bindir/cloud-setup-encryption.in +++ b/setup/bindir/cloud-setup-encryption.in @@ -63,7 +63,7 @@ class DBDeployer(object): dbDotProperties = {} dbDotPropertiesIndex = 0 encryptionKeyFile = '@MSCONF@/key' - encryptionJarPath = '@JAVADIR@/cloud-jasypt-1.8.jar' + encryptionJarPath = '@JAVADIR@/cloud-jasypt-1.8.jar:@JAVADIR@/jasypt-1.8.jar:@JAVADIR@/jasypt-1.9.0.jar' success = False magicString = 'This_is_a_magic_string_i_think_no_one_will_duplicate' @@ -184,7 +184,7 @@ for example: def processEncryptionStuff(self): def encrypt(input): - cmd = ['java','-classpath',self.encryptionJarPath,'org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI', 'encrypt.sh', 'input=%s'%input, 'password=%s'%self.mgmtsecretkey,'verbose=false'] + cmd = ['java','-classpath',self.encryptionJarPath,'org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI', 'encrypt.sh', 'input=\'%s\''%input, 'password=%s'%self.mgmtsecretkey,'verbose=false'] return runCmd(cmd).strip('\n') def saveMgmtServerSecretKey(): diff --git a/setup/db/create-database-simulator.sql b/setup/db/create-database-simulator.sql new file mode 100644 index 00000000000..8924eda3ff5 --- /dev/null +++ b/setup/db/create-database-simulator.sql @@ -0,0 +1,29 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you 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. + + +DROP DATABASE IF EXISTS `simulator`; + +CREATE DATABASE `simulator`; + +GRANT ALL ON simulator.* to cloud@`localhost` identified by 'cloud'; +GRANT ALL ON simulator.* to cloud@`%` identified by 'cloud'; + +GRANT process ON *.* TO cloud@`localhost`; +GRANT process ON *.* TO cloud@`%`; + +commit; diff --git a/setup/db/create-index-fk.sql b/setup/db/create-index-fk.sql index 82284d42e2e..62674c6c798 100755 --- a/setup/db/create-index-fk.sql +++ b/setup/db/create-index-fk.sql @@ -93,3 +93,5 @@ ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__account_id` ALTER TABLE `cloud`.`ssh_keypairs` ADD CONSTRAINT `fk_ssh_keypairs__domain_id` FOREIGN KEY `fk_ssh_keypair__domain_id` (`domain_id`) REFERENCES `domain` (`id`) ON DELETE CASCADE; ALTER TABLE `cloud`.`usage_event` ADD INDEX `i_usage_event__created`(`created`); + +ALTER TABLE `cloud`.`nicira_nvp_nic_map` ADD CONSTRAINT `fk_nicira_nvp_nic_map__nic` FOREIGN KEY `fk_nicira_nvp_nic_map__nic` (`nic`) REFERENCES `nics` (`uuid`) ON DELETE CASCADE; diff --git a/setup/db/create-schema-simulator.sql b/setup/db/create-schema-simulator.sql index b8168aaa3c9..1ab838b1e73 100644 --- a/setup/db/create-schema-simulator.sql +++ b/setup/db/create-schema-simulator.sql @@ -15,14 +15,14 @@ -- specific language governing permissions and limitations -- under the License. -DROP TABLE IF EXISTS `cloud`.`mockhost`; -DROP TABLE IF EXISTS `cloud`.`mocksecstorage`; -DROP TABLE IF EXISTS `cloud`.`mockstoragepool`; -DROP TABLE IF EXISTS `cloud`.`mockvm`; -DROP TABLE IF EXISTS `cloud`.`mockvolume`; -DROP TABLE IF EXISTS `cloud`.`mocksecurityrules`; +DROP TABLE IF EXISTS `simulator`.`mockhost`; +DROP TABLE IF EXISTS `simulator`.`mocksecstorage`; +DROP TABLE IF EXISTS `simulator`.`mockstoragepool`; +DROP TABLE IF EXISTS `simulator`.`mockvm`; +DROP TABLE IF EXISTS `simulator`.`mockvolume`; +DROP TABLE IF EXISTS `simulator`.`mocksecurityrules`; -CREATE TABLE `cloud`.`mockhost` ( +CREATE TABLE `simulator`.`mockhost` ( `id` bigint unsigned NOT NULL auto_increment, `name` varchar(255) NOT NULL, `private_ip_address` char(40), @@ -48,7 +48,7 @@ CREATE TABLE `cloud`.`mockhost` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`mocksecstorage` ( +CREATE TABLE `simulator`.`mocksecstorage` ( `id` bigint unsigned NOT NULL auto_increment, `url` varchar(255), `capacity` bigint unsigned, @@ -56,7 +56,7 @@ CREATE TABLE `cloud`.`mocksecstorage` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`mockstoragepool` ( +CREATE TABLE `simulator`.`mockstoragepool` ( `id` bigint unsigned NOT NULL auto_increment, `guid` varchar(255), `mount_point` varchar(255), @@ -67,7 +67,7 @@ CREATE TABLE `cloud`.`mockstoragepool` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`mockvm` ( +CREATE TABLE `simulator`.`mockvm` ( `id` bigint unsigned NOT NULL auto_increment, `name` varchar(255), `host_id` bigint unsigned, @@ -83,7 +83,7 @@ CREATE TABLE `cloud`.`mockvm` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`mockvolume` ( +CREATE TABLE `simulator`.`mockvolume` ( `id` bigint unsigned NOT NULL auto_increment, `name` varchar(255), `size` bigint unsigned, @@ -97,7 +97,7 @@ CREATE TABLE `cloud`.`mockvolume` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`mockconfiguration` ( +CREATE TABLE `simulator`.`mockconfiguration` ( `id` bigint unsigned NOT NULL auto_increment, `data_center_id` bigint unsigned, `pod_id` bigint unsigned, @@ -108,7 +108,7 @@ CREATE TABLE `cloud`.`mockconfiguration` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`mocksecurityrules` ( +CREATE TABLE `simulator`.`mocksecurityrules` ( `id` bigint unsigned NOT NULL auto_increment, `vmid` bigint unsigned, `signature` varchar(255), diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 5b6dc0447c7..acbbc414813 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -146,6 +146,7 @@ DROP TABLE IF EXISTS `cloud`.`s2s_vpn_gateway`; DROP TABLE IF EXISTS `cloud`.`s2s_vpn_connection`; DROP TABLE IF EXISTS `cloud`,`external_nicira_nvp_devices`; DROP TABLE IF EXISTS `cloud`,`nicira_nvp_nic_map`; +DROP TABLE IF EXISTS `cloud`,`nicira_nvp_router_map`; CREATE TABLE `cloud`.`version` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', @@ -1362,16 +1363,15 @@ CREATE TABLE `cloud`.`sync_queue` ( `id` bigint unsigned NOT NULL auto_increment, `sync_objtype` varchar(64) NOT NULL, `sync_objid` bigint unsigned NOT NULL, - `queue_proc_msid` bigint, `queue_proc_number` bigint COMMENT 'process number, increase 1 for each iteration', - `queue_proc_time` datetime COMMENT 'last time to process the queue', `created` datetime COMMENT 'date created', `last_updated` datetime COMMENT 'date created', + `queue_size` smallint DEFAULT 0 COMMENT 'number of items being processed by the queue', + `queue_size_limit` smallint DEFAULT 1 COMMENT 'max number of items the queue can process concurrently', PRIMARY KEY (`id`), UNIQUE `i_sync_queue__objtype__objid`(`sync_objtype`, `sync_objid`), INDEX `i_sync_queue__created`(`created`), - INDEX `i_sync_queue__last_updated`(`last_updated`), - INDEX `i_sync_queue__queue_proc_time`(`queue_proc_time`) + INDEX `i_sync_queue__last_updated`(`last_updated`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`stack_maid` ( @@ -1392,13 +1392,15 @@ CREATE TABLE `cloud`.`sync_queue_item` ( `content_id` bigint, `queue_proc_msid` bigint COMMENT 'owner msid when the queue item is being processed', `queue_proc_number` bigint COMMENT 'used to distinguish raw items and items being in process', + `queue_proc_time` datetime COMMENT 'when processing started for the item', `created` datetime COMMENT 'time created', PRIMARY KEY (`id`), CONSTRAINT `fk_sync_queue_item__queue_id` FOREIGN KEY `fk_sync_queue_item__queue_id` (`queue_id`) REFERENCES `sync_queue` (`id`) ON DELETE CASCADE, INDEX `i_sync_queue_item__queue_id`(`queue_id`), INDEX `i_sync_queue_item__created`(`created`), INDEX `i_sync_queue_item__queue_proc_number`(`queue_proc_number`), - INDEX `i_sync_queue_item__queue_proc_msid`(`queue_proc_msid`) + INDEX `i_sync_queue_item__queue_proc_msid`(`queue_proc_msid`), + INDEX `i_sync_queue__queue_proc_time`(`queue_proc_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`disk_offering` ( @@ -2370,5 +2372,12 @@ CREATE TABLE `cloud`.`nicira_nvp_nic_map` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -SET foreign_key_checks = 1; +CREATE TABLE `cloud`.`nicira_nvp_router_map` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `logicalrouter_uuid` varchar(255) NOT NULL UNIQUE COMMENT 'nicira uuid of logical router', + `network_id` bigint unsigned NOT NULL UNIQUE COMMENT 'cloudstack id of the network', + PRIMARY KEY (`id`), + CONSTRAINT `fk_nicira_nvp_router_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +SET foreign_key_checks = 1; diff --git a/setup/db/db/schema-2214to30.sql b/setup/db/db/schema-2214to30.sql index 0b3e45431a7..60eceea447d 100755 --- a/setup/db/db/schema-2214to30.sql +++ b/setup/db/db/schema-2214to30.sql @@ -722,6 +722,19 @@ UPDATE `cloud`.`network_offerings` SET display_text='Offering for Shared Securit UPDATE `cloud`.`configuration` SET category = 'Secure' where name in ('alert.smtp.password', 'network.loadbalancer.haproxy.stats.auth', 'security.singlesignon.key', 'project.smtp.password'); +UPDATE `cloud`.`guest_os` set id = 158 where id = 141; +UPDATE `cloud`.`guest_os` set id = 159 where id = 142; +UPDATE `cloud`.`guest_os` set id = 160 where id = 143; +UPDATE `cloud`.`vm_template` set guest_os_id = 158 where guest_os_id = 141; +UPDATE `cloud`.`vm_template` set guest_os_id = 159 where guest_os_id = 142; +UPDATE `cloud`.`vm_template` set guest_os_id = 160 where guest_os_id = 143; +UPDATE `cloud`.`vm_instance` set guest_os_id = 158 where guest_os_id = 141; +UPDATE `cloud`.`vm_instance` set guest_os_id = 159 where guest_os_id = 142; +UPDATE `cloud`.`vm_instance` set guest_os_id = 160 where guest_os_id = 143; +UPDATE `cloud`.`guest_os_hypervisor` set guest_os_id = 158 where guest_os_id = 141; +UPDATE `cloud`.`guest_os_hypervisor` set guest_os_id = 159 where guest_os_id = 142; +UPDATE `cloud`.`guest_os_hypervisor` set guest_os_id = 160 where guest_os_id = 143; + INSERT IGNORE INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (143, 1, 'CentOS 6.0 (32-bit)'); @@ -748,3 +761,6 @@ UPDATE `cloud`.`networks` n SET n.display_text=(CONCAT('guestNetworkForBasicZon UPDATE `cloud`.`configuration` SET description='Bypass internal dns, use exetrnal dns1 and dns2' WHERE name='use.external.dns'; UPDATE `cloud`.`configuration` SET category='Alert' WHERE name='capacity.check.period'; UPDATE `cloud`.`vm_instance` SET vnc_password = '' where removed is not null; +DELETE FROM `cloud`.`host_details` where name in ('storage.network.device1', 'storage.network.device2'); +UPDATE `cloud`.`configuration` SET category = 'Hidden' where name in ('secondary.storage.vm', 'xen.create.pools.in.pod', 'cloud.identifier', 'security.hash.key', 'router.ram.size'); +DELETE FROM `cloud`.`host_details` where name in ('storage.network.device1', 'storage.network.device2'); diff --git a/setup/db/db/schema-301to302.sql b/setup/db/db/schema-301to302.sql index 595ce1974b5..f33fcb436d8 100755 --- a/setup/db/db/schema-301to302.sql +++ b/setup/db/db/schema-301to302.sql @@ -60,3 +60,5 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.reserve.mem', 'false', 'Specify whether or not to reserve memory based on memory overprovisioning factor'); UPDATE `cloud`.`storage_pool` SET removed=now() WHERE path='lvm' AND id NOT IN (select pool_id from storage_pool_host_ref); + +UPDATE `cloud`.`user` SET PASSWORD=RAND() WHERE id=1; diff --git a/setup/db/db/schema-302to40.sql b/setup/db/db/schema-302to40.sql index 091615624a2..0c4efa33025 100644 --- a/setup/db/db/schema-302to40.sql +++ b/setup/db/db/schema-302to40.sql @@ -474,4 +474,6 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'manage INSERT IGNORE INTO `cloud`.`guest_os_category` VALUES ('11','None',NULL); ALTER TABLE `cloud`.`user` ADD COLUMN `incorrect_login_attempts` integer unsigned NOT NULL DEFAULT '0'; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'incorrect.login.attempts.allowed', '5', 'Incorrect login attempts allowed before the user is disabled'); +UPDATE `cloud`.`configuration` set description ='Uuid of the service offering used by console proxy; if NULL - system offering will be used' where name ='consoleproxy.service.offering'; +UPDATE `cloud`.`user` SET PASSWORD=RAND() WHERE id=1; diff --git a/setup/db/db/schema-30to301.sql b/setup/db/db/schema-30to301.sql index 615d7930481..0cc51e7d08f 100755 --- a/setup/db/db/schema-30to301.sql +++ b/setup/db/db/schema-30to301.sql @@ -33,3 +33,5 @@ ALTER TABLE `cloud_usage`.`account` ADD CONSTRAINT `uc_account__uuid` UNIQUE (`u ALTER TABLE `cloud`.`host` ALTER COLUMN `resource_state` SET DEFAULT 'Enabled'; ALTER TABLE `cloud`.`physical_network_service_providers` ADD COLUMN `removed` datetime COMMENT 'date removed if not null'; + +UPDATE `cloud`.`user` SET PASSWORD=RAND() WHERE id=1; diff --git a/setup/db/deploy-db-simulator.sh b/setup/db/deploy-db-simulator.sh index fe21c819e13..4f8c14ebfe5 100644 --- a/setup/db/deploy-db-simulator.sh +++ b/setup/db/deploy-db-simulator.sh @@ -87,6 +87,10 @@ echo "Recreating Database cloud_usage." mysql --user=root --password=$3 < create-database-premium.sql > /dev/null 2>/dev/null handle_error create-database-premium.sql +echo "Recreating Database simulator." +mysql --user=root --password=$3 < create-database-simulator.sql > /dev/null 2>/dev/null +handle_error create-database-simulator.sql + mysql --user=cloud --password=cloud cloud < create-schema.sql if [ $? -ne 0 ]; then printf "Error: Cannot execute create-schema.sql\n" diff --git a/test/conf/README b/test/conf/README deleted file mode 100644 index 6836c0f8b7f..00000000000 --- a/test/conf/README +++ /dev/null @@ -1,8 +0,0 @@ -To run submitCertEC2 and deleteCertEC2 scripts, update parameters in conf/tool.properties file: - -* host - ip address of the host where cloud-bridge software is installed -* port - port cloud-bridge software is listening to -* accesspoint - access point for cloud-bridge REST request -* version - Amazon EC2 api version supported by cloud-bridge -* signaturemethod - HmacSHA1 or HmacSHA256 -* expires - the date when certificate expires \ No newline at end of file diff --git a/test/integration/README b/test/integration/README deleted file mode 100644 index e137a070030..00000000000 --- a/test/integration/README +++ /dev/null @@ -1,8 +0,0 @@ -To run the tests - you should have marvin installed and correctly importable. -The tests are long running and are best monitored by external hudson jobs. - -Also you will have to point marvin to the right configuration file that has -details about your cloudstack deployment. For more help on how to write the -config file and run tests check the tutorial at : - -https://cwiki.apache.org/confluence/display/CLOUDSTACK/Testing+with+Python diff --git a/test/integration/component/README b/test/integration/component/README deleted file mode 100644 index 2fd8d4be795..00000000000 --- a/test/integration/component/README +++ /dev/null @@ -1,41 +0,0 @@ -P1 Cases --------------------------------------- -These test cases are the core functionality tests that ensure the application is stable and can be tested thoroughly. -These P1 cases definitions are located at : https://docs.google.com/a/clogeny.com/spreadsheet/ccc?key=0Aq5M2ldK6eyedDJBa0EzM0RPNmdVNVZOWnFnOVJJcHc&hl=en_US - - -Guidelines ----------- -P1 test cases are being developed using Python's unittests2. Following are certain guidelines being followed - 1. Tests exercised for the same resource should ideally be present under a single suite or file. - - 2. Time-consuming operations that create new cloud resources like server creation, volume creation etc - should not necessarily be exercised per unit test. The resources can be shared by creating them at - the class-level using setUpClass and shared across all instances during a single run. - - 3. Certain tests pertaining to NAT, Firewall and Load Balancing warrant fresh resources per test. Hence a call should be - taken by the stakeholders regarding sharing resources. - - 4. Ensure that the tearDown/tearDownClass functions clean up all the resources created during the test run. - -For more information about unittests: http://docs.python.org/library/unittest.html - - -P1 Tests ----------- -The following files contain these P1 cases: - -1. test_snapshots.py - Snapshots related tests -2. test_routers.py - Router related tests -3. test_usage.py - Usage realted tests -4. test_account.py - Account related tests -5. test_resource_limits.py - Resource limits tests -6. test_security_groups.py - Security groups related tests -7. test_templates.py - templates related tests -8. test_volumes.py - Volumes related tests -9. test_blocker_bugs.py - Blocker bugs tests -10. test_project_configs.py - Project global configuration related tests -11. test_project_limits.py - Project resource limits related tests -12. test_project_resources.py - Project resource creation related tests -13. test_project_usage.py - Project usage related tests -14. test_projects - Projects functionality tests diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index 641f6fd139c..d0b4434bb4e 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -19,9 +19,9 @@ #Import Local Modules from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin import remoteSSHClient import datetime diff --git a/test/integration/component/test_allocation_states.py b/test/integration/component/test_allocation_states.py index 5d702b9f9c6..006f8795fbf 100644 --- a/test/integration/component/test_allocation_states.py +++ b/test/integration/component/test_allocation_states.py @@ -1,23 +1,27 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * import datetime diff --git a/test/integration/component/test_blocker_bugs.py b/test/integration/component/test_blocker_bugs.py index 2285afa8e89..cc5da0ace4a 100644 --- a/test/integration/component/test_blocker_bugs.py +++ b/test/integration/component/test_blocker_bugs.py @@ -18,9 +18,9 @@ """ import marvin from nose.plugins.attrib import attr -from integration.lib.base import * -from integration.lib.utils import * -from integration.lib.common import * +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * #Import Local Modules from marvin.cloudstackTestCase import * @@ -407,7 +407,6 @@ class TestTemplate(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/component/test_egress_rules.py b/test/integration/component/test_egress_rules.py index 982f036bdf7..73a91f41bfe 100644 --- a/test/integration/component/test_egress_rules.py +++ b/test/integration/component/test_egress_rules.py @@ -23,9 +23,9 @@ from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.remoteSSHClient import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * #Import System modules import time @@ -138,7 +138,6 @@ class TestDefaultSecurityGroupEgress(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -297,7 +296,6 @@ class TestAuthorizeIngressRule(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -455,7 +453,6 @@ class TestDefaultGroupEgress(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -656,7 +653,6 @@ class TestDefaultGroupEgressAfterDeploy(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -839,7 +835,6 @@ class TestRevokeEgressRule(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -1101,7 +1096,6 @@ class TestInvalidAccountAuthroize(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -1223,7 +1217,6 @@ class TestMultipleAccountsEgressRuleNeg(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -1471,7 +1464,6 @@ class TestMultipleAccountsEgressRule(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -1768,7 +1760,6 @@ class TestStartStopVMWithEgressRule(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -1980,7 +1971,6 @@ class TestInvalidParametersForEgress(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -2163,7 +2153,6 @@ class TestEgressAfterHostMaintainance(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/component/test_eip_elb.py b/test/integration/component/test_eip_elb.py index 7c28c3d2343..4c8dcbe2c07 100644 --- a/test/integration/component/test_eip_elb.py +++ b/test/integration/component/test_eip_elb.py @@ -22,9 +22,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import datetime @@ -176,7 +176,6 @@ class TestEIP(cloudstackTestCase): try: #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - self.dbclient.close() except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -999,7 +998,6 @@ class TestELB(cloudstackTestCase): try: #Clean up, terminate the created network offerings cleanup_resources(self.apiclient, self.cleanup) - self.dbclient.close() except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return diff --git a/test/integration/component/test_network_offering.py b/test/integration/component/test_network_offering.py index 35cc01129ce..c1a518b458a 100644 --- a/test/integration/component/test_network_offering.py +++ b/test/integration/component/test_network_offering.py @@ -22,9 +22,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import datetime diff --git a/test/integration/component/test_project_configs.py b/test/integration/component/test_project_configs.py index c82bf134871..d5ce9d6024d 100644 --- a/test/integration/component/test_project_configs.py +++ b/test/integration/component/test_project_configs.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import datetime diff --git a/test/integration/component/test_project_limits.py b/test/integration/component/test_project_limits.py index c1ef86aade8..8f7c1281b23 100644 --- a/test/integration/component/test_project_limits.py +++ b/test/integration/component/test_project_limits.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * import datetime diff --git a/test/integration/component/test_project_resources.py b/test/integration/component/test_project_resources.py index a32ca74c2e5..27452be811f 100644 --- a/test/integration/component/test_project_resources.py +++ b/test/integration/component/test_project_resources.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import datetime @@ -1172,7 +1172,6 @@ class TestSecurityGroup(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/component/test_project_usage.py b/test/integration/component/test_project_usage.py index c171e3c7f8b..4561576543c 100644 --- a/test/integration/component/test_project_usage.py +++ b/test/integration/component/test_project_usage.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import datetime diff --git a/test/integration/component/test_projects.py b/test/integration/component/test_projects.py index 26d4a6f91c4..811d092d18e 100644 --- a/test/integration/component/test_projects.py +++ b/test/integration/component/test_projects.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import datetime diff --git a/test/integration/component/test_resource_limits.py b/test/integration/component/test_resource_limits.py index f182ed17bd0..cd007f1595e 100644 --- a/test/integration/component/test_resource_limits.py +++ b/test/integration/component/test_resource_limits.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * import datetime diff --git a/test/integration/component/test_routers.py b/test/integration/component/test_routers.py index dde8aa4b8b6..a65c5c34005 100644 --- a/test/integration/component/test_routers.py +++ b/test/integration/component/test_routers.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient #Import System modules diff --git a/test/integration/component/test_security_groups.py b/test/integration/component/test_security_groups.py index 1cad467416a..13a87b67c83 100644 --- a/test/integration/component/test_security_groups.py +++ b/test/integration/component/test_security_groups.py @@ -22,9 +22,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient #Import System modules @@ -110,7 +110,6 @@ class TestDefaultSecurityGroup(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -383,7 +382,6 @@ class TestAuthorizeIngressRule(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -519,7 +517,6 @@ class TestRevokeIngressRule(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -678,7 +675,6 @@ class TestDhcpOnlyRouter(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -815,7 +811,6 @@ class TestdeployVMWithUserData(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -1019,7 +1014,6 @@ class TestDeleteSecurityGroup(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -1265,7 +1259,6 @@ class TestIngressRule(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/component/test_snapshots.py b/test/integration/component/test_snapshots.py index b368b853c72..27c960f1b16 100644 --- a/test/integration/component/test_snapshots.py +++ b/test/integration/component/test_snapshots.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient @@ -54,6 +54,30 @@ class Services: "name": "Small Disk", "disksize": 1 }, + "server_with_disk": + { + "displayname": "Test VM -With Disk", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + + "server_without_disk": + { + "displayname": "Test VM-No Disk", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + # For NAT rule creation + "publicport": 22, + "protocol": 'TCP', + }, "server": { "displayname": "TestVM", "username": "root", @@ -102,6 +126,1062 @@ class Services: } +class TestSnapshotRootDisk(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestSnapshotRootDisk, cls).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + cls.services["domainid"] = cls.domain.id + cls.services["server_without_disk"]["zoneid"] = cls.zone.id + cls.services["template"] = template.id + cls.services["zoneid"] = cls.zone.id + + # Create VMs, NAT Rules etc + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + + cls.services["account"] = cls.account.account.name + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.virtual_machine = cls.virtual_machine_with_disk = \ + VirtualMachine.create( + cls.api_client, + cls.services["server_without_disk"], + templateid=template.id, + accountid=cls.account.account.name, + domainid=cls.account.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.services["mode"] + ) + cls._cleanup = [ + cls.service_offering, + cls.account, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + return + + def tearDown(self): + try: + #Clean up, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(speed = "slow") + @attr(tags = ["advanced", "advancedns", "smoke"]) + def test_01_snapshot_root_disk(self): + """Test Snapshot Root Disk + """ + + # Validate the following + # 1. listSnapshots should list the snapshot that was created. + # 2. verify that secondary storage NFS share contains + # the reqd volume under + # /secondary/snapshots//$account_id/$volumeid/$snapshot_uuid + # 3. verify backup_snap_id was non null in the `snapshots` table + + volumes = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine_with_disk.id, + type='ROOT', + listall=True + ) + + snapshot = Snapshot.create( + self.apiclient, + volumes[0].id, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + self.debug("Snapshot created: ID - %s" % snapshot.id) + + snapshots = list_snapshots( + self.apiclient, + id=snapshot.id + ) + self.assertEqual( + isinstance(snapshots, list), + True, + "Check list response returns a valid list" + ) + + self.assertNotEqual( + snapshots, + None, + "Check if result exists in list item call" + ) + self.assertEqual( + snapshots[0].id, + snapshot.id, + "Check resource id in list resources call" + ) + self.debug( + "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ + % str(snapshot.id) + ) + qresultset = self.dbclient.execute( + "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ + % str(snapshot.id) + ) + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set" + ) + + qresult = qresultset[0] + + snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID + account_id = qresult[1] + volume_id = qresult[2] + + self.assertNotEqual( + str(snapshot_uuid), + 'NULL', + "Check if backup_snap_id is not null" + ) + + # Get the Secondary Storage details from list Hosts + hosts = list_hosts( + self.apiclient, + type='SecondaryStorage', + zoneid=self.zone.id + ) + self.assertEqual( + isinstance(hosts, list), + True, + "Check list response returns a valid list" + ) + uuids = [] + for host in hosts: + # hosts[0].name = "nfs://192.168.100.21/export/test" + parse_url = (host.name).split('/') + # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] + + # Split IP address and export path from name + sec_storage_ip = parse_url[2] + # Sec Storage IP: 192.168.100.21 + + export_path = '/'.join(parse_url[3:]) + # Export path: export/test + + try: + # Login to VM to check snapshot present on sec disk + ssh_client = self.virtual_machine_with_disk.get_ssh_client() + + cmds = [ + "mkdir -p %s" % self.services["mount_dir"], + "mount %s/%s %s" % ( + sec_storage_ip, + export_path, + self.services["mount_dir"] + ), + "ls %s/snapshots/%s/%s" % ( + self.services["mount_dir"], + account_id, + volume_id + ), + ] + + for c in cmds: + self.debug(c) + result = ssh_client.execute(c) + self.debug(result) + + except Exception: + self.fail("SSH failed for Virtual machine: %s" % + self.virtual_machine_with_disk.ipaddress) + + uuids.append(result) + # Unmount the Sec Storage + cmds = [ + "umount %s" % (self.services["mount_dir"]), + ] + try: + for c in cmds: + self.debug(c) + result = ssh_client.execute(c) + self.debug(result) + + except Exception as e: + self.fail("SSH failed for Virtual machine: %s" % + self.virtual_machine_with_disk.ipaddress) + + res = str(uuids) + # Check snapshot UUID in secondary storage and database + self.assertEqual( + res.count(snapshot_uuid), + 1, + "Check snapshot UUID in secondary storage and database" + ) + return + + +class TestSnapshots(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestSnapshots, cls).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + cls.services["domainid"] = cls.domain.id + cls.services["server_with_disk"]["zoneid"] = cls.zone.id + cls.services["server_with_disk"]["diskoffering"] = cls.disk_offering.id + + cls.services["server_without_disk"]["zoneid"] = cls.zone.id + + cls.services["template"] = template.id + cls.services["zoneid"] = cls.zone.id + cls.services["diskoffering"] = cls.disk_offering.id + + # Create VMs, NAT Rules etc + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + + cls.services["account"] = cls.account.account.name + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.virtual_machine = cls.virtual_machine_with_disk = \ + VirtualMachine.create( + cls.api_client, + cls.services["server_with_disk"], + templateid=template.id, + accountid=cls.account.account.name, + domainid=cls.account.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.services["mode"] + ) + cls.virtual_machine_without_disk = \ + VirtualMachine.create( + cls.api_client, + cls.services["server_without_disk"], + templateid=template.id, + accountid=cls.account.account.name, + domainid=cls.account.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.services["mode"] + ) + cls._cleanup = [ + cls.service_offering, + cls.disk_offering, + cls.account, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + return + + def tearDown(self): + try: + #Clean up, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(speed = "slow") + @attr(tags = ["advanced", "advancedns", "smoke"]) + def test_02_snapshot_data_disk(self): + """Test Snapshot Data Disk + """ + + volume = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine_with_disk.id, + type='DATADISK', + listall=True + ) + self.assertEqual( + isinstance(volume, list), + True, + "Check list response returns a valid list" + ) + + self.debug("Creating a Snapshot from data volume: %s" % volume[0].id) + snapshot = Snapshot.create( + self.apiclient, + volume[0].id, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + snapshots = list_snapshots( + self.apiclient, + id=snapshot.id + ) + self.assertEqual( + isinstance(snapshots, list), + True, + "Check list response returns a valid list" + ) + self.assertNotEqual( + snapshots, + None, + "Check if result exists in list item call" + ) + self.assertEqual( + snapshots[0].id, + snapshot.id, + "Check resource id in list resources call" + ) + self.debug( + "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ + % str(snapshot.id) + ) + qresultset = self.dbclient.execute( + "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ + % str(snapshot.id) + ) + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set" + ) + + qresult = qresultset[0] + snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID + account_id = qresult[1] + volume_id = qresult[2] + + self.assertNotEqual( + str(snapshot_uuid), + 'NULL', + "Check if backup_snap_id is not null" + ) + + # Get the Secondary Storage details from list Hosts + hosts = list_hosts( + self.apiclient, + type='SecondaryStorage', + zoneid=self.zone.id + ) + self.assertEqual( + isinstance(hosts, list), + True, + "Check list response returns a valid list" + ) + uuids = [] + for host in hosts: + # hosts[0].name = "nfs://192.168.100.21/export" + parse_url = (host.name).split('/') + # parse_url = ['nfs:', '', '192.168.100.21', 'export'] + + # Split IP address and export path from name + sec_storage_ip = parse_url[2] + # Sec Storage IP: 192.168.100.21 + + export_path = '/'.join(parse_url[3:]) + # Export path: export + + try: + # Login to VM to check snapshot present on sec disk + ssh_client = self.virtual_machine_with_disk.get_ssh_client() + + cmds = [ + "mkdir -p %s" % self.services["mount_dir"], + "mount %s/%s %s" % ( + sec_storage_ip, + export_path, + self.services["mount_dir"] + ), + "ls %s/snapshots/%s/%s" % ( + self.services["mount_dir"], + account_id, + volume_id + ), + ] + for c in cmds: + self.debug(c) + result = ssh_client.execute(c) + self.debug(result) + + except Exception as e: + self.fail("SSH failed for VM with IP: %s" % + self.virtual_machine_with_disk.ipaddress) + + uuids.append(result) + # Unmount the Sec Storage + cmds = [ + "umount %s" % (self.services["mount_dir"]), + ] + try: + for c in cmds: + self.debug(c) + ssh_client.execute(c) + + except Exception as e: + self.fail("SSH failed for VM with IP: %s" % + self.virtual_machine_with_disk.ipaddress) + + res = str(uuids) + # Check snapshot UUID in secondary storage and database + self.assertEqual( + res.count(snapshot_uuid), + 1, + "Check snapshot UUID in secondary storage and database" + ) + return + + @attr(speed = "slow") + @attr(tags = ["advanced", "advancedns", "smoke"]) + def test_03_volume_from_snapshot(self): + """Create volumes from snapshots + """ + #1. Login to machine; create temp/test directories on data volume + #2. Snapshot the Volume + #3. Create another Volume from snapshot + #4. Mount/Attach volume to another server + #5. Compare data + random_data_0 = random_gen(100) + random_data_1 = random_gen(100) + + try: + ssh_client = self.virtual_machine.get_ssh_client() + + #Format partition using ext3 + format_volume_to_ext3( + ssh_client, + self.services["diskdevice"] + ) + cmds = [ + "mkdir -p %s" % self.services["mount_dir"], + "mount %s1 %s" % ( + self.services["diskdevice"], + self.services["mount_dir"] + ), + "mkdir -p %s/%s/{%s,%s} " % ( + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir1"], + self.services["sub_lvl_dir2"] + ), + "echo %s > %s/%s/%s/%s" % ( + random_data_0, + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir1"], + self.services["random_data"] + ), + "echo %s > %s/%s/%s/%s" % ( + random_data_1, + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir2"], + self.services["random_data"] + ), + ] + for c in cmds: + self.debug(c) + ssh_client.execute(c) + + except Exception as e: + self.fail("SSH failed for VM with IP: %s" % + self.virtual_machine.ipaddress) + # Unmount the Sec Storage + cmds = [ + "umount %s" % (self.services["mount_dir"]), + ] + + try: + for c in cmds: + self.debug(c) + ssh_client.execute(c) + + except Exception as e: + self.fail("SSH failed for VM with IP: %s" % + self.virtual_machine.ipaddress) + + list_volume_response = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='DATADISK', + listall=True + ) + + volume_response = list_volume_response[0] + #Create snapshot from attached volume + snapshot = Snapshot.create( + self.apiclient, + volume_response.id, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + self.debug("Created Snapshot from volume: %s" % volume_response.id) + + #Create volume from snapshot + self.debug("Creating volume from snapshot: %s" % snapshot.id) + volume = Volume.create_from_snapshot( + self.apiclient, + snapshot.id, + self.services, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + + volumes = list_volumes( + self.apiclient, + id=volume.id + ) + self.assertEqual( + isinstance(volumes, list), + True, + "Check list response returns a valid list" + ) + self.assertNotEqual( + len(volumes), + None, + "Check Volume list Length" + ) + + self.assertEqual( + volumes[0].id, + volume.id, + "Check Volume in the List Volumes" + ) + #Attaching volume to new VM + new_virtual_machine = self.virtual_machine_without_disk + self.cleanup.append(new_virtual_machine) + + cmd = attachVolume.attachVolumeCmd() + cmd.id = volume.id + cmd.virtualmachineid = new_virtual_machine.id + self.apiclient.attachVolume(cmd) + + try: + #Login to VM to verify test directories and files + ssh = new_virtual_machine.get_ssh_client() + + cmds = [ + "mkdir -p %s" % self.services["mount_dir"], + "mount %s1 %s" % ( + self.services["diskdevice"], + self.services["mount_dir"] + ), + ] + + for c in cmds: + self.debug(c) + result = ssh.execute(c) + self.debug(result) + + returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir1"], + self.services["random_data"] + )) + returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir2"], + self.services["random_data"] + )) + + except Exception as e: + self.fail("SSH failed for VM with IP: %s" % + self.new_virtual_machine.ipaddress) + + #Verify returned data + self.assertEqual( + random_data_0, + returned_data_0[0], + "Verify newly attached volume contents with existing one" + ) + self.assertEqual( + random_data_1, + returned_data_1[0], + "Verify newly attached volume contents with existing one" + ) + # Unmount the Sec Storage + cmds = [ + "umount %s" % (self.services["mount_dir"]), + ] + try: + for c in cmds: + ssh_client.execute(c) + + except Exception as e: + self.fail("SSH failed for VM with IP: %s" % + self.new_virtual_machine.ipaddress) + return + + @attr(speed = "slow") + @attr(tags = ["advanced", "advancedns", "smoke"]) + def test_04_delete_snapshot(self): + """Test Delete Snapshot + """ + + #1. Snapshot the Volume + #2. Delete the snapshot + #3. Verify snapshot is removed by calling List Snapshots API + + volumes = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='DATADISK', + listall=True + ) + self.assertEqual( + isinstance(volumes, list), + True, + "Check list response returns a valid list" + ) + snapshot = Snapshot.create( + self.apiclient, + volumes[0].id, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + snapshot.delete(self.apiclient) + + snapshots = list_snapshots( + self.apiclient, + id=snapshot.id + ) + + self.assertEqual( + snapshots, + None, + "Check if result exists in list item call" + ) + return + + @attr(speed = "slow") + @attr(tags = ["advanced", "advancedns", "smoke"]) + def test_05_recurring_snapshot_root_disk(self): + """Test Recurring Snapshot Root Disk + """ + #1. Create snapshot policy for root disk + #2. ListSnapshot policy should return newly created policy + #3. Verify only most recent number (maxsnaps) snapshots retailed + + volume = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine_with_disk.id, + type='ROOT', + listall=True + ) + self.assertEqual( + isinstance(volume, list), + True, + "Check list response returns a valid list" + ) + recurring_snapshot = SnapshotPolicy.create( + self.apiclient, + volume[0].id, + self.services["recurring_snapshot"] + ) + self.cleanup.append(recurring_snapshot) + + #ListSnapshotPolicy should return newly created policy + list_snapshots_policy = list_snapshot_policy( + self.apiclient, + id=recurring_snapshot.id, + volumeid=volume[0].id + ) + self.assertEqual( + isinstance(list_snapshots_policy, list), + True, + "Check list response returns a valid list" + ) + self.assertNotEqual( + list_snapshots_policy, + None, + "Check if result exists in list item call" + ) + snapshots_policy = list_snapshots_policy[0] + self.assertEqual( + snapshots_policy.id, + recurring_snapshot.id, + "Check recurring snapshot id in list resources call" + ) + self.assertEqual( + snapshots_policy.maxsnaps, + self.services["recurring_snapshot"]["maxsnaps"], + "Check interval type in list resources call" + ) + # Sleep for (maxsnaps+1) hours to verify + # only maxsnaps snapshots are retained + time.sleep( + (self.services["recurring_snapshot"]["maxsnaps"]) * 3600 + ) + + timeout = self.services["timeout"] + while True: + snapshots = list_snapshots( + self.apiclient, + volumeid=volume[0].id, + intervaltype=\ + self.services["recurring_snapshot"]["intervaltype"], + snapshottype='RECURRING', + listall=True + ) + + if isinstance(snapshots, list): + break + + elif timeout == 0: + raise Exception("List snapshots API call failed.") + + time.sleep(1) + timeout = timeout - 1 + + self.assertEqual( + isinstance(snapshots, list), + True, + "Check list response returns a valid list" + ) + + self.assertEqual( + len(snapshots), + self.services["recurring_snapshot"]["maxsnaps"], + "Check maximum number of recurring snapshots retained" + ) + return + + @attr(speed = "slow") + @attr(tags = ["advanced", "advancedns", "smoke"]) + def test_06_recurring_snapshot_data_disk(self): + """Test Recurring Snapshot data Disk + """ + #1. Create snapshot policy for data disk + #2. ListSnapshot policy should return newly created policy + #3. Verify only most recent number (maxsnaps) snapshots retailed + + volume = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine_with_disk.id, + type='DATADISK', + listall=True + ) + + self.assertEqual( + isinstance(volume, list), + True, + "Check list response returns a valid list" + ) + + recurring_snapshot = SnapshotPolicy.create( + self.apiclient, + volume[0].id, + self.services["recurring_snapshot"] + ) + self.cleanup.append(recurring_snapshot) + #ListSnapshotPolicy should return newly created policy + list_snapshots_policy = list_snapshot_policy( + self.apiclient, + id=recurring_snapshot.id, + volumeid=volume[0].id + ) + + self.assertEqual( + isinstance(list_snapshots_policy, list), + True, + "Check list response returns a valid list" + ) + + self.assertNotEqual( + list_snapshots_policy, + None, + "Check if result exists in list item call" + ) + snapshots_policy = list_snapshots_policy[0] + self.assertEqual( + snapshots_policy.id, + recurring_snapshot.id, + "Check recurring snapshot id in list resources call" + ) + self.assertEqual( + snapshots_policy.maxsnaps, + self.services["recurring_snapshot"]["maxsnaps"], + "Check interval type in list resources call" + ) + + # Sleep for (maxsnaps) hours to verify only maxsnaps snapshots are + # retained + time.sleep( + (self.services["recurring_snapshot"]["maxsnaps"]) * 3600 + ) + + timeout = self.services["timeout"] + while True: + snapshots = list_snapshots( + self.apiclient, + volumeid=volume[0].id, + intervaltype=\ + self.services["recurring_snapshot"]["intervaltype"], + snapshottype='RECURRING', + listall=True + ) + + if isinstance(snapshots, list): + break + + elif timeout == 0: + raise Exception("List snapshots API call failed.") + + time.sleep(1) + timeout = timeout - 1 + + self.assertEqual( + isinstance(snapshots, list), + True, + "Check list response returns a valid list" + ) + self.assertEqual( + len(snapshots), + self.services["recurring_snapshot"]["maxsnaps"], + "Check maximum number of recurring snapshots retained" + ) + return + + @attr(speed = "slow") + @attr(tags = ["advanced", "advancedns", "smoke"]) + def test_07_template_from_snapshot(self): + """Create Template from snapshot + """ + + #1. Login to machine; create temp/test directories on data volume + #2. Snapshot the Volume + #3. Create Template from snapshot + #4. Deploy Virtual machine using this template + #5. Login to newly created virtual machine + #6. Compare data + + random_data_0 = random_gen(100) + random_data_1 = random_gen(100) + + try: + #Login to virtual machine + ssh_client = self.virtual_machine.get_ssh_client() + + cmds = [ + "mkdir -p %s" % self.services["mount_dir"], + "mount %s1 %s" % ( + self.services["rootdisk"], + self.services["mount_dir"] + ), + "mkdir -p %s/%s/{%s,%s} " % ( + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir1"], + self.services["sub_lvl_dir2"] + ), + "echo %s > %s/%s/%s/%s" % ( + random_data_0, + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir1"], + self.services["random_data"] + ), + "echo %s > %s/%s/%s/%s" % ( + random_data_1, + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir2"], + self.services["random_data"] + ), + "sync", + ] + + for c in cmds: + self.debug(c) + result = ssh_client.execute(c) + self.debug(result) + + except Exception as e: + self.fail("SSH failed for VM with IP address: %s" % + self.virtual_machine.ipaddress) + + # Unmount the Volume + cmds = [ + "umount %s" % (self.services["mount_dir"]), + ] + for c in cmds: + self.debug(c) + ssh_client.execute(c) + + volumes = list_volumes( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='ROOT', + listall=True + ) + self.assertEqual( + isinstance(volumes, list), + True, + "Check list response returns a valid list" + ) + + volume = volumes[0] + + #Create a snapshot of volume + snapshot = Snapshot.create( + self.apiclient, + volume.id, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + + self.debug("Snapshot created from volume ID: %s" % volume.id) + # Generate template from the snapshot + template = Template.create_from_snapshot( + self.apiclient, + snapshot, + self.services["templates"] + ) + self.cleanup.append(template) + self.debug("Template created from snapshot ID: %s" % snapshot.id) + + # Verify created template + templates = list_templates( + self.apiclient, + templatefilter=\ + self.services["templates"]["templatefilter"], + id=template.id + ) + self.assertNotEqual( + templates, + None, + "Check if result exists in list item call" + ) + + self.assertEqual( + templates[0].id, + template.id, + "Check new template id in list resources call" + ) + self.debug("Deploying new VM from template: %s" % template.id) + + # Deploy new virtual machine using template + new_virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["server_without_disk"], + templateid=template.id, + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.services["mode"] + ) + self.cleanup.append(new_virtual_machine) + + try: + #Login to VM & mount directory + ssh = new_virtual_machine.get_ssh_client() + + cmds = [ + "mkdir -p %s" % self.services["mount_dir"], + "mount %s1 %s" % ( + self.services["rootdisk"], + self.services["mount_dir"] + ) + ] + + for c in cmds: + ssh.execute(c) + + returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir1"], + self.services["random_data"] + )) + self.debug(returned_data_0) + returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( + self.services["mount_dir"], + self.services["sub_dir"], + self.services["sub_lvl_dir2"], + self.services["random_data"] + )) + self.debug(returned_data_1) + except Exception as e: + self.fail("SSH failed for VM with IP address: %s" % + new_virtual_machine.ipaddress) + #Verify returned data + self.assertEqual( + random_data_0, + returned_data_0[0], + "Verify newly attached volume contents with existing one" + ) + self.assertEqual( + random_data_1, + returned_data_1[0], + "Verify newly attached volume contents with existing one" + ) + # Unmount the volume + cmds = [ + "umount %s" % (self.services["mount_dir"]), + ] + try: + for c in cmds: + self.debug(c) + ssh_client.execute(c) + + except Exception as e: + self.fail("SSH failed for VM with IP address: %s" % + new_virtual_machine.ipaddress) + return + class TestCreateVMsnapshotTemplate(cloudstackTestCase): @classmethod diff --git a/test/integration/component/test_templates.py b/test/integration/component/test_templates.py index 0aa60616fef..e6b2dd6c476 100644 --- a/test/integration/component/test_templates.py +++ b/test/integration/component/test_templates.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import urllib from random import random @@ -113,7 +113,6 @@ class TestCreateTemplate(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/component/test_usage.py b/test/integration/component/test_usage.py index e5684f8694b..34dbc3780d0 100644 --- a/test/integration/component/test_usage.py +++ b/test/integration/component/test_usage.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient import datetime diff --git a/test/integration/component/test_volumes.py b/test/integration/component/test_volumes.py index 3bad5f10254..5819001e1b9 100644 --- a/test/integration/component/test_volumes.py +++ b/test/integration/component/test_volumes.py @@ -21,9 +21,9 @@ import marvin from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient #Import System modules import os diff --git a/test/integration/smoke/README b/test/integration/smoke/README deleted file mode 100644 index b4c5d82ac19..00000000000 --- a/test/integration/smoke/README +++ /dev/null @@ -1,41 +0,0 @@ -Build Verification Testing (BVT) Cases --------------------------------------- -These test cases are the core functionality tests that ensure the application is stable and can be tested thoroughly. -These BVT cases definitions are located at : https://docs.google.com/a/cloud.com/spreadsheet/ccc?key=0Ak8acbfxQG8ndEppOGZSLV9mUF9idjVkTkZkajhTZkE&invite=CPij0K0L - - -Guidelines ----------- -BVT test cases are being developed using Python's unittests2. Following are certain guidelines being followed - 1. Tests exercised for the same resource should ideally be present under a single suite or file. - - 2. Time-consuming operations that create new cloud resources like server creation, volume creation etc - should not necessarily be exercised per unit test. The resources can be shared by creating them at - the class-level using setUpClass and shared across all instances during a single run. - - 3. Certain tests pertaining to NAT, Firewall and Load Balancing warrant fresh resources per test. Hence a call should be - taken by the stakeholders regarding sharing resources. - - 4. Ensure that the tearDown/tearDownClass functions clean up all the resources created during the test run. - -For more information about unittests: http://docs.python.org/library/unittest.html - - -BVT Tests ----------- -The following files contain these BVT cases: - -1. test_vm_life_cycle.py - VM Life Cycle tests -2. test_volumes.py - Volumes related tests -3. test_snapshots.py - Snapshots related tests -4. test_disk_offerings.py - Disk Offerings related tests -5. test_service_offerings.py - Service Offerings related tests -6. test_hosts.py - Hosts and Clusters related tests -7. test_iso.py - ISO related tests -8. test_network.py - Network related tests -9. test_primary_storage.py - Primary storage related tests -10. test_secondary_storage.py - Secondary storage related tests -11. test_ssvm.py - SSVM & CPVM related tests -12. test_templates.py - Templates related tests -13. test_routers.py - Router related tests - diff --git a/test/integration/smoke/test_disk_offerings.py b/test/integration/smoke/test_disk_offerings.py index eeb514aa378..ce77b9aecf6 100644 --- a/test/integration/smoke/test_disk_offerings.py +++ b/test/integration/smoke/test_disk_offerings.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr class Services: @@ -49,7 +49,6 @@ class TestCreateDiskOffering(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -112,7 +111,6 @@ class TestDiskOfferings(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/smoke/test_hosts.py b/test/integration/smoke/test_hosts.py index ad443256f3f..cedf43c58f0 100644 --- a/test/integration/smoke/test_hosts.py +++ b/test/integration/smoke/test_hosts.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr #Import System modules @@ -109,7 +109,6 @@ class TestHosts(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -226,4 +225,4 @@ class TestHosts(cloudstackTestCase): cluster.hypervisortype, "Check hypervisor type with is " + v["hypervisor"] + " or not" ) - return \ No newline at end of file + return diff --git a/test/integration/smoke/test_iso.py b/test/integration/smoke/test_iso.py index 17da99c0e36..7ed2c1bb4e8 100644 --- a/test/integration/smoke/test_iso.py +++ b/test/integration/smoke/test_iso.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr import urllib from random import random @@ -108,8 +108,6 @@ class TestCreateIso(cloudstackTestCase): def tearDown(self): try: - - self.dbclient.close() #Clean up, terminate the created ISOs cleanup_resources(self.apiclient, self.cleanup) @@ -247,7 +245,6 @@ class TestISO(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created ISOs, VMs cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py index b0a793c5c6d..c1277f5933f 100644 --- a/test/integration/smoke/test_network.py +++ b/test/integration/smoke/test_network.py @@ -21,9 +21,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr #Import System modules import time diff --git a/test/integration/smoke/test_primary_storage.py b/test/integration/smoke/test_primary_storage.py index 5c804f7ed9c..7daf3ca1cbe 100644 --- a/test/integration/smoke/test_primary_storage.py +++ b/test/integration/smoke/test_primary_storage.py @@ -20,10 +20,10 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr -from integration.lib.common import * #Import System modules import time @@ -240,4 +240,4 @@ class TestPrimaryStorageServices(cloudstackTestCase): # Call cleanup for reusing primary storage cleanup_resources(self.apiclient, self.cleanup) self.cleanup = [] - return \ No newline at end of file + return diff --git a/test/integration/smoke/test_routers.py b/test/integration/smoke/test_routers.py index e5f4735a846..346ba6189da 100644 --- a/test/integration/smoke/test_routers.py +++ b/test/integration/smoke/test_routers.py @@ -21,9 +21,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr #Import System modules import time diff --git a/test/integration/smoke/test_secondary_storage.py b/test/integration/smoke/test_secondary_storage.py index ef81d041b82..d345bcb56b8 100644 --- a/test/integration/smoke/test_secondary_storage.py +++ b/test/integration/smoke/test_secondary_storage.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr #Import System modules @@ -241,7 +241,6 @@ class TestSecStorageServices(cloudstackTestCase): self.apiclient, systemvmtype='secondarystoragevm', zoneid=self.zone.id, - podid=self.pod.id ) if not isinstance(list_ssvm_response, list): # Sleep to ensure SSVMs are Up and Running @@ -277,8 +276,8 @@ class TestSecStorageServices(cloudstackTestCase): # Validate the following # If SSVM is in UP state and running - # 1. wait for listTemplates to show all builtin templates - # downloaded for all added hypervisors and in “Ready” state" + # 1. wait for listTemplates to show all builtin templates downloaded and + # in Ready state for k, v in self.services["hypervisors"].items(): diff --git a/test/integration/smoke/test_service_offerings.py b/test/integration/smoke/test_service_offerings.py index 5913338a207..a4188b6cee2 100644 --- a/test/integration/smoke/test_service_offerings.py +++ b/test/integration/smoke/test_service_offerings.py @@ -20,9 +20,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr @@ -52,7 +52,6 @@ class TestCreateServiceOffering(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -132,7 +131,6 @@ class TestServiceOfferings(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/smoke/test_snapshots.py b/test/integration/smoke/test_snapshots.py deleted file mode 100644 index 79a2c0a2852..00000000000 --- a/test/integration/smoke/test_snapshots.py +++ /dev/null @@ -1,1177 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -""" BVT tests for Snapshots -""" -#Import Local Modules -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.remoteSSHClient import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * -from nose.plugins.attrib import attr - - -class Services: - """Test Snapshots Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "server_with_disk": - { - "displayname": "Test VM -With Disk", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - - "server_without_disk": - { - "displayname": "Test VM-No Disk", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - # For NAT rule creation - "publicport": 22, - "protocol": 'TCP', - }, - - "recurring_snapshot": - { - "intervaltype": 'HOURLY', - # Frequency of snapshots - "maxsnaps": 1, # Should be min 2 - "schedule": 1, - "timezone": 'US/Arizona', - # Timezone Formats - http://cloud.mindtouch.us/CloudStack_Documentation/Developer's_Guide%3A_CloudStack - }, - - "templates": - { - "displaytext": 'Template from snapshot', - "name": 'Template from snapshot', - "ostypeid": '01853327-513e-4508-9628-f1f55db1946f', - "templatefilter": 'self', - }, - "ostypeid": '01853327-513e-4508-9628-f1f55db1946f', - # Cent OS 5.3 (64 bit) - "diskdevice": "/dev/xvdb", # Data Disk - "rootdisk": "/dev/xvda", # Root Disk - - "diskname": "Test Disk", - "size": 1, # GBs - - "mount_dir": "/mnt/tmp", - "sub_dir": "test", - "sub_lvl_dir1": "test1", - "sub_lvl_dir2": "test2", - "random_data": "random.data", - - "username": "root", - "password": "password", - "ssh_port": 22, - "sleep": 60, - "timeout": 10, - "mode": 'advanced', - # Networking mode, Advanced, Basic - } - - -class TestSnapshotRootDisk(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshotRootDisk, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["server_without_disk"]["zoneid"] = cls.zone.id - cls.services["template"] = template.id - cls.services["zoneid"] = cls.zone.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = cls.virtual_machine_with_disk = \ - VirtualMachine.create( - cls.api_client, - cls.services["server_without_disk"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - cls._cleanup = [ - cls.service_offering, - cls.account, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) - def test_01_snapshot_root_disk(self): - """Test Snapshot Root Disk - """ - - # Validate the following - # 1. listSnapshots should list the snapshot that was created. - # 2. verify that secondary storage NFS share contains - # the reqd volume under - # /secondary/snapshots//$account_id/$volumeid/$snapshot_uuid - # 3. verify backup_snap_id was non null in the `snapshots` table - - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine_with_disk.id, - type='ROOT', - listall=True - ) - - snapshot = Snapshot.create( - self.apiclient, - volumes[0].id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Snapshot created: ID - %s" % snapshot.id) - - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list item call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check resource id in list resources call" - ) - self.debug( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % str(snapshot.id) - ) - qresultset = self.dbclient.execute( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % str(snapshot.id) - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = qresultset[0] - - snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID - account_id = qresult[1] - volume_id = qresult[2] - - self.assertNotEqual( - str(snapshot_uuid), - 'NULL', - "Check if backup_snap_id is not null" - ) - - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - - try: - # Login to VM to check snapshot present on sec disk - ssh_client = self.virtual_machine_with_disk.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception: - self.fail("SSH failed for Virtual machine: %s" % - self.virtual_machine_with_disk.ipaddress) - - uuids.append(result) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception as e: - self.fail("SSH failed for Virtual machine: %s" % - self.virtual_machine_with_disk.ipaddress) - - res = str(uuids) - # Check snapshot UUID in secondary storage and database - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) - return - - -class TestSnapshots(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshots, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - - cls.services["domainid"] = cls.domain.id - cls.services["server_with_disk"]["zoneid"] = cls.zone.id - cls.services["server_with_disk"]["diskoffering"] = cls.disk_offering.id - - cls.services["server_without_disk"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - cls.services["zoneid"] = cls.zone.id - cls.services["diskoffering"] = cls.disk_offering.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = cls.virtual_machine_with_disk = \ - VirtualMachine.create( - cls.api_client, - cls.services["server_with_disk"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - cls.virtual_machine_without_disk = \ - VirtualMachine.create( - cls.api_client, - cls.services["server_without_disk"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) - def test_02_snapshot_data_disk(self): - """Test Snapshot Data Disk - """ - - volume = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine_with_disk.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(volume, list), - True, - "Check list response returns a valid list" - ) - - self.debug("Creating a Snapshot from data volume: %s" % volume[0].id) - snapshot = Snapshot.create( - self.apiclient, - volume[0].id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list item call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check resource id in list resources call" - ) - self.debug( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % str(snapshot.id) - ) - qresultset = self.dbclient.execute( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % str(snapshot.id) - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = qresultset[0] - snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID - account_id = qresult[1] - volume_id = qresult[2] - - self.assertNotEqual( - str(snapshot_uuid), - 'NULL', - "Check if backup_snap_id is not null" - ) - - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export - - try: - # Login to VM to check snapshot present on sec disk - ssh_client = self.virtual_machine_with_disk.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine_with_disk.ipaddress) - - uuids.append(result) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine_with_disk.ipaddress) - - res = str(uuids) - # Check snapshot UUID in secondary storage and database - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) - return - - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) - def test_03_volume_from_snapshot(self): - """Create volumes from snapshots - """ - #1. Login to machine; create temp/test directories on data volume - #2. Snapshot the Volume - #3. Create another Volume from snapshot - #4. Mount/Attach volume to another server - #5. Compare data - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - - try: - ssh_client = self.virtual_machine.get_ssh_client() - - #Format partition using ext3 - format_volume_to_ext3( - ssh_client, - self.services["diskdevice"] - ) - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] - ), - "mkdir -p %s/%s/{%s,%s} " % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - ), - ] - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) - - list_volume_response = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - - volume_response = list_volume_response[0] - #Create snapshot from attached volume - snapshot = Snapshot.create( - self.apiclient, - volume_response.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created Snapshot from volume: %s" % volume_response.id) - - #Create volume from snapshot - self.debug("Creating volume from snapshot: %s" % snapshot.id) - volume = Volume.create_from_snapshot( - self.apiclient, - snapshot.id, - self.services, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - volumes = list_volumes( - self.apiclient, - id=volume.id - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(volumes), - None, - "Check Volume list Length" - ) - - self.assertEqual( - volumes[0].id, - volume.id, - "Check Volume in the List Volumes" - ) - #Attaching volume to new VM - new_virtual_machine = self.virtual_machine_without_disk - self.cleanup.append(new_virtual_machine) - - cmd = attachVolume.attachVolumeCmd() - cmd.id = volume.id - cmd.virtualmachineid = new_virtual_machine.id - self.apiclient.attachVolume(cmd) - - try: - #Login to VM to verify test directories and files - ssh = new_virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] - ), - ] - - for c in cmds: - self.debug(c) - result = ssh.execute(c) - self.debug(result) - - returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - )) - returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - )) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) - - #Verify returned data - self.assertEqual( - random_data_0, - returned_data_0[0], - "Verify newly attached volume contents with existing one" - ) - self.assertEqual( - random_data_1, - returned_data_1[0], - "Verify newly attached volume contents with existing one" - ) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) - return - - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) - def test_04_delete_snapshot(self): - """Test Delete Snapshot - """ - - #1. Snapshot the Volume - #2. Delete the snapshot - #3. Verify snapshot is removed by calling List Snapshots API - - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - snapshot = Snapshot.create( - self.apiclient, - volumes[0].id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - snapshot.delete(self.apiclient) - - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id - ) - - self.assertEqual( - snapshots, - None, - "Check if result exists in list item call" - ) - return - - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) - def test_05_recurring_snapshot_root_disk(self): - """Test Recurring Snapshot Root Disk - """ - #1. Create snapshot policy for root disk - #2. ListSnapshot policy should return newly created policy - #3. Verify only most recent number (maxsnaps) snapshots retailed - - volume = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine_with_disk.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volume, list), - True, - "Check list response returns a valid list" - ) - recurring_snapshot = SnapshotPolicy.create( - self.apiclient, - volume[0].id, - self.services["recurring_snapshot"] - ) - self.cleanup.append(recurring_snapshot) - - #ListSnapshotPolicy should return newly created policy - list_snapshots_policy = list_snapshot_policy( - self.apiclient, - id=recurring_snapshot.id, - volumeid=volume[0].id - ) - self.assertEqual( - isinstance(list_snapshots_policy, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - list_snapshots_policy, - None, - "Check if result exists in list item call" - ) - snapshots_policy = list_snapshots_policy[0] - self.assertEqual( - snapshots_policy.id, - recurring_snapshot.id, - "Check recurring snapshot id in list resources call" - ) - self.assertEqual( - snapshots_policy.maxsnaps, - self.services["recurring_snapshot"]["maxsnaps"], - "Check interval type in list resources call" - ) - # Sleep for (maxsnaps+1) hours to verify - # only maxsnaps snapshots are retained - time.sleep( - (self.services["recurring_snapshot"]["maxsnaps"]) * 3600 - ) - - timeout = self.services["timeout"] - while True: - snapshots = list_snapshots( - self.apiclient, - volumeid=volume[0].id, - intervaltype=\ - self.services["recurring_snapshot"]["intervaltype"], - snapshottype='RECURRING', - listall=True - ) - - if isinstance(snapshots, list): - break - - elif timeout == 0: - raise Exception("List snapshots API call failed.") - - time.sleep(1) - timeout = timeout - 1 - - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - - self.assertEqual( - len(snapshots), - self.services["recurring_snapshot"]["maxsnaps"], - "Check maximum number of recurring snapshots retained" - ) - return - - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) - def test_06_recurring_snapshot_data_disk(self): - """Test Recurring Snapshot data Disk - """ - #1. Create snapshot policy for data disk - #2. ListSnapshot policy should return newly created policy - #3. Verify only most recent number (maxsnaps) snapshots retailed - - volume = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine_with_disk.id, - type='DATADISK', - listall=True - ) - - self.assertEqual( - isinstance(volume, list), - True, - "Check list response returns a valid list" - ) - - recurring_snapshot = SnapshotPolicy.create( - self.apiclient, - volume[0].id, - self.services["recurring_snapshot"] - ) - self.cleanup.append(recurring_snapshot) - #ListSnapshotPolicy should return newly created policy - list_snapshots_policy = list_snapshot_policy( - self.apiclient, - id=recurring_snapshot.id, - volumeid=volume[0].id - ) - - self.assertEqual( - isinstance(list_snapshots_policy, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - list_snapshots_policy, - None, - "Check if result exists in list item call" - ) - snapshots_policy = list_snapshots_policy[0] - self.assertEqual( - snapshots_policy.id, - recurring_snapshot.id, - "Check recurring snapshot id in list resources call" - ) - self.assertEqual( - snapshots_policy.maxsnaps, - self.services["recurring_snapshot"]["maxsnaps"], - "Check interval type in list resources call" - ) - - # Sleep for (maxsnaps) hours to verify only maxsnaps snapshots are - # retained - time.sleep( - (self.services["recurring_snapshot"]["maxsnaps"]) * 3600 - ) - - timeout = self.services["timeout"] - while True: - snapshots = list_snapshots( - self.apiclient, - volumeid=volume[0].id, - intervaltype=\ - self.services["recurring_snapshot"]["intervaltype"], - snapshottype='RECURRING', - listall=True - ) - - if isinstance(snapshots, list): - break - - elif timeout == 0: - raise Exception("List snapshots API call failed.") - - time.sleep(1) - timeout = timeout - 1 - - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(snapshots), - self.services["recurring_snapshot"]["maxsnaps"], - "Check maximum number of recurring snapshots retained" - ) - return - - @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke"]) - def test_07_template_from_snapshot(self): - """Create Template from snapshot - """ - - #1. Login to machine; create temp/test directories on data volume - #2. Snapshot the Volume - #3. Create Template from snapshot - #4. Deploy Virtual machine using this template - #5. Login to newly created virtual machine - #6. Compare data - - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - - try: - #Login to virtual machine - ssh_client = self.virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["rootdisk"], - self.services["mount_dir"] - ), - "mkdir -p %s/%s/{%s,%s} " % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - ), - "sync", - ] - - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception as e: - self.fail("SSH failed for VM with IP address: %s" % - self.virtual_machine.ipaddress) - - # Unmount the Volume - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - - volume = volumes[0] - - #Create a snapshot of volume - snapshot = Snapshot.create( - self.apiclient, - volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.debug("Snapshot created from volume ID: %s" % volume.id) - # Generate template from the snapshot - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["templates"] - ) - self.cleanup.append(template) - self.debug("Template created from snapshot ID: %s" % snapshot.id) - - # Verify created template - templates = list_templates( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id - ) - self.assertNotEqual( - templates, - None, - "Check if result exists in list item call" - ) - - self.assertEqual( - templates[0].id, - template.id, - "Check new template id in list resources call" - ) - self.debug("Deploying new VM from template: %s" % template.id) - - # Deploy new virtual machine using template - new_virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server_without_disk"], - templateid=template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - mode=self.services["mode"] - ) - self.cleanup.append(new_virtual_machine) - - try: - #Login to VM & mount directory - ssh = new_virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["rootdisk"], - self.services["mount_dir"] - ) - ] - - for c in cmds: - ssh.execute(c) - - returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - )) - self.debug(returned_data_0) - returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - )) - self.debug(returned_data_1) - except Exception as e: - self.fail("SSH failed for VM with IP address: %s" % - new_virtual_machine.ipaddress) - #Verify returned data - self.assertEqual( - random_data_0, - returned_data_0[0], - "Verify newly attached volume contents with existing one" - ) - self.assertEqual( - random_data_1, - returned_data_1[0], - "Verify newly attached volume contents with existing one" - ) - # Unmount the volume - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP address: %s" % - new_virtual_machine.ipaddress) - return diff --git a/test/integration/smoke/test_ssvm.py b/test/integration/smoke/test_ssvm.py index 5c9d030380d..e86446330cd 100644 --- a/test/integration/smoke/test_ssvm.py +++ b/test/integration/smoke/test_ssvm.py @@ -21,9 +21,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr import telnetlib diff --git a/test/integration/smoke/test_templates.py b/test/integration/smoke/test_templates.py index d68371667b5..62b923768d8 100644 --- a/test/integration/smoke/test_templates.py +++ b/test/integration/smoke/test_templates.py @@ -21,9 +21,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.remoteSSHClient import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr import urllib from random import random @@ -112,7 +112,6 @@ class TestCreateTemplate(cloudstackTestCase): def tearDown(self): try: - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) @@ -418,8 +417,6 @@ class TestTemplates(cloudstackTestCase): def tearDown(self): try: - - self.dbclient.close() #Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index b47c1642925..15ffb26e6f8 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -21,9 +21,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.remoteSSHClient import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr #Import System modules import time diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index ed5cbafe28d..1707187210e 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -21,9 +21,9 @@ import marvin from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.remoteSSHClient import remoteSSHClient -from integration.lib.utils import * -from integration.lib.base import * -from integration.lib.common import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * from nose.plugins.attrib import attr #Import System modules import os diff --git a/test/pom.xml b/test/pom.xml index f70a89f825a..4507e8cc916 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -16,15 +16,14 @@ specific language governing permissions and limitations under the License. --> - + 4.0.0 cloud-testclient Apache CloudStack Test org.apache.cloudstack cloudstack - 4.0.0-SNAPSHOT + 4.1.0-SNAPSHOT diff --git a/test/scripts/wget.exe b/test/scripts/wget.exe deleted file mode 100644 index 1b15a04242a..00000000000 Binary files a/test/scripts/wget.exe and /dev/null differ diff --git a/test/setup-test-data.sh b/test/setup-test-data.sh index 732d5937efd..844c275da7c 100755 --- a/test/setup-test-data.sh +++ b/test/setup-test-data.sh @@ -20,6 +20,7 @@ usage() { printf "Usage: %s:\n [-t path to tests ] \n [-m mgmt-server ] \n + [-h hypervisor (xen|kvm) ] \n [-p hypervisor root password ] \n [-d db node url ]\n" $(basename $0) >&2 } @@ -34,7 +35,7 @@ MGMT_SVR="localhost" DB_SVR="localhost" HV_PASSWD="password" -while getopts 't:d:m:p:' OPTION +while getopts 't:d:m:p:h:' OPTION do case $OPTION in d) dflag=1 @@ -46,6 +47,9 @@ do m) mflag=1 MGMT_SVR="$OPTARG" ;; + h) hflag=1 + HV="$OPTARG" + ;; p) pflag=1 HV_PASSWD="$OPTARG" ;; @@ -56,13 +60,17 @@ do done #Damn Small Linux ISO type -ostypeid=$(mysql -uroot -Dcloud -h$DB_SVR -s -N -r -e"select uuid from guest_os where display_name='CentOS 5.3 (64-bit)'") +if [[ $HV == "kvm" ]]; then + ostypeid=$(mysql -ucloud -Dcloud -pcloud -h$DB_SVR -s -N -r -e"select uuid from guest_os where display_name='CentOS 5.5 (64-bit)'") +else + ostypeid=$(mysql -ucloud -Dcloud -pcloud -h$DB_SVR -s -N -r -e"select uuid from guest_os where display_name='CentOS 5.3 (64-bit)'") +fi if [[ $ostypeid == "" ]]; then echo "Unable to contact DB server @ $DB_SVR" exit 2 fi -$(nc -z $MGMT_SVR 8096) +nc -z $MGMT_SVR 8096 if [[ $? -ne 0 ]]; then echo "$MGMT_SVR doesn't have port 8096 open" exit 2 diff --git a/setup/apidoc/XmlToHtmlConverter.java b/tools/apidoc/XmlToHtmlConverter.java similarity index 100% rename from setup/apidoc/XmlToHtmlConverter.java rename to tools/apidoc/XmlToHtmlConverter.java diff --git a/setup/apidoc/build-apidoc.sh b/tools/apidoc/build-apidoc.sh old mode 100644 new mode 100755 similarity index 100% rename from setup/apidoc/build-apidoc.sh rename to tools/apidoc/build-apidoc.sh diff --git a/setup/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py similarity index 99% rename from setup/apidoc/gen_toc.py rename to tools/apidoc/gen_toc.py index 1f7fe36d556..4106531ac84 100644 --- a/setup/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -124,6 +124,7 @@ known_categories = { 'PrivateGateway': 'VPC', 'StaticRoute': 'VPC', 'Tags': 'Resource tags', + 'NiciraNvpDevice': 'Nicira NVP' } diff --git a/setup/apidoc/generateadmincommands.xsl b/tools/apidoc/generateadmincommands.xsl similarity index 97% rename from setup/apidoc/generateadmincommands.xsl rename to tools/apidoc/generateadmincommands.xsl index 73872a32102..5f576c0f887 100644 --- a/setup/apidoc/generateadmincommands.xsl +++ b/tools/apidoc/generateadmincommands.xsl @@ -8,7 +8,7 @@ version="1.0"> -CloudStack | The Power Behind Your Cloud +Apache CloudStack | The Power Behind Your Cloud @@ -39,7 +39,7 @@ version="1.0"> - CloudStack v3.0 Root Admin API Reference + Apache CloudStack v4.0.0 Root Admin API Reference

diff --git a/setup/apidoc/generatecommand.xsl b/tools/apidoc/generatecommand.xsl similarity index 100% rename from setup/apidoc/generatecommand.xsl rename to tools/apidoc/generatecommand.xsl diff --git a/setup/apidoc/generatecustomcommand.xsl b/tools/apidoc/generatecustomcommand.xsl similarity index 100% rename from setup/apidoc/generatecustomcommand.xsl rename to tools/apidoc/generatecustomcommand.xsl diff --git a/setup/apidoc/generatedomainadmincommands.xsl b/tools/apidoc/generatedomainadmincommands.xsl similarity index 97% rename from setup/apidoc/generatedomainadmincommands.xsl rename to tools/apidoc/generatedomainadmincommands.xsl index f7e560c7680..7d60ef2b91f 100644 --- a/setup/apidoc/generatedomainadmincommands.xsl +++ b/tools/apidoc/generatedomainadmincommands.xsl @@ -8,7 +8,7 @@ version="1.0"> -CloudStack | The Power Behind Your Cloud +Apache CloudStack | The Power Behind Your Cloud @@ -42,7 +42,7 @@ version="1.0"> - CloudStack v3.0 Domain Admin API Reference + Apache CloudStack v4.0.0 Domain Admin API Reference

diff --git a/setup/apidoc/generategenericcommand.xsl b/tools/apidoc/generategenericcommand.xsl similarity index 100% rename from setup/apidoc/generategenericcommand.xsl rename to tools/apidoc/generategenericcommand.xsl diff --git a/setup/apidoc/generatetoc.xsl b/tools/apidoc/generatetoc.xsl similarity index 100% rename from setup/apidoc/generatetoc.xsl rename to tools/apidoc/generatetoc.xsl diff --git a/setup/apidoc/generatetoc_footer.xsl b/tools/apidoc/generatetoc_footer.xsl similarity index 100% rename from setup/apidoc/generatetoc_footer.xsl rename to tools/apidoc/generatetoc_footer.xsl diff --git a/setup/apidoc/generatetoc_header.xsl b/tools/apidoc/generatetoc_header.xsl similarity index 97% rename from setup/apidoc/generatetoc_header.xsl rename to tools/apidoc/generatetoc_header.xsl index 99066b563d6..ffb8c2973c1 100644 --- a/setup/apidoc/generatetoc_header.xsl +++ b/tools/apidoc/generatetoc_header.xsl @@ -52,7 +52,7 @@ version="1.0">
-

CloudStack API Documentation (v3.0)

+

Apache CloudStack API Documentation (v4.0.0)

Using the CloudStack API

diff --git a/setup/apidoc/generateusercommands.xsl b/tools/apidoc/generateusercommands.xsl similarity index 97% rename from setup/apidoc/generateusercommands.xsl rename to tools/apidoc/generateusercommands.xsl index 3ec3a62c425..ca0eb1f6eaf 100644 --- a/setup/apidoc/generateusercommands.xsl +++ b/tools/apidoc/generateusercommands.xsl @@ -8,7 +8,7 @@ version="1.0"> -CloudStack | The Power Behind Your Cloud +Apache CloudStack | The Power Behind Your Cloud @@ -39,7 +39,7 @@ version="1.0"> - CloudStack v3.0 User API Reference + Apache CloudStack v4.0.0 User API Reference

diff --git a/setup/apidoc/images/api_bullets.gif b/tools/apidoc/images/api_bullets.gif similarity index 100% rename from setup/apidoc/images/api_bullets.gif rename to tools/apidoc/images/api_bullets.gif diff --git a/setup/apidoc/images/back_button.gif b/tools/apidoc/images/back_button.gif similarity index 100% rename from setup/apidoc/images/back_button.gif rename to tools/apidoc/images/back_button.gif diff --git a/setup/apidoc/images/back_button_hover.gif b/tools/apidoc/images/back_button_hover.gif similarity index 100% rename from setup/apidoc/images/back_button_hover.gif rename to tools/apidoc/images/back_button_hover.gif diff --git a/setup/apidoc/images/cloudstack.png b/tools/apidoc/images/cloudstack.png similarity index 100% rename from setup/apidoc/images/cloudstack.png rename to tools/apidoc/images/cloudstack.png diff --git a/setup/apidoc/images/ins_buttonshadow.gif b/tools/apidoc/images/ins_buttonshadow.gif similarity index 100% rename from setup/apidoc/images/ins_buttonshadow.gif rename to tools/apidoc/images/ins_buttonshadow.gif diff --git a/setup/apidoc/images/insdownload_button.gif b/tools/apidoc/images/insdownload_button.gif similarity index 100% rename from setup/apidoc/images/insdownload_button.gif rename to tools/apidoc/images/insdownload_button.gif diff --git a/setup/apidoc/images/insdownload_button_hover.gif b/tools/apidoc/images/insdownload_button_hover.gif similarity index 100% rename from setup/apidoc/images/insdownload_button_hover.gif rename to tools/apidoc/images/insdownload_button_hover.gif diff --git a/setup/apidoc/images/insjoincomm_button.gif b/tools/apidoc/images/insjoincomm_button.gif similarity index 100% rename from setup/apidoc/images/insjoincomm_button.gif rename to tools/apidoc/images/insjoincomm_button.gif diff --git a/setup/apidoc/images/insjoincomm_button_hover.gif b/tools/apidoc/images/insjoincomm_button_hover.gif similarity index 100% rename from setup/apidoc/images/insjoincomm_button_hover.gif rename to tools/apidoc/images/insjoincomm_button_hover.gif diff --git a/setup/apidoc/includes/main.css b/tools/apidoc/includes/main.css similarity index 100% rename from setup/apidoc/includes/main.css rename to tools/apidoc/includes/main.css diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml new file mode 100644 index 00000000000..d36b8ebeb6b --- /dev/null +++ b/tools/apidoc/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + cloud-apidoc + Apache CloudStack apidoc Tools + pom + + org.apache.cloudstack + cloudstack + 4.1.0-SNAPSHOT + ../../pom.xml + + + + org.apache.cloudstack + cloud-client-ui + ${project.version} + war + + + + ../../client/target/cloud-client-ui-4.1.0-SNAPSHOT/WEB-INF/ + ${client.config.base}/lib + ${client.config.base}/classes + + + + install + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + compile + compile + + exec + + + bash + + -x + ./build-apidoc.sh + ${client.config.jars} + ${client.config.jars} + ./target + -f + ${client.config.conf}/commands.properties, ${client.config.conf}/commands-ext.properties,${client.config.conf}/virtualrouter_commands.properties, ${client.config.conf}/nicira-nvp_commands.properties + + + + + package + package + + exec + + + target + tar + + -cvjf + apidoc.tar.bz2 + xmldoc + + + + + + + + diff --git a/tools/build/build_asf.sh b/tools/build/build_asf.sh index 9d05f177247..c652a20bf42 100755 --- a/tools/build/build_asf.sh +++ b/tools/build/build_asf.sh @@ -23,7 +23,6 @@ branch='master' tag='no' certid='X' - usage(){ echo "usage: $0 -v version [-b branch] [-s source dir] [-o output dir] [-t [-u]] [-h]" echo " -v sets the version" @@ -31,11 +30,12 @@ usage(){ echo " -s sets the source directory (defaults to $sourcedir)" echo " -o sets the output directory (defaults to $outputdir)" echo " -t tags the git repo with the version" - echo " -u sets the certificate ID to sign the tag with (if not provided, the default key is attempted)" + echo " -u sets the certificate ID to sign the tag with (if not provided, the default key is attempted)" + echo " -k sets the key to sign the tarball with" echo " -h" } -while getopts v:s:o:b:tu:h opt +while getopts v:s:o:b:tu:k:h opt do case "$opt" in v) version="$OPTARG";; @@ -44,9 +44,10 @@ do b) branch="$OPTARG";; t) tag='yes';; u) certid="$OPTARG";; + k) keyid="--default-key $OPTARG";; h) usage exit 0;; - \?) # unknown flag + /?) # unknown flag usage exit 1;; esac @@ -73,29 +74,31 @@ else fi if [ -d "$outputdir" ]; then - rm $outputdir/* + rm -r $outputdir/* else mkdir $outputdir fi -cp $sourcedir/KEYS $outputdir/KEYS - cd $sourcedir -git archive --format=tar.gz --prefix=apache-cloudstack-$version-incubating-src/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.tar.gz -git archive --format=zip --prefix=apache-cloudstack-$version-incubating-src/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.zip +echo 'archiving' +git archive --format=tar --prefix=apache-cloudstack-$version-incubating-src/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.tar +bzip2 $outputdir/apache-cloudstack-$version-incubating-src.tar cd $outputdir -gpg -v --armor --output apache-cloudstack-$version-incubating-src.tar.gz.asc --detach-sig apache-cloudstack-$version-incubating-src.tar.gz -gpg -v --armor --output apache-cloudstack-$version-incubating-src.zip.asc --detach-sig apache-cloudstack-$version-incubating-src.zip -gpg -v --print-md MD5 apache-cloudstack-$version-incubating-src.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.md5 -gpg -v --print-md MD5 apache-cloudstack-$version-incubating-src.zip > apache-cloudstack-$version-incubating-src.zip.md5 -gpg -v --print-md SHA512 apache-cloudstack-$version-incubating-src.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.sha -gpg -v --print-md SHA512 apache-cloudstack-$version-incubating-src.zip > apache-cloudstack-$version-incubating-src.zip.sha +echo 'armor' +gpg -v $keyid --armor --output apache-cloudstack-$version-incubating-src.tar.bz2.asc --detach-sig apache-cloudstack-$version-incubating-src.tar.bz2 -gpg -v --verify apache-cloudstack-$version.tar.gz.asc apache-cloudstack-$version-incubating-src.tar.gz -gpg -v --verify apache-cloudstack-$version.zip.asc apache-cloudstack-$version-incubating-src.zip +echo 'md5' +gpg -v --print-md MD5 apache-cloudstack-$version-incubating-src.tar.bz2 > apache-cloudstack-$version-incubating-src.tar.bz2.md5 + +echo 'sha' +gpg -v --print-md SHA512 apache-cloudstack-$version-incubating-src.tar.bz2 > apache-cloudstack-$version-incubating-src.tar.bz2.sha + +echo 'verify' +gpg -v --verify apache-cloudstack-$version-incubating-src.tar.bz2.asc apache-cloudstack-$version-incubating-src.tar.bz2 if [ $tag == 'yes' ]; then + echo 'tag' cd $sourcedir if [ $certid == 'X' ]; then git tag -s $version -m "Tagging release $version on branch $branch." diff --git a/tools/build/build_docs.sh b/tools/build/build_docs.sh new file mode 100755 index 00000000000..8bb63e30e87 --- /dev/null +++ b/tools/build/build_docs.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +sourcedir=~/incubator-cloudstack/ +common_content_dir=/usr/share/publican/Common_Content +publican_path=/usr/bin/publican + +usage(){ + echo "usage: $0 [-s source dir] [-c publican common content] [-p path to publican]" + echo " -s sets the source directory (defaults to $sourcedir)" + echo " -c sets the public common content directory (defaults to $common_content_dir)" + echo " -p sets the path to the publican binary (defaults to $publican_path)" + echo " -h" +} + +while getopts v:s:c:p:h opt +do + case "$opt" in + v) version="$OPTARG";; + s) sourcedir="$OPTARG";; + c) common_content_dir="$OPTARG";; + p) publican_path="$OPTARG";; + h) usage + exit 0;; + \?) + usage + exit 1;; + esac +done + +if [ ! -x "$publican_path" ]; then + echo "$publican_path doesn't seem like an executeable?" + exit 1 +fi + +cd $sourcedir/docs +cp -R /usr/share/publican/Common_Content . +ln -s $sourcedir/docs/publican-cloudstack Common_Content/cloudstack +publican build --config=publican-installation.cfg --formats html,pdf --langs en-US --common_content=$sourcedir/docs/Common_Content +rm -r Common_Content \ No newline at end of file diff --git a/tools/build/installer/debinstall_full.sh b/tools/build/installer/debinstall_full.sh new file mode 100644 index 00000000000..a3bf1aeec57 --- /dev/null +++ b/tools/build/installer/debinstall_full.sh @@ -0,0 +1,163 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + + +function cleanup() { + test -f /etc/apt/sources.list.vmops.bak && mv -f /etc/apt/sources.list.vmops.bak /etc/apt/sources.list || true +} + +function setuprepo() { + pathtorepo=`pwd` + echo "Setting up the temporary repository..." >&2 + cp /etc/apt/sources.list /etc/apt/sources.list.vmops.bak + echo " +deb file://$pathtorepo ./" >> /etc/apt/sources.list + + echo "Fetching updated listings..." >&2 + aptitude update +} + +function installed() { + dpkg -l "$@" 2> /dev/null | grep '^i' > /dev/null || return $? +} + +function doinstall() { + aptitude install "$@" || return $? +} + +function doupdate() { + service cloud-management stop + apt-get --force-yes -y -u install "cloud-*" + service cloud-management restart +} + +function doremove() { + apt-get remove "$@" || return $? +} + +[ `whoami` != 'root' ] && echo "This script must run as root" && exit 1 + +trap "cleanup" INT TERM EXIT + +cd `dirname "$0"` +setuprepo + +installms=" M) Install the Management Server +" +installag=" A) Install the Agent +" +installus=" S) Install the Usage Monitor +" +installdb=" D) Install the database server +" +quitoptio=" Q) Quit +" +unset removedb +unset upgrade +unset remove + +if installed cloud-client || installed cloud-agent || installed cloud-usage; then + upgrade=" U) Upgrade the CloudStack packages installed on this computer +" + remove=" R) Stop any running CloudStack services and remove the CloudStack packages from this computer +" +fi +if installed cloud-client ; then + unset installms +fi +if installed cloud-agent ; then + unset installag +fi +if installed cloud-usage ; then + unset installus +fi +if installed mysql-server ; then + unset installdb + removedb=" E) Remove the MySQL server (will not remove the MySQL databases) +" +fi + +read -p "Welcome to the Apache CloudStack (Incubating) Installer. What would you like to do? + +$installms$installag$installbm$installus$installdb$upgrade$remove$removedb$quitoptio + > " installtype + +if [ "$installtype" == "q" -o "$installtype" == "Q" ] ; then + + true + +elif [ "$installtype" == "m" -o "$installtype" == "M" ] ; then + + echo "Installing the Management Server..." >&2 + doinstall cloud-client + true + +elif [ "$installtype" == "a" -o "$installtype" == "A" ] ; then + + echo "Installing the Agent..." >&2 + if doinstall cloud-agent cloud-system-iso ; then + echo "Agent installation is completed, please add the host from management server" >&2 + else + true + fi +elif [ "$installtype" == "s" -o "$installtype" == "S" ] ; then + + echo "Installing the Usage Server..." >&2 + doinstall cloud-usage + true + +elif [ "$installtype" == "d" -o "$installtype" == "D" ] ; then + + echo "Installing the MySQL server..." >&2 + if doinstall mysql-server ; then + if /usr/sbin/service mysql status > /dev/null 2>&1 ; then + echo "Restarting the MySQL server..." >&2 + /usr/sbin/service mysql restart # mysqld running already, we restart it + else + echo "Starting the MySQL server..." >&2 + /usr/sbin/service mysql start # we start mysqld for the first time + fi + else + true + fi + +elif [ "$installtype" == "u" -o "$installtype" == "U" ] ; then + + echo "Updating the CloudStack and its dependencies..." >&2 + doupdate + +elif [ "$installtype" == "r" -o "$installtype" == "R" ] ; then + + echo "Removing all CloudStack packages on this computer..." >&2 + doremove 'cloud-*' + +elif [ "$installtype" == "e" -o "$installtype" == "E" ] ; then + + echo "Removing the MySQL server on this computer..." >&2 + doremove 'mysql-server' + +else + + echo "Incorrect choice. Nothing to do." >&2 + exit 8 + +fi + + +echo "Done" >&2 +cleanup diff --git a/tools/build/installer/rpminstall_full.sh b/tools/build/installer/rpminstall_full.sh new file mode 100755 index 00000000000..9cc78a5c7ee --- /dev/null +++ b/tools/build/installer/rpminstall_full.sh @@ -0,0 +1,178 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +function cleanup() { + rm -f /etc/yum.repos.d/cloud-temp.repo || true +} + +function setuprepo() { + pathtorepo=`pwd` + echo "Setting up the temporary repository..." >&2 + echo \ +"[cloud-temp] +baseurl=file://$pathtorepo +gpgcheck=0 +enabled=1 +name=CloudStack temporary repository +" > /etc/yum.repos.d/cloud-temp.repo + + echo "Cleaning Yum cache..." >&2 + rm /var/cache/yum/cloud-temp/ -rf + yum clean expire-cache || true +} + +function installed() { + rpm -q "$@" > /dev/null 2>&1 || return $? +} + +function doinstall() { + yum install "$@" || return $? +} + +function doupdate() { + yum update --enablerepo='cloud-temp' 'cloud-*' || return $? + rpm -Uvh --force cloud-scripts-*.rpm +} + +function doremove() { + yum remove "$@" || return $? +} + +[ `whoami` != 'root' ] && echo "This script must run as root" && exit 1 + +trap "cleanup" INT TERM EXIT + +cd `dirname "$0"` +setuprepo + +installms=" M) Install the Management Server +" +installag=" A) Install the Agent +" +installbm=" B) Install BareMetal Agent +" +installus=" S) Install the Usage Monitor +" +installdb=" D) Install the database server +" +quitoptio=" Q) Quit +" +unset removedb +unset upgrade +unset remove + +if installed cloud-client || installed cloud-agent || installed cloud-usage || installed cloud-baremetal-agent; then + upgrade=" U) Upgrade the CloudStack packages installed on this computer +" + remove=" R) Stop any running CloudStack services and remove the CloudStack packages from this computer +" +fi +if installed cloud-client ; then + unset installms +fi +if installed cloud-agent ; then + unset installag +fi +if installed cloud-baremetal-agent ; then + unset installbm +fi +if installed cloud-usage ; then + unset installus +fi +if installed mysql-server ; then + unset installdb + removedb=" E) Remove the MySQL server (will not remove the MySQL databases) +" +fi + +read -p "Welcome to the Apache CloudStack (Incubating) Installer. What would you like to do? + +$installms$installag$installbm$installus$installdb$upgrade$remove$removedb$quitoptio + > " installtype + +if [ "$installtype" == "q" -o "$installtype" == "Q" ] ; then + + true + +elif [ "$installtype" == "m" -o "$installtype" == "M" ] ; then + + echo "Installing the Management Server..." >&2 + doinstall cloud-client + true + +elif [ "$installtype" == "a" -o "$installtype" == "A" ] ; then + + echo "Installing the Agent..." >&2 + if doinstall cloud-agent; then + + echo "Agent installation is completed, please add the host from management server" >&2 + else + true + fi +elif [ "$installtype" == "b" -o "$installtype" == "B" ] ; then + echo "Installing the BareMetal Agent..." >&2 + doinstall cloud-baremetal-agent + true + +elif [ "$installtype" == "s" -o "$installtype" == "S" ] ; then + + echo "Installing the Usage Server..." >&2 + doinstall cloud-usage + true + +elif [ "$installtype" == "d" -o "$installtype" == "D" ] ; then + + echo "Installing the MySQL server..." >&2 + if doinstall mysql-server ; then + /sbin/chkconfig --add mysqld + /sbin/chkconfig --level 345 mysqld on + if /sbin/service mysqld status > /dev/null 2>&1 ; then + echo "Restarting the MySQL server..." >&2 + /sbin/service mysqld restart # mysqld running already, we restart it + else + echo "Starting the MySQL server..." >&2 + /sbin/service mysqld start # we start mysqld for the first time + fi + else + true + fi + +elif [ "$installtype" == "u" -o "$installtype" == "U" ] ; then + + echo "Updating the CloudStack and its dependencies..." >&2 + doupdate + +elif [ "$installtype" == "r" -o "$installtype" == "R" ] ; then + + echo "Removing all CloudStack packages on this computer..." >&2 + doremove 'cloud-*' + +elif [ "$installtype" == "e" -o "$installtype" == "E" ] ; then + + echo "Removing the MySQL server on this computer..." >&2 + doremove 'mysql-server' +else + + echo "Incorrect choice. Nothing to do." >&2 + exit 8 + +fi + + +echo "Done" >&2 +cleanup diff --git a/tools/devcloud/README b/tools/devcloud/README deleted file mode 100644 index b0161543284..00000000000 --- a/tools/devcloud/README +++ /dev/null @@ -1,56 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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. - -=========================================================== - -NOTE - This folder is a work in progress. The project has not determined -how to best establish a nightly DevCloud build process, or how to distribute -the image. - -=========================================================== -Contents: - -This folder contains various scripts used to build the devcloud image. -devcloudsetup.sh - the origional devcloud build script (assumes an Ubuntu 12.04 VM image) - -build_vagrant_basebox.sh - a script that uses VirtualBox, VeeWee, Vagrant (patched) and puppet to create a devcloud basebox -veewee - configuration files used to build a basic Ubuntu 12.04 vagrant box via VeeWee -basebuild - The Vagrantfile and puppet module that gets applied to the basic Ubuntu 12.04 box -devcloudbox - The Vagrantfile and puppet module that is used with the [hopefully] distributed devcloud base box - -=========================================================== -Instructions: - -To build a "devcloud base box", run you need a system with VirtualBox and rvm -installed (use ruby 1.9.2). Run build_vagrant_basebox.sh to build the base box. - -To use the "devcloud base box" that is created in the previous step, you -need to have installed a forked version of Vagrant (until we make the changes -plugins instead of direct source patches) that can be found here: - - -Once installed per the Vagrant installation process, run: - -vagrant box add devcloud [path to devcloud.box] - -Then, either go into the devcloudbox folder of your checked out -version of the CloudStack code (incubator-cloudstack/tools/devcloud/devcloudbox), -or copy the contents of that folder to another location. - -Assuming the patched Vagrant installation is working, you then -simply run "vagrant up" from within that directory. - diff --git a/tools/devcloud/devcloud.cfg b/tools/devcloud/devcloud.cfg index c0ea6c0b9f5..1a4b00cf23f 100644 --- a/tools/devcloud/devcloud.cfg +++ b/tools/devcloud/devcloud.cfg @@ -2,26 +2,46 @@ "zones": [ { "name": "DevCloud0", - "providers": [ + "physical_networks": [ { - "broadcastdomainrange": "ZONE", - "name": "VirtualRouter" + "broadcastdomainrange": "Zone", + "name": "test-network", + "traffictypes": [ + { + "typ": "Guest" + }, + { + "typ": "Management" + } + ], + "providers": [ + { + "broadcastdomainrange": "ZONE", + "name": "VirtualRouter" + }, + { + "broadcastdomainrange": "Pod", + "name": "SecurityGroupProvider" + } + ] } - ], + ], "dns2": "4.4.4.4", - "dns1": "8.8.8.8", + "dns1": "8.8.8.8", + "securitygroupenabled": "true", + "localstorageenabled": "true", "networktype": "Basic", "pods": [ { - "endip": "10.0.2.220", + "endip": "192.168.56.220", "name": "test00", - "startip": "10.0.2.200", + "startip": "192.168.56.200", "guestIpRanges": [ { - "startip": "10.0.2.100", - "endip": "10.0.2.199", + "startip": "192.168.56.100", + "endip": "192.168.56.199", "netmask": "255.255.255.0", - "gateway": "10.0.2.2" + "gateway": "192.168.56.1" } ], "netmask": "255.255.255.0", @@ -32,32 +52,24 @@ "hosts": [ { "username": "root", - "url": "http://10.0.2.15/", + "url": "http://192.168.56.2/", "password": "password" } ], "clustertype": "CloudManaged" } ], - "gateway": "10.0.2.2" + "gateway": "192.168.56.1" } ], - "internaldns1": "10.0.2.3", - "internaldns2": "10.0.2.3", + "internaldns1": "192.168.56.1", "secondaryStorages": [ { - "url": "nfs://10.0.2.15/opt/storage/secondary" + "url": "nfs://192.168.56.2:/opt/storage/secondary" } ] } ], - "dbSvr": { - "dbSvr": "localhost", - "passwd": "cloud", - "db": "cloud", - "port": 3306, - "user": "cloud" - }, "logger": [ { "name": "TestClient", @@ -80,6 +92,22 @@ { "name": "expunge.interval", "value": "60" + }, + { + "name":"enable.ec2.api", + "value":"true" + }, + { + "name":"system.vm.use.local.storage", + "value":"true" + }, + { + "name":"enable.s3.api", + "value":"true" + }, + { + "name":"host", + "value":"192.168.56.1" } ], "mgtSvr": [ @@ -87,5 +115,13 @@ "mgtSvrIp": "127.0.0.1", "port": 8096 } - ] + ], + "dbSvr": + { + "dbSvr": "127.0.0.1", + "port": 3306, + "user": "cloud", + "passwd": "cloud", + "db": "cloud" + } } diff --git a/setup/db/clouddev.sql b/tools/devcloud/devcloud.sql similarity index 59% rename from setup/db/clouddev.sql rename to tools/devcloud/devcloud.sql index 10ad3b2513e..6bcbcf7e6c5 100644 --- a/setup/db/clouddev.sql +++ b/tools/devcloud/devcloud.sql @@ -16,18 +16,17 @@ -- under the License. -UPDATE `cloud`.`configuration` SET value = 'true' where name = 'use.local.storage'; -UPDATE `cloud`.`configuration` SET value = 'true' where name = 'system.vm.use.local.storage'; -INSERT INTO `cloud`.`disk_offering` (id, name, uuid, display_text, created, use_local_storage, type) VALUES (17, 'tinyOffering', UUID(), 'tinyOffering', NOW(), 1, 'Service'); +INSERT INTO `cloud`.`disk_offering` (id, name, uuid, display_text, created, use_local_storage, type, disk_size) VALUES (17, 'tinyOffering', UUID(), 'tinyOffering', NOW(), 1, 'Service', 0); INSERT INTO `cloud`.`service_offering` (id, cpu, speed, ram_size) VALUES (17, 1, 100, 100); INSERT INTO `cloud`.`disk_offering` (id, name, uuid, display_text, created, type, disk_size) VALUES (18, 'tinyDiskOffering', UUID(), 'tinyDiskOffering', NOW(), 'Disk', 1073741824); -INSERT INTO `cloud`.`configuration` (name,value) VALUE('router.ram.size', '100'); -INSERT INTO `cloud`.`configuration` (name,value) VALUE('router.cpu.mhz','100'); -INSERT INTO `cloud`.`configuration` (name,value) VALUE('console.ram.size','100'); -INSERT INTO `cloud`.`configuration` (name,value) VALUE('console.cpu.mhz', '100'); -INSERT INTO `cloud`.`configuration` (name,value) VALUE('ssvm.ram.size','100'); -INSERT INTO `cloud`.`configuration` (name,value) VALUE('ssvm.cpu.mhz','100'); +INSERT INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','router.ram.size', '100'); +INSERT INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','router.cpu.mhz','100'); +INSERT INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','console.ram.size','100'); +INSERT INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','console.cpu.mhz', '100'); +INSERT INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','ssvm.ram.size','100'); +INSERT INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','ssvm.cpu.mhz','100'); +INSERT INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'system.vm.use.local.storage', 'true'); UPDATE `cloud`.`configuration` SET value='10' where name = 'storage.overprovisioning.factor'; UPDATE `cloud`.`configuration` SET value='10' where name = 'cpu.overprovisioning.factor'; UPDATE `cloud`.`configuration` SET value='10' where name = 'mem.overprovisioning.factor'; -UPDATE `cloud`.`vm_template` SET unique_name="tiny Linux",name="tiny Linux",url="http://nfs1.lab.vmops.com/templates/ttylinux_pv.vhd",checksum="046e134e642e6d344b34648223ba4bc1",display_text="tiny Linux" where id=5; +UPDATE `cloud`.`vm_template` SET unique_name="tiny Linux",name="tiny Linux",url="https://github.com/downloads/bhaisaab/incubator-cloudstack/ttylinux_pv.vhd",checksum="046e134e642e6d344b34648223ba4bc1",display_text="tiny Linux" where id=5; diff --git a/tools/devcloud/devcloudbox/puppet-devcloud/files/builddevcloud.sh b/tools/devcloud/devcloudbox/puppet-devcloud/files/builddevcloud.sh index 7755766ec3f..03bd854e015 100644 --- a/tools/devcloud/devcloudbox/puppet-devcloud/files/builddevcloud.sh +++ b/tools/devcloud/devcloudbox/puppet-devcloud/files/builddevcloud.sh @@ -18,5 +18,11 @@ # under the License. export CATALINA_HOME=/opt/cloudstack/apache-tomcat-6.0.32 +export M2_HOME=/opt/cloudstack/apache-maven-3.0.4 +export M2=$M2_HOME/bin +MAVEN_OPTS="-Xms256m -Xmx512m" +PATH=$M2:$PATH cd /opt/cloudstack/incubator-cloudstack/ +/usr/bin/mvn -P deps +/usr/bin/mvn clean /usr/bin/ant clean-all build-all deploy-server deploydb diff --git a/tools/gcc/gcc.sh b/tools/devcloud/devcloudbox/puppet-devcloud/files/installmaven.sh similarity index 53% rename from tools/gcc/gcc.sh rename to tools/devcloud/devcloudbox/puppet-devcloud/files/installmaven.sh index 91fea1ab8b8..48ffdfe8de7 100644 --- a/tools/gcc/gcc.sh +++ b/tools/devcloud/devcloudbox/puppet-devcloud/files/installmaven.sh @@ -1,4 +1,5 @@ -#!/usr/bin/env bash +#!/bin/sh + # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -16,25 +17,6 @@ # specific language governing permissions and limitations # under the License. - -usage() { - printf "Usage:\n %s [source directory where the java script files are] [destination directory to put the result] \n" $(basename $0) >&2 -} - -if [ $# -ne 2 ]; then - usage - exit 2; -fi - -set -x - -jsfiles="--js $1/jquery-1.4.min.js --js $1/date.js " -for file in `ls -l $1/jquery*.js | grep -v jquery-1.4 | awk '{print $NF}'`; do - jsfiles=`echo $jsfiles "--js " $file` -done -jsfiles=`echo $jsfiles "--js $1/cloud.core.callbacks.js --js $1/cloud.core.js "` -for file in `ls -l $1/cloud*.js | egrep -v 'callback|core.js' | awk '{print $NF}'`; do - jsfiles=`echo $jsfiles "--js " $file` -done - -java -jar compiler.jar $jsfiles --js_output_file $2/cloud.core.min.js +cd /opt/cloudstack +/usr/bin/wget http://apache.mirrors.pair.com/maven/maven-3/3.0.4/binaries/apache-maven-3.0.4-bin.tar.gz +/bin/tar xvfz apache-maven-3.0.4-bin.tar.gz diff --git a/tools/devcloud/devcloudbox/puppet-devcloud/manifests/init.pp b/tools/devcloud/devcloudbox/puppet-devcloud/manifests/init.pp index 5547ed3fefa..3dc74a18206 100644 --- a/tools/devcloud/devcloudbox/puppet-devcloud/manifests/init.pp +++ b/tools/devcloud/devcloudbox/puppet-devcloud/manifests/init.pp @@ -297,9 +297,26 @@ class puppet-devcloud { group => '0', } + file { '/opt/cloudstack/installmaven.sh': + ensure => 'file', + source => 'puppet:///modules/puppet-devcloud/installmaven.sh', + mode => '777', + owner => '0', + group => '0', + } + + exec { "install_maven": + require => File['/opt/cloudstack/installmaven.sh'], + command => '/opt/cloudstack/installmaven.sh', + cwd => '/opt/cloudstack', + creates => '/opt/cloudstack/apache-maven-3.0.4/', + timeout => '0', + } + exec { "build_cloudstack": require => [ Package['ant'], + Exec['install_maven'], Exec["catalina_home"], File['/opt/cloudstack/incubator-cloudstack/dist'], File['/opt/cloudstack/incubator-cloudstack/target'], diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml new file mode 100644 index 00000000000..5c532c90a1b --- /dev/null +++ b/tools/devcloud/pom.xml @@ -0,0 +1,138 @@ + + + 4.0.0 + cloud-devcloud + Apache CloudStack Developer Tools + pom + + org.apache.cloudstack + cloudstack + 4.1.0-SNAPSHOT + ../../pom.xml + + + + mysql + mysql-connector-java + 5.1.21 + runtime + + + + + install + + + + deploydb + + + deploydb + + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0-alpha-2 + + + initialize + + read-project-properties + + + + ${project.parent.basedir}/utils/conf/db.properties + ${project.parent.basedir}/utils/conf/db.properties.override + + true + + + + + + org.codehaus.mojo + sql-maven-plugin + 1.5 + + + + mysql + mysql-connector-java + ${cs.mysql.version} + + + + org.gjt.mm.mysql.Driver + jdbc:mysql://${db.cloud.host}:${db.cloud.port}/cloud + ${db.cloud.username} + ${db.cloud.password} + + ${maven.test.skip} + true + + + + create-schema + process-test-resources + + execute + + + + ${basedir}/devcloud.sql + + + + + + + + + + deploysvr + + + deploysvr + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + package + + exec + + + + + python + + ../marvin/marvin/deployDataCenter.py + -i + devcloud.cfg + + + + + + + + diff --git a/tools/devcloud/veewee/README b/tools/devcloud/veewee/README deleted file mode 100644 index c9299e504b4..00000000000 --- a/tools/devcloud/veewee/README +++ /dev/null @@ -1,5 +0,0 @@ -Install DevCloud Base system: -1. get code from https://github.com/jedi4ever/veewee, and install -2. veewee vbox define devcloud ubuntu-12.04-server-i386 -3. put these two files(definition.rb and preseed.cfg) under ./definition/devcloud/ -3. veewee vbox build devcloud diff --git a/tools/gcc/README b/tools/gcc/README deleted file mode 100644 index 8718f5b572f..00000000000 --- a/tools/gcc/README +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2009 Google Inc. - * - * 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. - */ - -// -// Contents -// - -The Closure Compiler performs checking, instrumentation, and -optimizations on JavaScript code. The purpose of this README is to -explain how to build and run the Closure Compiler. - -The Closure Compiler requires Java 6 or higher. -http://www.java.com/ - - -// -// Building The Closure Compiler -// - -There are three ways to get a Closure Compiler executable. - -1) Use one we built for you. - -Pre-built Closure binaries can be found at -http://code.google.com/p/closure-compiler/downloads/list - - -2) Check out the source and build it with Apache Ant. - -First, check out the full source tree of the Closure Compiler. There -are instructions on how to do this at the project site. -http://code.google.com/p/closure-compiler/source/checkout - -Apache Ant is a cross-platform build tool. -http://ant.apache.org/ - -At the root of the source tree, there is an Ant file named -build.xml. To use it, navigate to the same directory and type the -command - -ant jar - -This will produce a jar file called "build/compiler.jar". - - -3) Check out the source and build it with Eclipse. - -Eclipse is a cross-platform IDE. -http://www.eclipse.org/ - -Under Eclipse's File menu, click "New > Project ..." and create a -"Java Project." You will see an options screen. Give the project a -name, select "Create project from existing source," and choose the -root of the checked-out source tree as the existing directory. Verify -that you are using JRE version 6 or higher. - -Eclipse can use the build.xml file to discover rules. When you -navigate to the build.xml file, you will see all the build rules in -the "Outline" pane. Run the "jar" rule to build the compiler in -build/compiler.jar. - - -// -// Running The Closure Compiler -// - -Once you have the jar binary, running the Closure Compiler is straightforward. - -On the command line, type - -java -jar compiler.jar - -This starts the compiler in interactive mode. Type - -var x = 17 + 25; - -then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux) -and "Enter" again. The Compiler will respond: - -var x=42; - -The Closure Compiler has many options for reading input from a file, -writing output to a file, checking your code, and running -optimizations. To learn more, type - -java -jar compiler.jar --help - -You can read more detailed documentation about the many flags at -http://code.google.com/closure/compiler/docs/gettingstarted_app.html - - -// -// Compiling Multiple Scripts -// - -If you have multiple scripts, you should compile them all together with -one compile command. - -java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js - -The Closure Compiler will concatenate the files in the order they're -passed at the command line. - -If you need to compile many, many scripts together, you may start to -run into problems with managing dependencies between scripts. You -should check out the Closure Library. It contains functions for -enforcing dependencies between scripts, and a tool called calcdeps.py -that knows how to give scripts to the Closure Compiler in the right -order. - -http://code.google.com/p/closure-library/ - -// -// Licensing -// - -Unless otherwise stated, all source files are licensed under -the Apache License, Version 2.0. - - ------ -Code under: -src/com/google/javascript/rhino -test/com/google/javascript/rhino - -URL: http://www.mozilla.org/rhino -Version: 1.5R3, with heavy modifications -License: Netscape Public License and MPL / GPL dual license - -Description: A partial copy of Mozilla Rhino. Mozilla Rhino is an -implementation of JavaScript for the JVM. The JavaScript parser and -the parse tree data structures were extracted and modified -significantly for use by Google's JavaScript compiler. - -Local Modifications: The packages have been renamespaced. All code not -relavant to parsing has been removed. A JSDoc parser and static typing -system have been added. - - ------ -Code in: -lib/libtrunk_rhino_parser_jarjared.jar - -Rhino -URL: http://www.mozilla.org/rhino -Version: Trunk -License: Netscape Public License and MPL / GPL dual license - -Description: Mozilla Rhino is an implementation of JavaScript for the JVM. - -Local Modifications: None. We've used JarJar to renamespace the code -post-compilation. See: -http://code.google.com/p/jarjar/ - - ------ -Code in: -lib/args4j_deploy.jar - -Args4j -URL: https://args4j.dev.java.net/ -Version: 2.0.9 -License: MIT - -Description: -args4j is a small Java class library that makes it easy to parse command line -options/arguments in your CUI application. - -Local Modifications: None. - - ------ -Code in: -lib/google_common_deploy.jar - -Guava Libraries -URL: http://code.google.com/p/guava-libraries/ -Version: Trunk -License: Apache License 2.0 - -Description: Google's core Java libraries. - -Local Modifications: None. - - ------ -Code in: -lib/hamcrest-core-1.1.jar - -Hamcrest -URL: http://code.google.com/p/hamcrest -License: BSD -License File: LICENSE - -Description: -Provides a library of matcher objects (also known as constraints or -predicates) allowing 'match' rules to be defined declaratively, to be used in -other frameworks. Typical scenarios include testing frameworks, mocking -libraries and UI validation rules. - -Local modifications: -The original jars contained both source code and compiled classes. - -hamcrest-core-1.1.jar just contains the compiled classes. - - ----- -Code in: -lib/junit.jar - -JUnit -URL: http://sourceforge.net/projects/junit/ -Version: 4.5 -License: Common Public License 1.0 - -Description: A framework for writing and running automated tests in Java. - -Local Modifications: None. - - ---- -Code in: -lib/protobuf_deploy.jar - -Protocol Buffers -URL: http://code.google.com/p/protobuf/ -Version: 2.2.0a -License: New BSD License - -Description: Supporting libraries for protocol buffers, -an encoding of structured data. - -Local Modifications: None - - ---- -Code in: -lib/ant_deploy.jar - -URL: http://ant.apache.org/bindownload.cgi -Version: 1.6.5 -License: Apache License 2.0 -Description: - Ant is a Java based build tool. In theory it is kind of like "make" - without make's wrinkles and with the full portability of pure java code. - -Local Modifications: - Modified apache-ant-1.6.5/bin/ant to look in the ant.runfiles directory diff --git a/tools/gcc/compiler.jar b/tools/gcc/compiler.jar deleted file mode 100644 index 851f5afef85..00000000000 Binary files a/tools/gcc/compiler.jar and /dev/null differ diff --git a/tools/git/prepare-commit-msg b/tools/git/prepare-commit-msg new file mode 100755 index 00000000000..1addb0e9239 --- /dev/null +++ b/tools/git/prepare-commit-msg @@ -0,0 +1,103 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first comments out the +# "Conflicts:" part of a merge commit. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +#case "$2,$3" in +# merge,) +# /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; + +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$1" ;; + +# *) ;; +#esac + +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +run_generic_commit () { +local file=$1 +cat < $file +################################# 80 chars ##################################### +# The following is an example of how to fill out the above form. Please limit +# your formatting to 80 cols. +# +# Summary: One line description of commit, followed by blank line +# +# Detail: Multi-line description, followed by blank line +# +# BUG-ID: CLOUDSTACK-9999 +# Reviewed-by: Bar Barlington , Foo McFooson +# Reported-by: Baz Bazelli +# Signed-off-by: You +# +$ORIGINAL +EOF + +SOB=$(git var GIT_AUTHOR_IDENT) + +sed -i "1s/^/################################# 80 chars #####################################\n\ +Summary: \n\n\ +Detail: \n\n\ +BUG-ID : \n\ +Reviewed-by: \n\ +Reported-by: \n\ +Signed-off-by: ${SOB}\n\n/" $file + +} + +case "$2,$3" in + merge,*) + ;; + + template,*) + ;; + + message,*) + ;; + + squash,*) + ;; + + *) + run_generic_commit $1 + ;; +esac + diff --git a/tools/guest_password/cloud-set-guest-password b/tools/guest_password/cloud-set-guest-password new file mode 100644 index 00000000000..3da0ff36191 --- /dev/null +++ b/tools/guest_password/cloud-set-guest-password @@ -0,0 +1,116 @@ +#!/bin/bash +# +# Init file for Password Download Client +# +# chkconfig: 345 98 02 +# description: Password Download Client + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + + +# Modify this line to specify the user (default is root) +user=root + +# Add your DHCP lease folders here +DHCP_FOLDERS="/var/lib/dhclient/* /var/lib/dhcp3/* /var/lib/dhcp/*" +password_received=0 +file_count=0 +error_count=0 + +for DHCP_FILE in $DHCP_FOLDERS +do + if [ -f $DHCP_FILE ] + then + file_count=$((file_count+1)) + PASSWORD_SERVER_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;') + + if [ -n $PASSWORD_SERVER_IP ] + then + logger -t "cloud" "Found password server IP $PASSWORD_SERVER_IP in $DHCP_FILE" + logger -t "cloud" "Sending request to password server at $PASSWORD_SERVER_IP" + password=$(wget -q -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $PASSWORD_SERVER_IP:8080) + password=$(echo $password | tr -d '\r') + + if [ $? -eq 0 ] + then + logger -t "cloud" "Got response from server at $PASSWORD_SERVER_IP" + + case $password in + + "") logger -t "cloud" "Password server at $PASSWORD_SERVER_IP did not have any password for the VM" + continue + ;; + + "bad_request") logger -t "cloud" "VM sent an invalid request to password server at $PASSWORD_SERVER_IP" + error_count=$((error_count+1)) + continue + ;; + + "saved_password") logger -t "cloud" "VM has already saved a password from the password server at $PASSWORD_SERVER_IP" + continue + ;; + + *) logger -t "cloud" "VM got a valid password from server at $PASSWORD_SERVER_IP" + password_received=1 + break + ;; + + esac + else + logger -t "cloud" "Failed to send request to password server at $PASSWORD_SERVER_IP" + error_count=$((error_count+1)) + fi + else + logger -t "cloud" "Could not find password server IP in $DHCP_FILE" + error_count=$((error_count+1)) + fi + fi +done + +if [ "$password_received" == "0" ] +then + if [ "$error_count" == "$file_count" ] + then + logger -t "cloud" "Failed to get password from any server" + exit 1 + else + logger -t "cloud" "Did not need to change password." + exit 0 + fi +fi + +logger -t "cloud" "Changing password ..." +echo $user:$password | chpasswd + +if [ $? -gt 0 ] +then + usermod -p `mkpasswd -m SHA-512 $password` $user + + if [ $? -gt 0 ] + then + logger -t "cloud" "Failed to change password for user $user" + exit 1 + else + logger -t "cloud" "Successfully changed password for user $user" + fi +fi + +logger -t "cloud" "Sending acknowledgment to password server at $PASSWORD_SERVER_IP" +wget -t 3 -T 20 -O - --header "DomU_Request: saved_password" $PASSWORD_SERVER_IP:8080 +exit 0 + diff --git a/tools/marvin/DISCLAIMER.txt b/tools/marvin/DISCLAIMER.txt new file mode 100644 index 00000000000..fa1e9261a36 --- /dev/null +++ b/tools/marvin/DISCLAIMER.txt @@ -0,0 +1,7 @@ +Apache CloudStack is an effort undergoing incubation at The Apache Software Foundation (ASF), +sponsored by the Apache Incubator. Incubation is required of all newly accepted +projects until a further review indicates that the infrastructure, communications, and +decision making process have stabilized in a manner consistent with other successful ASF +projects. While incubation status is not necessarily a reflection of the completeness or +stability of the code, it does indicate that the project has yet to be fully endorsed by +the ASF. diff --git a/tools/marvin/LICENSE.txt b/tools/marvin/LICENSE.txt index 00ae6c00d2e..d9a10c0d8e8 100644 --- a/tools/marvin/LICENSE.txt +++ b/tools/marvin/LICENSE.txt @@ -1,17 +1,176 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/tools/marvin/README b/tools/marvin/README deleted file mode 100644 index 785f078804b..00000000000 --- a/tools/marvin/README +++ /dev/null @@ -1,18 +0,0 @@ -Marvin is the testing framework for CloudStack written in python. Writing of -unittests and functional tests with Marvin makes testing with cloudstack easier - -1. INSTALL - untar Marvin-0.1.0.tar.gz - cd Marvin-0.1.0 - python setup.py install - -2. Facility it provides: - 1. very handy cloudstack API python wrapper - 2. support async job executing in parallel - 3. remote ssh login/execute command - 4. mysql query - -3. sample code is under sandbox - -4. WIKI page - https://cwiki.apache.org/confluence/display/CLOUDSTACK/Testing+with+Python diff --git a/tools/marvin/marvin/TestCaseExecuteEngine.py b/tools/marvin/marvin/TestCaseExecuteEngine.py index 44a44aa141c..63e7d0de6aa 100644 --- a/tools/marvin/marvin/TestCaseExecuteEngine.py +++ b/tools/marvin/marvin/TestCaseExecuteEngine.py @@ -27,13 +27,14 @@ def testCaseLogger(message, logger=None): logger.debug(message) class TestCaseExecuteEngine(object): - def __init__(self, testclient, testcaseLogFile=None, testResultLogFile=None, format="text", xmlDir="xml-reports"): + def __init__(self, testclient, config, testcaseLogFile=None, testResultLogFile=None, format="text", xmlDir="xml-reports"): """ Initialize the testcase execution engine, just the basics here @var testcaseLogFile: client log file @var testResultLogFile: summary report file """ self.testclient = testclient + self.config = config self.logformat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") self.loader = unittest.loader.TestLoader() self.suite = None @@ -83,6 +84,7 @@ class TestCaseExecuteEngine(object): #inject testclient and logger into each unittest setattr(test, "testClient", self.testclient) + setattr(test, "config", self.config) setattr(test, "debug", partial(testCaseLogger, logger=testcaselogger)) setattr(test.__class__, "clstestclient", self.testclient) if hasattr(test, "UserName"): diff --git a/tools/marvin/marvin/dbConnection.py b/tools/marvin/marvin/dbConnection.py index 1992f801428..8fa86438ab0 100644 --- a/tools/marvin/marvin/dbConnection.py +++ b/tools/marvin/marvin/dbConnection.py @@ -15,59 +15,39 @@ # specific language governing permissions and limitations # under the License. -import pymysql +import mysql +import contextlib +from mysql import connector +from mysql.connector import errors +from contextlib import closing import cloudstackException import sys import os -import traceback + class dbConnection(object): def __init__(self, host="localhost", port=3306, user='cloud', passwd='cloud', db='cloud'): self.host = host self.port = port - self.user = user + self.user = str(user) #Workaround: http://bugs.mysql.com/?id=67306 self.passwd = passwd self.database = db - try: - self.db = pymysql.Connect(host=host, port=port, user=user, passwd=passwd, db=db) - except: - traceback.print_exc() - raise cloudstackException.InvalidParameterException(sys.exc_info()) - - def __copy__(self): - return dbConnection(self.host, self.port, self.user, self.passwd, self.database) - - def close(self): - try: - self.db.close() - except: - pass - - def execute(self, sql=None): + def execute(self, sql=None, params=None): if sql is None: return None - + resultRow = [] - cursor = None - try: - # commit to restart the transaction, else we don't get fresh data - self.db.commit() - cursor = self.db.cursor() - cursor.execute(sql) - - result = cursor.fetchall() - if result is not None: - for r in result: - resultRow.append(r) - return resultRow - except pymysql.MySQLError, e: - raise cloudstackException.dbException("db Exception:%s"%e) - except: - raise cloudstackException.internalError(sys.exc_info()) - finally: - if cursor is not None: - cursor.close() - + with contextlib.closing(mysql.connector.connect(host=self.host, port=self.port, user=self.user, password=self.passwd, db=self.database)) as conn: + conn.autocommit = True + with contextlib.closing(conn.cursor(buffered=True)) as cursor: + cursor.execute(sql, params) + try: + resultRow = cursor.fetchall() + except errors.InterfaceError: + #Raised on empty result - DML + resultRow = [] + return resultRow + def executeSqlFromFile(self, fileName=None): if fileName is None: raise cloudstackException.InvalidParameterException("file can't not none") diff --git a/tools/marvin/marvin/deployAndRun.py b/tools/marvin/marvin/deployAndRun.py index 1c82d9fcc2e..e7b005caf68 100644 --- a/tools/marvin/marvin/deployAndRun.py +++ b/tools/marvin/marvin/deployAndRun.py @@ -46,21 +46,30 @@ if __name__ == "__main__": else: deploy.deploy() - format = "text" + fmt = "text" xmlDir = None if options.xmlrunner is not None: xmlDir = options.xmlrunner - format = "xml" + fmt = "xml" if options.testCaseFolder is None: if options.module is None: parser.print_usage() exit(1) else: - engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir) + engine = \ + TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, + deploy.getCfg(), + testCaseLogFile, + testResultLogFile, fmt, + xmlDir) engine.loadTestsFromFile(options.module) engine.run() else: - engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir) + engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, + deploy.getCfg(), + testCaseLogFile, + testResultLogFile, + fmt, xmlDir) engine.loadTestsFromDir(options.testCaseFolder) engine.run() diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index 571d5a4ff72..bdf08cc2d2d 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -349,6 +349,11 @@ class deployDataCenters(): self.config.mgtSvr[0].securityKey = securityKey return apiKey, securityKey + def getCfg(self): + if self.config is not None: + return self.config + return None + def loadCfg(self): try: self.config = configGenerator.get_setup_config(self.configFile) diff --git a/tools/marvin/marvin/integration/__init__.py b/tools/marvin/marvin/integration/__init__.py new file mode 100644 index 00000000000..57823fcc162 --- /dev/null +++ b/tools/marvin/marvin/integration/__init__.py @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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/test/integration/lib/__init__.py b/tools/marvin/marvin/integration/lib/__init__.py similarity index 100% rename from test/integration/lib/__init__.py rename to tools/marvin/marvin/integration/lib/__init__.py diff --git a/test/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py similarity index 100% rename from test/integration/lib/base.py rename to tools/marvin/marvin/integration/lib/base.py diff --git a/test/integration/lib/common.py b/tools/marvin/marvin/integration/lib/common.py similarity index 100% rename from test/integration/lib/common.py rename to tools/marvin/marvin/integration/lib/common.py diff --git a/test/integration/lib/utils.py b/tools/marvin/marvin/integration/lib/utils.py similarity index 100% rename from test/integration/lib/utils.py rename to tools/marvin/marvin/integration/lib/utils.py diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py index 0251e96a2bb..01fbd6e39b1 100644 --- a/tools/marvin/marvin/marvinPlugin.py +++ b/tools/marvin/marvin/marvinPlugin.py @@ -58,6 +58,7 @@ class MarvinPlugin(Plugin): deploy = deployDataCenter.deployDataCenters(options.config) deploy.loadCfg() if options.load else deploy.deploy() self.setClient(deploy.testClient) + self.setConfig(deploy.getCfg()) cfg = nose.config.Config() cfg.logStream = self.result_stream @@ -101,9 +102,13 @@ class MarvinPlugin(Plugin): self._injectClients(cls) def setClient(self, client): - if client: + if client is not None: self.testclient = client + def setConfig(self, config): + if config is not None: + self.config = config + def _injectClients(self, test): testcaselogger = logging.getLogger("testclient.testcase.%s" % test.__name__) self.debug_stream.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s")) @@ -111,6 +116,7 @@ class MarvinPlugin(Plugin): testcaselogger.setLevel(logging.DEBUG) setattr(test, "testClient", self.testclient) + setattr(test, "config", self.config) setattr(test, "debug", partial(testCaseLogger, logger=testcaselogger)) setattr(test, "clstestclient", self.testclient) if hasattr(test, "UserName"): diff --git a/tools/marvin/marvin/remoteSSHClient.py b/tools/marvin/marvin/remoteSSHClient.py index 60df2a744d7..036e1c381e1 100644 --- a/tools/marvin/marvin/remoteSSHClient.py +++ b/tools/marvin/marvin/remoteSSHClient.py @@ -18,6 +18,8 @@ import paramiko import time import cloudstackException +import contextlib +from contextlib import closing class remoteSSHClient(object): def __init__(self, host, port, user, passwd, retries = 10): @@ -67,8 +69,11 @@ class remoteSSHClient(object): except IOError, e: raise e + def close(self): + self.ssh.close() + if __name__ == "__main__": - ssh = remoteSSHClient("192.168.137.2", 22, "root", "password") - print ssh.execute("ls -l") - print ssh.execute("rm x") + with contextlib.closing(remoteSSHClient("10.223.75.10", 22, "root", + "password")) as ssh: + print ssh.execute("ls -l") diff --git a/tools/marvin/marvin/sandbox/README.txt b/tools/marvin/marvin/sandbox/README.txt deleted file mode 100644 index bb4d35e10e3..00000000000 --- a/tools/marvin/marvin/sandbox/README.txt +++ /dev/null @@ -1,30 +0,0 @@ -Welcome to the marvin sandbox ----------------------------------- - -In here you should find a few common deployment models of CloudStack that you -can configure with properties files to suit your own deployment. One deployment -model for each of - advanced zone, basic zone and a simulator demo are given. - -$ ls - -basic/ -advanced/ -simulator/ - -Each property file is divided into logical sections and should be familiar to -those who have deployed CloudStack before. Once you have your properties file -you will have to create a JSON configuration of your deployment using the -python script provided in the respective folder. - -The demo files are from the tutorial for testing with python that can be found at - https://cwiki.apache.org/confluence/display/CLOUDSTACK/Testing+with+Python - -A common deployment model of a simulator.cfg that can be used for debugging is -included. This will configure an advanced zone with simulators that can be used -for debugging purposes when you do not have hardware to debug with. - -To do this: -$ cd cloudstack-oss/ -$ ant run-simulator #This will start up the mgmt server with the simulator seeded - -## In another shell -$ ant run-simulator diff --git a/tools/marvin/marvin/sandbox/advanced/advanced_env.py b/tools/marvin/marvin/sandbox/advanced/advanced_env.py index 136629fe944..1873f31d50f 100644 --- a/tools/marvin/marvin/sandbox/advanced/advanced_env.py +++ b/tools/marvin/marvin/sandbox/advanced/advanced_env.py @@ -101,6 +101,8 @@ def describeResources(config): '''Add mgt server''' mgt = managementServer() mgt.mgtSvrIp = config.get('environment', 'mshost') + mgt.user = config.get('environment', 'mshost.user') + mgt.passwd = config.get('environment', 'mshost.passwd') zs.mgtSvr.append(mgt) '''Add a database''' diff --git a/tools/marvin/marvin/sandbox/advanced/setup.properties b/tools/marvin/marvin/sandbox/advanced/setup.properties index 966d1f9a52c..ba44d5146b6 100644 --- a/tools/marvin/marvin/sandbox/advanced/setup.properties +++ b/tools/marvin/marvin/sandbox/advanced/setup.properties @@ -36,6 +36,8 @@ secstorage.allowed.internal.sites=10.147.28.0/24 [environment] dns=10.147.28.6 mshost=10.147.29.111 +mshost.user=root +mshost.passwd=password mysql.host=10.147.29.111 mysql.cloud.user=cloud mysql.cloud.passwd=cloud diff --git a/tools/marvin/marvin/sandbox/advanced/tests/test_scenarios.py b/tools/marvin/marvin/sandbox/advanced/tests/test_scenarios.py deleted file mode 100644 index 7f552c33615..00000000000 --- a/tools/marvin/marvin/sandbox/advanced/tests/test_scenarios.py +++ /dev/null @@ -1,145 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - - - -#!/usr/bin/env python -try: - import unittest2 as unittest -except ImportError: - import unittest - -import random -import hashlib -from cloudstackTestCase import * -import remoteSSHClient - -class SampleScenarios(cloudstackTestCase): - ''' - ''' - def setUp(self): - pass - - - def tearDown(self): - pass - - - def test_1_createAccounts(self, numberOfAccounts=2): - ''' - Create a bunch of user accounts - ''' - mdf = hashlib.md5() - mdf.update('password') - mdf_pass = mdf.hexdigest() - api = self.testClient.getApiClient() - for i in range(1, numberOfAccounts + 1): - acct = createAccount.createAccountCmd() - acct.accounttype = 0 - acct.firstname = 'user' + str(i) - acct.lastname = 'user' + str(i) - acct.password = mdf_pass - acct.username = 'user' + str(i) - acct.email = 'user@example.com' - acct.account = 'user' + str(i) - acct.domainid = 1 - acctResponse = api.createAccount(acct) - self.debug("successfully created account: %s, user: %s, id: %s"%(acctResponse.account, acctResponse.username, acctResponse.id)) - - - def test_2_createServiceOffering(self): - apiClient = self.testClient.getApiClient() - createSOcmd=createServiceOffering.createServiceOfferingCmd() - createSOcmd.name='Sample SO' - createSOcmd.displaytext='Sample SO' - createSOcmd.storagetype='shared' - createSOcmd.cpunumber=1 - createSOcmd.cpuspeed=100 - createSOcmd.memory=128 - createSOcmd.offerha='false' - createSOresponse = apiClient.createServiceOffering(createSOcmd) - return createSOresponse.id - - def deployCmd(self, account, service): - deployVmCmd = deployVirtualMachine.deployVirtualMachineCmd() - deployVmCmd.zoneid = 1 - deployVmCmd.account=account - deployVmCmd.domainid=1 - deployVmCmd.templateid=2 - deployVmCmd.serviceofferingid=service - return deployVmCmd - - def listVmsInAccountCmd(self, acct): - api = self.testClient.getApiClient() - listVmCmd = listVirtualMachines.listVirtualMachinesCmd() - listVmCmd.account = acct - listVmCmd.zoneid = 1 - listVmCmd.domainid = 1 - listVmResponse = api.listVirtualMachines(listVmCmd) - return listVmResponse - - - def destroyVmCmd(self, key): - api = self.testClient.getApiClient() - destroyVmCmd = destroyVirtualMachine.destroyVirtualMachineCmd() - destroyVmCmd.id = key - api.destroyVirtualMachine(destroyVmCmd) - - - def test_3_stressDeploy(self): - ''' - Deploy 5 Vms in each account - ''' - service_id = self.test_2_createServiceOffering() - api = self.testClient.getApiClient() - for acct in range(1, 5): - [api.deployVirtualMachine(self.deployCmd('user'+str(acct), service_id)) for x in range(0,5)] - - @unittest.skip("skipping destroys") - def test_4_stressDestroy(self): - ''' - Cleanup all Vms in every account - ''' - api = self.testClient.getApiClient() - for acct in range(1, 6): - for vm in self.listVmsInAccountCmd('user'+str(acct)): - if vm is not None: - self.destroyVmCmd(vm.id) - - @unittest.skip("skipping destroys") - def test_5_combineStress(self): - for i in range(0, 5): - self.test_3_stressDeploy() - self.test_4_stressDestroy() - - def deployN(self,nargs=300,batchsize=0): - ''' - Deploy Nargs number of VMs concurrently in batches of size {batchsize}. - When batchsize is 0 all Vms are deployed in one batch - VMs will be deployed in 5:2:6 ratio - ''' - cmds = [] - - if batchsize == 0: - self.testClient.submitCmdsAndWait(cmds) - else: - while len(z) > 0: - try: - newbatch = [cmds.pop() for b in range(batchsize)] #pop batchsize items - self.testClient.submitCmdsAndWait(newbatch) - except IndexError: - break diff --git a/tools/marvin/marvin/sandbox/basic/basic_env.py b/tools/marvin/marvin/sandbox/basic/basic_env.py index 7c2a0b1d957..e588fdcc882 100644 --- a/tools/marvin/marvin/sandbox/basic/basic_env.py +++ b/tools/marvin/marvin/sandbox/basic/basic_env.py @@ -102,6 +102,8 @@ def describeResources(config): '''Add mgt server''' mgt = managementServer() mgt.mgtSvrIp = config.get('environment', 'mshost') + mgt.user = config.get('environment', 'mshost.user') + mgt.passwd = config.get('environment', 'mshost.passwd') zs.mgtSvr.append(mgt) '''Add a database''' diff --git a/tools/marvin/marvin/sandbox/basic/setup.properties b/tools/marvin/marvin/sandbox/basic/setup.properties index e9c0f4d70e3..8833b507252 100644 --- a/tools/marvin/marvin/sandbox/basic/setup.properties +++ b/tools/marvin/marvin/sandbox/basic/setup.properties @@ -36,6 +36,8 @@ secstorage.allowed.internal.sites=10.147.28.0/24 [environment] dns=10.147.28.6 mshost=10.147.39.69 +mshost.user=root +mshost.passwd=password mysql.host=10.147.39.69 mysql.cloud.user=cloud mysql.cloud.passwd=cloud diff --git a/tools/marvin/marvin/sandbox/demo/live/README b/tools/marvin/marvin/sandbox/demo/live/README deleted file mode 100644 index 8ca0f4cf763..00000000000 --- a/tools/marvin/marvin/sandbox/demo/live/README +++ /dev/null @@ -1,8 +0,0 @@ - -Download Marvin source from hudson - -Install Marvin: -pip install Marvin-0.1.0.tar.gz - -To Run the test: -python -m marvin.deployAndRun -c demo.cfg -t /tmp/t.log -r /tmp/r.log -f testSshDeployVM.py -l diff --git a/tools/marvin/marvin/sandbox/demo/simulator/README b/tools/marvin/marvin/sandbox/demo/simulator/README deleted file mode 100644 index d34ca9f80ec..00000000000 --- a/tools/marvin/marvin/sandbox/demo/simulator/README +++ /dev/null @@ -1,12 +0,0 @@ -To generate the config -Alter the .properties file to point to your simulator installed environment - -python simulator_setup.py -i simulatordemo.properties -o simulatordemo.cfg - - -To deploy the environment and run the tests - -python -m marvin.deployAndRun -c simulatordemo.cfg -t /tmp/t.log -r /tmp/r.log -d testcase - - - diff --git a/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg b/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg index 7d250c84ec0..219c4dbbff5 100644 --- a/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg +++ b/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg @@ -16,7 +16,6 @@ # under the License. - { "zones": [ { @@ -193,6 +192,8 @@ "mgtSvr": [ { "mgtSvrIp": "localhost", + "passwd": "password", + "user": "root", "port": 8096 } ] diff --git a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py index 2bd52f14345..0d341408aea 100644 --- a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py +++ b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py @@ -103,6 +103,8 @@ def describeResources(config): '''Add mgt server''' mgt = managementServer() mgt.mgtSvrIp = config.get('environment', 'mshost') + mgt.user = config.get('environment', 'mshost.user') + mgt.passwd = config.get('environment', 'mshost.passwd') zs.mgtSvr.append(mgt) '''Add a database''' diff --git a/tools/marvin/marvin/sandbox/demo/simulator/simulatordemo.properties b/tools/marvin/marvin/sandbox/demo/simulator/simulatordemo.properties index aa3deb0afa1..9d9f14b70a4 100644 --- a/tools/marvin/marvin/sandbox/demo/simulator/simulatordemo.properties +++ b/tools/marvin/marvin/sandbox/demo/simulator/simulatordemo.properties @@ -37,6 +37,8 @@ secstorage.allowed.internal.sites=10.147.28.0/24 [environment] dns=10.147.28.6 mshost=localhost +mshost.user=root +mshost.passwd=password mysql.host=localhost mysql.cloud.user=cloud mysql.cloud.passwd=cloud diff --git a/tools/marvin/marvin/sandbox/run-marvin.sh b/tools/marvin/marvin/sandbox/run-marvin.sh old mode 100644 new mode 100755 diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml new file mode 100644 index 00000000000..51c70cd92b8 --- /dev/null +++ b/tools/marvin/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + cloud-marvin + Apache CloudStack Developer Tools: marvin + pom + + org.apache.cloudstack + cloudstack + 4.1.0-SNAPSHOT + ../../pom.xml + + + + install + + + maven-antrun-plugin + 1.7 + + + generate-resource + generate-resources + + run + + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + compile + compile + + exec + + + marvin + python + + codegenerator.py + -s + ${basedir}/../apidoc/target/commands.xml + + + + + package + package + + exec + + + ${exec.workingdir} + python + + setup.py + sdist + + + + + deploy + deploy + + exec + + + dist + pip + + install + Marvin-0.1.0.tar.gz + + + + + + + + diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index c9841f31f3b..a9621bdae2e 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -16,7 +16,7 @@ # specific language governing permissions and limitations # under the License. -from distutils.core import setup +from setuptools import setup from sys import version import sys @@ -34,10 +34,12 @@ setup(name="Marvin", long_description="Marvin is the cloudstack testclient written around the python unittest framework", platforms=("Any",), url="http://jenkins.cloudstack.org:8080/job/marvin", - packages=["marvin", "marvin.cloudstackAPI", "marvin.sandbox", "marvin.sandbox.advanced", "marvin.sandbox.basic"], + packages=["marvin", "marvin.cloudstackAPI", "marvin.integration", + "marvin.integration.lib", "marvin.sandbox", + "marvin.sandbox.advanced", "marvin.sandbox.basic"], license="LICENSE.txt", install_requires=[ - "pymysql", + "mysql-connector-python", "paramiko", "nose", "unittest-xml-reporting" diff --git a/tools/whisker/descriptor.xml b/tools/whisker/descriptor.xml index b927bfc9528..0c573e38c6e 100644 --- a/tools/whisker/descriptor.xml +++ b/tools/whisker/descriptor.xml @@ -16,32 +16,6 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - - - - - - + name='Mozilla Public License, Version 1.0' + id='MPL1' + url='http://www.mozilla.org/MPL/1.1/' > + + MOZILLA PUBLIC LICENSE Version 1.1 @@ -912,7 +886,7 @@ EXHIBIT A -Mozilla Public License. use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] - + - + name='ANTLR 2 License' + id='antlr2' + url='http://www.antlr2.org/license.html'> + ANTLR 2 License We reserve no legal rights to the ANTLR--it is fully in the public domain. An @@ -1471,13 +1445,13 @@ mention that you developed it using ANTLR. In addition, we ask that the headers remain intact in our source code. As long as these guidelines are kept, we expect to continue enhancing this system and expect to make other tools available as they are completed. - + - + name='Dom4J License' + id='dom4j.license' + url='http://dom4j.cvs.sourceforge.net/viewvc/dom4j/dom4j/LICENSE.txt'> + Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved. Redistribution and use of this software and associated documentation @@ -1518,7 +1492,7 @@ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + - + + ========================================================================= == NOTICE file corresponding to section 4(d) of the Apache License, == == Version 2.0, in this case for the Apache Xerces Java distribution. == @@ -2248,8 +2222,8 @@ Portions of this software were originally based on the following: - voluntary contributions made by Paul Eng on behalf of the Apache Software Foundation that were originally developed at iClick, Inc., software copyright (c) 1999. - - + + ========================================================================= == NOTICE file corresponding to section 4(d) of the Apache License, == == Version 2.0, in this case for the Apache xml-commons xml-apis == @@ -2266,8 +2240,8 @@ Portions of this software were originally based on the following: - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. - software copyright (c) 1999, Sun Microsystems., http://www.sun.com. - software copyright (c) 2000 World Wide Web Consortium, http://www.w3.org - - + + Apache Rampart Copyright 2010 The Apache Software Foundation @@ -2277,12 +2251,26 @@ The Apache Software Foundation (http://www.apache.org/). Please read the different LICENSE files present in the lib directory of this distribution. + +Apache WebServices - WSS4J +Copyright 2004-2011 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +This product includes software Copyright University of Southampton IT +Innovation Centre, 2006 (http://www.it-innovation.soton.ac.uk). + + + id='openstack.org' + name='OpenStack, LLC' + url='http://www.openstack.org' /> + id='antlr2.org' + name='ANTLR Translator Generator Project' + url='http://www.antlr2.org/' /> + id='qos.ch' + name='QOS.ch' + url='http://www.qos.ch/' /> + id='dom4j.sourceforge.net' + name='DOM4J Project' + url='http://dom4j.sourceforge.net/' /> + id='json-simple' + name='Json.simple Project' + url='http://code.google.com/p/json-simple/' /> + id='junit.org' + name='JUnit Project' + url='http://www.junit.org/' /> + id='person:shigeru.chiba' + name='Shigeru Chiba' + url='http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/' /> + + + + + Copyright (c) 2012 The Apache Software Foundation @@ -2427,13 +2435,53 @@ The Apache Software Foundation (http://www.apache.org/). -Copyright © 2005-2010 Thomas Nagy +Copyright (c) 2005-2010 Thomas Nagy + + + +Copyright (c) 2012 The Apache Software Foundation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2448,7 +2496,7 @@ All rights reserved. -Copyright © 2009, John Resig +Copyright (c) 2009, John Resig @@ -2456,9 +2504,17 @@ Copyright © 2009, John Resig + + +Copyright (c) 2006 Google Inc. + + + + + -Copyright © 2011, John Resig +Copyright (c) 2011, John Resig @@ -2466,7 +2522,7 @@ Copyright © 2011, John Resig -Copyright © 2006 - 2011 Jörn Zaefferer +Copyright (c) 2006 - 2011 Jörn Zaefferer @@ -2474,7 +2530,7 @@ Copyright © 2006 - 2011 Jörn Zaefferer -Copyright © 2010, Sebastian Tschan +Copyright (c) 2010, Sebastian Tschan @@ -2482,7 +2538,7 @@ Copyright © 2010, Sebastian Tschan -Copyright © 2006 Klaus Hartl (stilbuero.de) +Copyright (c) 2006 Klaus Hartl (stilbuero.de) @@ -2490,7 +2546,7 @@ Copyright © 2006 Klaus Hartl (stilbuero.de) -Copyright © 2008 George McGinley Smith +Copyright (c) 2008 George McGinley Smith All rights reserved. @@ -2549,9 +2605,9 @@ Updated November 2009 with contributions from: btburnett3, Anthony Aragues and X - -Copyright © 2012 John Resig, Jörn Zaefferer - + +Copyright (c) 2012 John Resig, Jörn Zaefferer + @@ -2561,7 +2617,7 @@ Copyright © 2012 John Resig, Jörn Zaefferer -Copyright © 2005-2010 Thomas Nagy +Copyright (c) 2005-2010 Thomas Nagy @@ -2571,7 +2627,7 @@ Copyright © 2005-2010 Thomas Nagy -Copyright © 2004 Clinton Begin +Copyright (c) 2004 Clinton Begin ` @@ -2579,11 +2635,21 @@ Copyright © 2004 Clinton Begin + + +Copyright (C) 2008 Tóth István <stoty@tvnet.hu> + 2008-2012 Daniel Veillard <veillard@redhat.com> + 2009-2011 Bryan Kearney <bkearney@redhat.com> + + + + + -Copyright © 2012 The Apache Software Foundation +Copyright (c) 2012 The Apache Software Foundation - + @@ -2603,9 +2669,9 @@ Copyright © 2012 The Apache Software Foundation -Copyright © 2012 The Apache Software Foundation +Copyright (c) 2012 The Apache Software Foundation - + @@ -2619,7 +2685,7 @@ Copyright (c) 2007-2010, The JASYPT team (http://www.jasypt.org) -Copyright © 2003-2007 Luck Consulting Pty Ltd +Copyright (c) 2003-2007 Luck Consulting Pty Ltd @@ -2627,7 +2693,7 @@ Copyright © 2003-2007 Luck Consulting Pty Ltd -Copyright © 2006 Sun Microsystems, Inc. All rights reserved. +Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. @@ -2636,7 +2702,7 @@ Copyright © 2006 Sun Microsystems, Inc. All rights reserved. -Copyright © 1997-2010 Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. @@ -2644,7 +2710,7 @@ Copyright © 1997-2010 Oracle and/or its affiliates. All rights reserved. -Copyright © 2009 Google Inc. +Copyright (c) 2009 Google Inc. @@ -2652,7 +2718,7 @@ Copyright © 2009 Google Inc. -Copyright © 2012 The Eclipse Foundation. +Copyright (c) 2012 The Eclipse Foundation. @@ -2660,7 +2726,7 @@ Copyright © 2012 The Eclipse Foundation. -Copyright © 2009, Caringo, Inc. +Copyright (c) 2009, Caringo, Inc. @@ -2668,7 +2734,7 @@ Copyright © 2009, Caringo, Inc. -Copyright © 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. +Copyright (c) 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. @@ -2676,7 +2742,7 @@ Copyright © 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. -Copyright © IBM Corp 2006 +Copyright (c) IBM Corp 2006 @@ -2697,7 +2763,7 @@ Copyright © IBM Corp 2006 -Copyright © 2007-2008 Trilead AG (http://www.trilead.com) +Copyright (c) 2007-2008 Trilead AG (http://www.trilead.com) All rights reserved. @@ -2713,8 +2779,8 @@ All rights reserved. - - + + @@ -2724,68 +2790,59 @@ All rights reserved. - - -Copyright © 2010-2011 OpenStack, LLC. - - - - - - + + +Copyright (c) 2010-2011 OpenStack, LLC. + + + + + + - - -Copyright © 2010-2011 OpenStack, LLC. - - - - - - - - - -Copyright © 2009 Google Inc. - - - - - - + + +Copyright (c) 2010-2011 OpenStack, LLC. + + + + + + - - -Copyright © 2004-2008 The Apache Software Foundation - - - - - - + + +Copyright (c) 2004-2008 The Apache Software Foundation + + + + + + - - - - - - -Copyright © 2004-2011 QOS.ch - - - - - - + + + + + + +Copyright (c) 2004-2011 QOS.ch + + + + + + -Copyright © 2004-2012 The Apache Software Foundation +Copyright (c) 2004-2012 The Apache Software Foundation - + + @@ -2810,11 +2867,12 @@ Copyright © 2004-2012 The Apache Software Foundation + -Copyright © 2009 Google Inc. +Copyright (c) 2009 Google Inc. @@ -2822,14 +2880,14 @@ Copyright © 2009 Google Inc. - - - - + + + + -Copyright © 1997-2010 Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. @@ -2839,7 +2897,7 @@ Copyright © 1997-2010 Oracle and/or its affiliates. All rights reserved. -Copyright © 2006 Sun Microsystems, Inc. All rights reserved. +Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. @@ -2847,7 +2905,7 @@ Copyright © 2006 Sun Microsystems, Inc. All rights reserved. -Copyright © 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. +Copyright (c) 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. @@ -2861,7 +2919,7 @@ Copyright © 2002-2011 Atsuhiko Yamanaka, JCraft,Inc. -Copyright © 1997-2010 Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. @@ -2869,23 +2927,23 @@ Copyright © 1997-2010 Oracle and/or its affiliates. All rights reserved. - - + + - - PROJECTJavassist - INITIAL_DEVELOPERShigeru Chiba - INITIAL_DEVELOPER_COPYRIGHT1999-2008 Shigeru Chiba - CONTRIBUTORS - ALT_LIC_NAMEGNU Lesser General Public License Version 2.1 or later - ALT_LIC_SHORTLGPL - - - - + + PROJECTJavassist + INITIAL_DEVELOPERShigeru Chiba + INITIAL_DEVELOPER_COPYRIGHT1999-2008 Shigeru Chiba + CONTRIBUTORS + ALT_LIC_NAMEGNU Lesser General Public License Version 2.1 or later + ALT_LIC_SHORTLGPL + + + + - + diff --git a/ui/css/cloudstack3-ie7.css b/ui/css/cloudstack3-ie7.css index 90b823a4c0a..114e9c01edc 100644 --- a/ui/css/cloudstack3-ie7.css +++ b/ui/css/cloudstack3-ie7.css @@ -32,12 +32,13 @@ div.toolbar div.text-search div.search-bar input { float: left; border: none; margin-top: -1px; - margin-right:0px; - margin-bottom:0px; - margin-left:-12px; + margin-right: 0px; + margin-bottom: 0px; + margin-left: -12px; width: 97%; height: 67%; } + div.panel div.list-view div.fixed-header { top: expression(this.offsetParent.scrollTop + 30); } @@ -162,3 +163,47 @@ table th { top: 5px; } +.quick-view-tooltip div.title > span.title { +} + +.quick-view-tooltip div.title .icon { + top: -15px; +} + +.quick-view-tooltip table { +} + +.quick-view-tooltip .main-groups { + float: left; + left: 0px; + margin-top: 7px; +} + +.quick-view-tooltip .actions { + width: 426px !important; + float: left; +} + +.quick-view-tooltip .action { + float: left !important; + width: 54px !important; + margin-left: 7px !important; +} + +.quick-view-tooltip .action .label { + float: left; + max-width: 20px; +} + +.quick-view-tooltip .action .icon { + float: left; + height: 7px; + left: 0px; +} + +.list-view td.quick-view { +} + +.quick-view-tooltip .detail-view .detail-group.actions .action.text { + filter:alpha(opacity=100); +} diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index dfd4b1677d9..93578037168 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -1,3 +1,4 @@ +/*[fmt]1C20-1C0D-E*/ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -6,9 +7,9 @@ * to you 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 @@ -16,7 +17,6 @@ * specific language governing permissions and limitations * under the License. */ -/*[fmt]1C20-1C0D-E*/ /*+clearfix {*/ div.toolbar:after, .multi-wizard .progress ul li:after, @@ -62,9 +62,8 @@ body.install-wizard { #container { width: 1024px; - height: 768px; + height: 783px; margin: auto; - overflow: hidden; border: 1px solid #E2E2E2; border-top: none; position: relative; @@ -74,6 +73,7 @@ body.install-wizard { display: none; } +/*Table*/ table { width: 740px; max-width: 777px; @@ -140,10 +140,11 @@ table tbody td.loading { border-top: 1px solid #FBFBFB; } +/** Actions table cell*/ table tbody td.actions { - width: 155px; - max-width: 155px !important; - min-width: 155px !important; + width: 130px; + max-width: 130px !important; + min-width: 130px !important; vertical-align: middle; } @@ -155,6 +156,44 @@ table tbody td.actions input { margin: 11px 0 0px; } +/** Quick view table cell*/ +table tbody td.quick-view, +table thead th.quick-view { + min-width: 58px; + max-width: 58px !important; + width: 58px !important; + height: 14px !important; + text-indent: 7px; +} + +table tbody td.quick-view { + cursor: pointer; +} + +table tbody td.quick-view .icon { + margin-left: 22px; + margin-top: 3px; + padding: 0px 0px 6px 12px; + background: url(../images/sprites.png) no-repeat -44px -62px; +} + +table tbody td.quick-view:hover .icon { + background-position: -44px -644px; +} + +table tbody tr.loading td.quick-view .icon { + display: none; +} + +table tbody tr.loading td.quick-view { + cursor: default; +} + +table tbody tr.loading td.quick-view .loading { + background-position: center center; +} + +/** Row styling*/ table tbody tr { border-left: 1px solid #C4C5C5; border-right: 1px solid #C4C5C5; @@ -220,6 +259,7 @@ table th div.ui-resizable-handle { float: right; } +/** Header, misc*/ #header, #navigation { /*+text-shadow:0px -1px 1px #000000;*/ @@ -1153,7 +1193,7 @@ div.notification.corner-alert:hover div.message span { div.panel div.list-view { overflow: auto; overflow-x: hidden; - height: 652px; + height: 668px; margin-top: 30px; border-bottom: 1px solid #E7E7E7; } @@ -1229,7 +1269,9 @@ div.panel div.list-view div.fixed-header table { } div.list-view td.state { - width: 129px; + width: 120px; + min-width: 120px; + max-width: 120px; } div.list-view td.first { @@ -1241,7 +1283,7 @@ div.list-view td.first:hover { } div.list-view td.state span { - padding: 0 0 0 26px; + padding: 1px 0 0 18px; text-align: center; width: 80px; /*+text-shadow:0px 1px 1px #FFFFFF;*/ @@ -1266,6 +1308,241 @@ div.list-view td.state.off span { background-position: 1px -496px; } +/** Quick view tooltip*/ +.quick-view-tooltip { + width: 400px; + display: inline-block; + margin-left: -359px; + padding-top: 50px; +} + +.quick-view-tooltip > div.title { + width: 376px; + position: absolute; + top: 71px; + left: 10px; + color: #5A6977; + /*+text-shadow:0px 1px #EAEAEA;*/ + -moz-text-shadow: 0px 1px #EAEAEA; + -webkit-text-shadow: 0px 1px #EAEAEA; + -o-text-shadow: 0px 1px #EAEAEA; + text-shadow: 0px 1px #EAEAEA; +} + +.quick-view-tooltip > div.title .icon { + position: relative; + top: -3px; + background: url(../images/sprites.png) no-repeat -42px -67px; + float: right; + padding: 5px 21px 0 1px; +} + +.quick-view-tooltip .loading-overlay { + top: 94px; + height: 57px; + left: 1px; + /*+opacity:35%;*/ + filter: alpha(opacity=35); + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=35); + -moz-opacity: 0.35; + opacity: 0.35; +} + +.quick-view-tooltip > div.title span.title { +} + +.quick-view-tooltip .container { + border: 1px solid #9EA2A5; + background: #CCCFD6; + width: 400px; + min-height: 100px; + height: auto; + overflow: hidden; + display: inline-block; + /*+box-shadow:0px 7px 9px #676F76;*/ + -moz-box-shadow: 0px 7px 9px #676F76; + -webkit-box-shadow: 0px 7px 9px #676F76; + -o-box-shadow: 0px 7px 9px #676F76; + box-shadow: 0px 7px 9px #676F76; +} + +/*** Quick view detail view*/ +.quick-view-tooltip .detail-view { +} + +.quick-view-tooltip .detail-view .main-groups { + width: 394px; + height: 132px; + position: absolute; + top: 55px; + padding-top: 7px; + border: 1px solid #808080; + border-left: none; + border-right: none; + overflow: hidden; + /*+box-shadow:0px 1px #E6E6E6;*/ + -moz-box-shadow: 0px 1px #E6E6E6; + -webkit-box-shadow: 0px 1px #E6E6E6; + -o-box-shadow: 0px 1px #E6E6E6; + box-shadow: 0px 1px #E6E6E6; +} + +.quick-view-tooltip .detail-view .actions { +} + +.quick-view-tooltip .detail-view .tagger { + display: none; +} + +.quick-view-tooltip .detail-view ul { + display: none !important; +} + +.quick-view-tooltip .detail-view .ui-tabs-panel { + display: inline-block; + width: 100% !important; + float: left; + height: auto; + overflow: hidden; +} + +.quick-view-tooltip .detail-view .details { + display: inline-block; + height: auto; + padding-bottom: 209px; +} + +.quick-view-tooltip .detail-view .detail-group { + width: 365px; + margin: 0; + padding: 0; + left: -9px; + background: none; + border: none; +} + +.quick-view-tooltip .detail-view .detail-group table { + margin: 0; + border: none; + background: none; +} + +.quick-view-tooltip .detail-view .detail-group table tr { + background: none; +} + +.quick-view-tooltip .detail-view .detail-group table td.name { + color: #3E5F7F !important; + padding: 0px 29px 0px 5px !important; + font-size: 13px; + /*+text-shadow:0px 1px #DBDBDB;*/ + -moz-text-shadow: 0px 1px #DBDBDB; + -webkit-text-shadow: 0px 1px #DBDBDB; + -o-text-shadow: 0px 1px #DBDBDB; + text-shadow: 0px 1px #DBDBDB; +} + +.quick-view-tooltip .detail-view .detail-group table td.value { + font-size: 12px; + /*+text-shadow:0px 1px #EAEAEA;*/ + -moz-text-shadow: 0px 1px #EAEAEA; + -webkit-text-shadow: 0px 1px #EAEAEA; + -o-text-shadow: 0px 1px #EAEAEA; + text-shadow: 0px 1px #EAEAEA; +} + +.quick-view-tooltip .detail-view .detail-group table td.value input[type=text] { + width: 258px; + height: 10px; + margin-left: 0px; +} + +.quick-view-tooltip .detail-view .detail-group .main-groups table td.value span { + height: 15px; + top: 0px; +} + +.quick-view-tooltip .detail-view .detail-group.actions { + position: relative; + top: 202px; + float: left; + width: 100%; + height: auto; +} + +.quick-view-tooltip .detail-view .detail-group.actions .button { + top: 160px; +} + +.quick-view-tooltip .detail-view .detail-group.actions .action.text { + width: 112px; + height: 41px; + background: none; + border: none; + float: left; + margin-left: 5px; + display: inline-block; +} + +.quick-view-tooltip .detail-view .detail-group.actions .action.text:hover { + /*+box-shadow:none;*/ + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; +} + +.quick-view-tooltip .detail-view .detail-group.actions .action.text .icon { + display: block; + float: left; + width: 4px; +} + +.quick-view-tooltip .detail-view .detail-group.actions .action.text .label { + width: 81px; + display: block; + float: right; + font-size: 11px; + color: #454C53; + /*+text-shadow:0px 1px #FFFFFF;*/ + -moz-text-shadow: 0px 1px #FFFFFF; + -webkit-text-shadow: 0px 1px #FFFFFF; + -o-text-shadow: 0px 1px #FFFFFF; + text-shadow: 0px 1px #FFFFFF; + text-indent: 0px; +} + +.quick-view-tooltip .detail-view .detail-group.actions .action.text:hover .label { + color: #000000; +} + +.quick-view-tooltip .detail-view .detail-group.actions .detail-actions { + width: 400px; + height: auto; + background: none; + vertical-align: top; + float: left; +} + +.quick-view-tooltip .detail-view .detail-group.actions td.view-all { + position: relative; + left: 0px; + float: left; + width: 394px; + height: 22px; + border-top: 1px solid #808080; + /*+box-shadow:inset 0px 1px #FFFFFF;*/ + -moz-box-shadow: inset 0px 1px #FFFFFF; + -webkit-box-shadow: inset 0px 1px #FFFFFF; + -o-box-shadow: inset 0px 1px #FFFFFF; + box-shadow: inset 0px 1px #FFFFFF; +} + +.quick-view-tooltip .detail-view .detail-actions a { + background: none; + width: 30px; +} + /*Details page*/ .detail-view { padding: 0 0 0 14px; @@ -2168,6 +2445,13 @@ div.detail-group.actions td { overflow: hidden; } +#browser.panel-highlight { + overflow: visible; +} + +#browser.panel-highlight .panel { +} + #browser div.panel { height: 698px; background: #F7F7F7; @@ -2175,6 +2459,35 @@ div.detail-group.actions td { overflow: visible; } +#browser div.panel.panel-highlight-wrapper { + display: inline-block; + background: none; + /*+border-radius:9px;*/ + -moz-border-radius: 9px; + -webkit-border-radius: 9px; + -khtml-border-radius: 9px; + border-radius: 9px; + margin-top: 7px; + /*+box-shadow:0px 0px 12px #000000;*/ + -moz-box-shadow: 0px 0px 12px #000000; + -webkit-box-shadow: 0px 0px 12px #000000; + -o-box-shadow: 0px 0px 12px #000000; + box-shadow: 0px 0px 12px #000000; + border: 3px solid #FFFFFF; + height: 542px; + overflow: hidden; + position: absolute; + z-index: 10000; + padding: 78px 0px 67px 51px; +} + +#browser div.panel.panel-highlight-wrapper .panel { + left: 20px !important; + height: 631px; + overflow: hidden; + top: 3px; +} + .project-view #browser div.panel { background: #6D747D; } @@ -2197,6 +2510,38 @@ div.detail-group.actions td { background: url(../images/bg-panel-shadow.png) repeat-y 0px 0px; } +#browser.panel-highlight { + overflow: visible; +} + +#browser.panel-highlight .panel.highlighted { + /*+box-shadow:0px 10px 11px #5C5C5C;*/ + -moz-box-shadow: 0px 10px 11px #5C5C5C; + -webkit-box-shadow: 0px 10px 11px #5C5C5C; + -o-box-shadow: 0px 10px 11px #5C5C5C; + box-shadow: 0px 10px 11px #5C5C5C; + border: 5px solid #FFFFFF; + /*+border-radius:6px;*/ + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + -khtml-border-radius: 6px; + border-radius: 6px; + margin-top: 21px; +} + +#browser.panel-highlight .panel > .shadow { + display: none; +} + +#browser .highlight-arrow { + width: 24px; + height: 19px; + background: url(../images/sprites.png) -590px -1295px; + position: absolute; + top: -22px; + left: 80px; +} + /*Toolbar*/ /*[clearfix]*/div.toolbar { width: 793px; @@ -2266,6 +2611,7 @@ div.toolbar div.filters select { div.toolbar div.text-search { float: right; + position: relative; } div.toolbar div.text-search div.search-bar { @@ -2400,6 +2746,137 @@ div.toolbar div.button.add span { border-right: 1px solid #43586B; } +/*** Advanced search*/ +#advanced_search { + width: 15px; + position: absolute; + left: 139px; + top: 4px; + z-index: 4; + background: none; +} + +#advanced_search .icon { + /*+opacity:56%;*/ + filter: alpha(opacity=56); + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=56); + -moz-opacity: 0.56; + opacity: 0.56; + background: url(../images/sprites.png) no-repeat -62px -162px; + padding: 10px; + position: absolute; + top: 1px; + left: -1px; + z-index: 10; +} + +#advanced_search:hover .icon { + /*+opacity:100%;*/ + filter: alpha(opacity=100); + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); + -moz-opacity: 1; + opacity: 1; +} + +#advanced_search .form-container { + /*+opacity:91%;*/ + filter: alpha(opacity=91); + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=91); + -moz-opacity: 0.91; + opacity: 0.91; + /*+box-shadow:0px 5px 9px #B6B0B0;*/ + -moz-box-shadow: 0px 5px 9px #B6B0B0; + -webkit-box-shadow: 0px 5px 9px #B6B0B0; + -o-box-shadow: 0px 5px 9px #B6B0B0; + box-shadow: 0px 5px 9px #B6B0B0; + border: 1px solid #808080; + /*+border-radius:0 0 4px 4px;*/ + -moz-border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px; + -khtml-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; + left: -290px; + top: 2px; + position: absolute; + display: inline-block; + background: #FFFFFF; + padding: 18px; + cursor: default; +} + +#advanced_search .form-container .name { + width: 66px; + float: left; +} + +#advanced_search .form-container .value { + width: 186px; + float: left; +} + +#advanced_search .form-container .form-item { + width: 268px; + height: 40px; + margin-bottom: 15px; +} + +#advanced_search .form-container .form-item input, +#advanced_search .form-container .form-item select { + width: 97%; + padding: 3px; +} + +#advanced_search input[type=submit] { + float: right; + background: url(../images/bg-gradients.png) 0px -220px; + /*+box-shadow:0px 2px 5px #858585;*/ + -moz-box-shadow: 0px 2px 5px #858585; + -webkit-box-shadow: 0px 2px 5px #858585; + -o-box-shadow: 0px 2px 5px #858585; + box-shadow: 0px 2px 5px #858585; + border: 1px solid #606060; + border-top: none; + color: #FFFFFF; + font-size: 12px; + font-weight: bold; + /*+text-shadow:0px 1px 1px #000000;*/ + -moz-text-shadow: 0px 1px 1px #000000; + -webkit-text-shadow: 0px 1px 1px #000000; + -o-text-shadow: 0px 1px 1px #000000; + text-shadow: 0px 1px 1px #000000; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + cursor: pointer; + padding: 8px 20px; +} + +#advanced_search input[type=submit]:hover { + /*+box-shadow:inset 0px 2px 3px #000000;*/ + -moz-box-shadow: inset 0px 2px 3px #000000; + -webkit-box-shadow: inset 0px 2px 3px #000000; + -o-box-shadow: inset 0px 2px 3px #000000; + box-shadow: inset 0px 2px 3px #000000; +} + +#advanced_search .button.cancel { + background: url(noen); + color: #9A9A9A; + font-size: 12px; + float: right; + /*+placement:shift -32px 13px;*/ + position: relative; + left: -32px; + top: 13px; + font-weight: bold; +} + +#advanced_search .button.cancel:hover { + color: #494949; +} + /*** Panel controls*/ #browser div.panel div.toolbar div.panel-controls { float: right; @@ -2444,7 +2921,7 @@ div.toolbar div.button.add span { } /*** Section switcher*/ -div.list-view div.toolbar div.section-switcher { +div.panel div.toolbar div.section-switcher { margin-top: 6px; margin-left: 10px; float: left; @@ -2454,12 +2931,12 @@ div.list-view div.toolbar div.section-switcher { display: none; } -div.list-view div.toolbar div.section-switcher div.section-select { +div.toolbar div.section-switcher div.section-select { float: right; background: #A8AFB6; } -div.list-view div.toolbar div.section-switcher div.section { +div.toolbar div.section-switcher div.section { float: left; font-size: 11px; font-weight: bold; @@ -2476,7 +2953,7 @@ div.list-view div.toolbar div.section-switcher div.section { text-shadow: 0px 1px 1px #EDEDED; } -div.list-view div.toolbar div.section-switcher div.section a { +div.toolbar div.section-switcher div.section a { background: url(../images/bg-section-switcher.png) repeat-x 0px -22px; text-decoration: none; display: block; @@ -2485,7 +2962,7 @@ div.list-view div.toolbar div.section-switcher div.section a { border: 1px solid #979FA4; } -div.list-view div.toolbar div.section-switcher div.section a.active { +div.toolbar div.section-switcher div.section a.active { background: url(../images/bg-section-switcher.png) repeat-x 0px -21px; background-position: 0px 0px; border: none; @@ -2499,7 +2976,7 @@ div.list-view div.toolbar div.section-switcher div.section a.active { box-shadow: inset 0px 1px 5px #546874; } -div.list-view div.toolbar div.section-switcher div.section.first a { +div.toolbar div.section-switcher div.section.first a { /*+border-radius:4px 0 0 5px;*/ -moz-border-radius: 4px 0 0 5px; -webkit-border-radius: 4px 0 0 5px; @@ -2507,7 +2984,7 @@ div.list-view div.toolbar div.section-switcher div.section.first a { border-radius: 4px 0 0 5px; } -div.list-view div.toolbar div.section-switcher div.section.last a { +div.toolbar div.section-switcher div.section.last a { /*+border-radius:0 4px 4px 0px;*/ -moz-border-radius: 0 4px 4px 0px; -webkit-border-radius: 0 4px 4px 0px; @@ -2515,7 +2992,7 @@ div.list-view div.toolbar div.section-switcher div.section.last a { border-radius: 0 4px 4px 0px; } -div.list-view div.toolbar div.section-switcher div.section.first.last a { +div.toolbar div.section-switcher div.section.first.last a { /*+border-radius:5px;*/ -moz-border-radius: 5px; -webkit-border-radius: 5px; @@ -2524,17 +3001,17 @@ div.list-view div.toolbar div.section-switcher div.section.first.last a { border-radius: 5px 5px 5px 5px; } -div.list-view div.toolbar div.section-switcher div.section-select { +div.toolbar div.section-switcher div.section-select { float: left; background: #A8AFB6; height: 26px; } -.project-view div.list-view div.toolbar div.section-switcher div.section-select { +.project-view div.toolbar div.section-switcher div.section-select { background: transparent; } -div.list-view div.toolbar div.section-switcher div.section-select select { +div.toolbar div.section-switcher div.section-select select { width: 142px; height: 21px; margin-right: 13px; @@ -2548,7 +3025,7 @@ div.list-view div.toolbar div.section-switcher div.section-select select { border-radius: 4px 4px 4px 4px; } -div.list-view div.toolbar div.section-switcher div.section-select label { +div.toolbar div.section-switcher div.section-select label { margin: 0 9px 0 0; } @@ -2844,7 +3321,7 @@ table td.actions span { table td.actions .action span.icon { background-image: url(../images/sprites.png); cursor: pointer; - width: 28px; + width: 23px; height: 21px; float: left; } @@ -7794,6 +8271,16 @@ div.panel.ui-dialog div.list-view div.fixed-header { background-color: #35404B; } +.system-dashboard.zone .status_box li .icon { + background: url(../images/infrastructure-icons.png) no-repeat 0px 0px; + padding: 65px 65px 5px; + /*+placement:shift 23px 24px;*/ + position: relative; + left: 23px; + top: 24px; + position: absolute; +} + .system-dashboard .status_box li span { color: #FFFFFF; /*+text-shadow:0px 1px 1px #000000;*/ @@ -8013,6 +8500,39 @@ div.panel.ui-dialog div.list-view div.fixed-header { margin: 8px 0 0 9px; } +/** Infrastructure icons*/ +.system-dashboard.zone .status_box li.zones .icon { + background-position: -36px -105px; +} + +.system-dashboard.zone .status_box li.pods .icon { + background-position: -229px -105px; +} + +.system-dashboard.zone .status_box li.clusters .icon { + background-position: -411px -96px; +} + +.system-dashboard.zone .status_box li.hosts .icon { + background-position: -601px -102px; +} + +.system-dashboard.zone .status_box li.primary-storage .icon { + background-position: -36px -404px; +} + +.system-dashboard.zone .status_box li.secondary-storage .icon { + background-position: -219px -404px; +} + +.system-dashboard.zone .status_box li.system-vms .icon { + background-position: -408px -399px; +} + +.system-dashboard.zone .status_box li.virtual-routers .icon { + background-position: -601px -400px; +} + /*Projects ** View switcher*/ #header .view-switcher { @@ -8611,6 +9131,9 @@ div.panel.ui-dialog div.list-view div.fixed-header { position: relative; left: 5px; top: 8px; + display: inline-block; + padding-bottom: 13px; + max-width: 171px; } .info-boxes .info-box ul li .total span { @@ -8998,6 +9521,38 @@ div.panel.ui-dialog div.list-view div.fixed-header { background: #DFE1E3; } +/*Tooltip*/ +.tooltip-box { + width: 15%; + height: auto; + display: inline-block, padding: 4px; + background: #FFFFFF; + border: 1px solid #BEB8B8; + padding: 10px; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + margin-left: 23px; + /*+box-shadow:0px 1px 12px #353535;*/ + -moz-box-shadow: 0px 1px 12px #353535; + -webkit-box-shadow: 0px 1px 12px #353535; + -o-box-shadow: 0px 1px 12px #353535; + box-shadow: 0px 1px 12px #353535; +} + +.tooltip-box .arrow { + width: 19px; + height: 30px; + background: url(../images/sprites.png) -585px -947px; + /*+placement:shift -16px 3px;*/ + position: relative; + left: -16px; + top: 3px; + position: absolute; +} + /*Tagger*/ .tagger { width: 94%; @@ -10006,6 +10561,23 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it font-size: 11px; } +/*List state BG colors*/ +.list-view .body td.item-state-on { + background: #C0FFC0; + border-bottom: 1px solid #09BC09; +} + +.list-view .body td.item-state-off { + background: #FFD8CF; + border-bottom: 1px solid #FF9F9F; +} + +.list-view .body tr.selected td.item-state-on, +.list-view .body tr.selected td.item-state-off { + background-color: inherit; + border-color: inherit; +} + /*Action icons*/ .action.edit .icon { background-position: 1px -1px; @@ -10386,5 +10958,6 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it .label-hovered { cursor: pointer; - color: blue !important; + color: #0000FF !important; } + diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index f64864ccadf..bf53ed970c3 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -25,6 +25,15 @@ under the License. <% long now = System.currentTimeMillis(); %> diff --git a/ui/images/infrastructure-icons.png b/ui/images/infrastructure-icons.png new file mode 100644 index 00000000000..7d4f8f9f082 Binary files /dev/null and b/ui/images/infrastructure-icons.png differ diff --git a/ui/images/sprites.png b/ui/images/sprites.png index db95cca7b6e..a3ad9e4862f 100644 Binary files a/ui/images/sprites.png and b/ui/images/sprites.png differ diff --git a/ui/index.jsp b/ui/index.jsp index a81dcb3c5f0..6c38e363734 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -68,10 +68,13 @@ under the License.
@@ -136,6 +139,9 @@ under the License.
  • + + +
      -
    • +
    • +   " view-all-target="zones">
    • -
    • +
    • +   " view-all-target="pods">
    • -
    • +
    • +   " view-all-target="clusters">
    • -
    • +
    • +   " view-all-target="hosts">
    • -
    • +
    • +   " view-all-target="primaryStorage">
    • -
    • +
    • +   " view-all-target="secondaryStorage">
    • -
    • +
    • +   " view-all-target="systemVms">
    • -
    • +
    • +   " @@ -1602,7 +1616,7 @@ under the License. - + @@ -1636,7 +1650,8 @@ under the License. - + + diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index 34a9538d89e..a74389d505f 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -19,12 +19,6 @@ var domainObjs; var rootDomainId; - var systemAccountId = 1; - var adminAccountId = 2; - - var systemUserId = 1; - var adminUserId = 2; - cloudStack.sections.accounts = { title: 'label.accounts', id: 'accounts', @@ -85,13 +79,15 @@ fields: { username: { label: 'label.username', - validation: { required: true } + validation: { required: true }, + docID: 'helpAccountUsername' }, password: { label: 'label.password', validation: { required: true }, isPassword: true, - id: 'password' + id: 'password', + docID: 'helpAccountPassword' }, 'password-confirm': { label: 'label.confirm.password', @@ -99,22 +95,27 @@ required: true, equalTo: '#password' }, - isPassword: true + isPassword: true, + docID: 'helpAccountConfirmPassword' }, email: { label: 'label.email', - validation: { required: true, email:true } + validation: { required: true, email:true }, + docID: 'helpAccountEmail' }, firstname: { label: 'label.first.name', - validation: { required: true } + validation: { required: true }, + docID: 'helpAccountFirstName' }, lastname: { label: 'label.last.name', - validation: { required: true } + validation: { required: true }, + docID: 'helpAccountLastName' }, domainid: { label: 'label.domain', + docID: 'helpAccountDomain', validation: { required: true }, select: function(args) { var data = {}; @@ -145,10 +146,12 @@ } }, account: { - label: 'label.account' + label: 'label.account', + docID: 'helpAccountAccount' }, accounttype: { label: 'label.type', + docID: 'helpAccountType', validation: { required: true }, select: function(args) { var items = []; @@ -159,6 +162,7 @@ }, timezone: { label: 'label.timezone', + docID: 'helpAccountTimezone', select: function(args) { var items = []; items.push({id: "", description: ""}); @@ -169,54 +173,69 @@ }, networkdomain: { label: 'label.network.domain', + docID: 'helpAccountNetworkDomain', validation: { required: false } } } }, action: function(args) { - var array1 = []; - array1.push("&username=" + todb(args.data.username)); - var errorMsg = ""; + var data = { + username: args.data.username + }; + var password = args.data.password; - if (md5Hashed) - password = $.md5(password); - else - password = todb(password); - array1.push("&password=" + password); - - array1.push("&email=" + todb(args.data.email)); - array1.push("&firstname=" + todb(args.data.firstname)); - array1.push("&lastname=" + todb(args.data.lastname)); - - array1.push("&domainid=" + args.data.domainid); + if (md5Hashed) { + password = $.md5(password); + } + $.extend(data, { + password: password + }); + + $.extend(data, { + email: args.data.email, + firstname: args.data.firstname, + lastname: args.data.lastname, + domainid: args.data.domainid + }); var account = args.data.account; - if(account == null || account.length == 0) + if(account == null || account.length == 0) { account = args.data.username; - array1.push("&account=" + todb(account)); - + } + $.extend(data, { + account: account + }); + var accountType = args.data.accounttype; - if (args.data.accounttype == "1" && args.data.domainid != rootDomainId) //if account type is admin, but domain is not Root domain - accountType = "2"; // Change accounttype from root-domain("1") to domain-admin("2") - array1.push("&accounttype=" + accountType); + if (args.data.accounttype == "1" && args.data.domainid != rootDomainId) { //if account type is admin, but domain is not Root domain + accountType = "2"; // Change accounttype from root-domain("1") to domain-admin("2") + } + $.extend(data, { + accounttype: accountType + }); + + if(args.data.timezone != null && args.data.timezone.length > 0) { + $.extend(data, { + timezone: args.data.timezone + }); + } - if(args.data.timezone != null && args.data.timezone.length > 0) - array1.push("&timezone=" + todb(args.data.timezone)); - - if(args.data.networkdomain != null && args.data.networkdomain.length > 0) - array1.push("&networkdomain=" + todb(args.data.networkdomain)); + if(args.data.networkdomain != null && args.data.networkdomain.length > 0) { + $.extend(data, { + networkdomain: args.data.networkdomain + }); + } $.ajax({ - url: createURL("createAccount" + array1.join("")), - dataType: "json", + url: createURL('createAccount'), + data: data, success: function(json) { var item = json.createaccountresponse.account; args.response.success({data:item}); }, - error: function(XMLHttpResponse) { - var errorMsg = parseXMLHttpResponse(XMLHttpResponse); - args.response.error(errorMsg); + error: function(XMLHttpResponse) { + args.response.error(parseXMLHttpResponse(XMLHttpResponse)); } }); }, @@ -232,23 +251,18 @@ }, dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - - if("domains" in args.context) - array1.push("&domainid=" + args.context.domains[0].id); + var data = {}; + listViewDataProvider(args, data); + + if("domains" in args.context) { + $.extend(data, { + domainid: args.context.domains[0].id + }); + } + $.ajax({ - url: createURL("listAccounts" + "&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + '&listAll=true'), - dataType: "json", + url: createURL('listAccounts'), + data: data, async: true, success: function(json) { var items = json.listaccountsresponse.account; @@ -267,82 +281,133 @@ actions: { edit: { label: 'message.edit.account', - action: function(args) { - var errorMsg = ""; + compactLabel: 'label.edit', + action: function(args) { var accountObj = args.context.accounts[0]; - var array1 = []; - array1.push("&newname=" + todb(args.data.name)); - array1.push("&networkdomain=" + todb(args.data.networkdomain)); + var data = { + domainid: accountObj.domainid, + account: accountObj.name, + newname: args.data.name, + networkdomain: args.data.networkdomain + }; + $.ajax({ - url: createURL("updateAccount&domainid=" + accountObj.domainid + "&account=" + accountObj.name + array1.join("")), - dataType: "json", + url: createURL('updateAccount'), + data: data, async: false, success: function(json) { accountObj = json.updateaccountresponse.account; }, error: function(json) { - errorMsg = parseXMLHttpResponse(json); + var errorMsg = parseXMLHttpResponse(json); args.response.error(errorMsg); - } + } + }); + + if(args.data.vmLimit != null) { + var data = { + resourceType: 0, + max: args.data.vmLimit, + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ + url: createURL('updateResourceLimit'), + data: data, + async: false, + success: function(json) { + accountObj["vmLimit"] = args.data.vmLimit; + } + }); + } + + if(args.data.ipLimit != null) { + var data = { + resourceType: 1, + max: args.data.ipLimit, + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ + url: createURL('updateResourceLimit'), + data: data, + async: false, + success: function(json) { + accountObj["ipLimit"] = args.data.ipLimit; + } + }); + } + + if(args.data.volumeLimit != null) { + var data = { + resourceType: 2, + max: args.data.volumeLimit, + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ + url: createURL('updateResourceLimit'), + data: data, + async: false, + success: function(json) { + accountObj["volumeLimit"] = args.data.volumeLimit; + } + }); + } + + if(args.data.snapshotLimit != null) { + var data = { + resourceType: 3, + max: args.data.snapshotLimit, + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ + url: createURL('updateResourceLimit'), + data: data, + async: false, + success: function(json) { + accountObj["snapshotLimit"] = args.data.snapshotLimit; + } + }); + } - }); + if(args.data.templateLimit != null) { + var data = { + resourceType: 4, + max: args.data.templateLimit, + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ + url: createURL('updateResourceLimit'), + data: data, + async: false, + success: function(json) { + accountObj["templateLimit"] = args.data.templateLimit; + } + }); + } + + if(args.data.vpcLimit != null) { + var data = { + resourceType: 7, + max: args.data.vpcLimit, + domainid: accountObj.domainid, + account: accountObj.name + }; + + $.ajax({ + url: createURL('updateResourceLimit'), + data: data, + async: false, + success: function(json) { + accountObj["vpcLimit"] = args.data.vpcLimit; + } + }); + } - $.ajax({ - url: createURL("updateResourceLimit&resourceType=0&max=" + todb(args.data.vmLimit) + "&account=" + accountObj.name + "&domainid=" + accountObj.domainid), - dataType: "json", - async: false, - success: function(json) { - accountObj["vmLimit"] = args.data.vmLimit; - } - }); - - $.ajax({ - url: createURL("updateResourceLimit&resourceType=1&max=" + todb(args.data.ipLimit) + "&account=" + accountObj.name + "&domainid=" + accountObj.domainid), - dataType: "json", - async: false, - success: function(json) { - accountObj["ipLimit"] = args.data.ipLimit; - } - }); - - $.ajax({ - url: createURL("updateResourceLimit&resourceType=2&max=" + todb(args.data.volumeLimit) + "&account=" + accountObj.name + "&domainid=" + accountObj.domainid), - dataType: "json", - async: false, - success: function(json) { - accountObj["volumeLimit"] = args.data.volumeLimit; - } - }); - - $.ajax({ - url: createURL("updateResourceLimit&resourceType=3&max=" + todb(args.data.snapshotLimit) + "&account=" + accountObj.name + "&domainid=" + accountObj.domainid), - dataType: "json", - async: false, - success: function(json) { - accountObj["snapshotLimit"] = args.data.snapshotLimit; - } - }); - - $.ajax({ - url: createURL("updateResourceLimit&resourceType=4&max=" + todb(args.data.templateLimit) + "&account=" + accountObj.name + "&domainid=" + accountObj.domainid), - dataType: "json", - async: false, - success: function(json) { - accountObj["templateLimit"] = args.data.templateLimit; - } - }); - - $.ajax({ - url: createURL("updateResourceLimit&resourceType=7&max=" + todb(args.data.vpcLimit) + "&account=" + accountObj.name + "&domainid=" + accountObj.domainid), - dataType: "json", - async: false, - success: function(json) { - accountObj["vpcLimit"] = args.data.vpcLimit; - } - }); - - if(errorMsg == "") args.response.success({data: accountObj}); } }, @@ -359,9 +424,14 @@ }, action: function(args) { var accountObj = args.context.accounts[0]; + var data = { + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ - url: createURL("updateResourceCount&domainid=" + accountObj.domainid + "&account=" + accountObj.name), - dataType: "json", + url: createURL('updateResourceCount'), + data: data, async: true, success: function(json) { //var resourcecounts= json.updateresourcecountresponse.resourcecount; //do nothing @@ -391,9 +461,15 @@ }, action: function(args) { var accountObj = args.context.accounts[0]; + var data = { + lock: false, + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ - url: createURL("disableAccount&lock=false&domainid=" + accountObj.domainid + "&account=" + accountObj.name), - dataType: "json", + url: createURL('disableAccount'), + data: data, async: true, success: function(json) { var jid = json.disableaccountresponse.jobid; @@ -429,9 +505,15 @@ }, action: function(args) { var accountObj = args.context.accounts[0]; + var data = { + lock: true, + domainid: accountObj.domainid, + account: accountObj.name + }; + $.ajax({ - url: createURL("disableAccount&lock=true&domainid=" + accountObj.domainid + "&account=" + accountObj.name), - dataType: "json", + url: createURL('disableAccount'), + data: data, async: true, success: function(json) { var jid = json.disableaccountresponse.jobid; @@ -467,9 +549,13 @@ }, action: function(args) { var accountObj = args.context.accounts[0]; + var data = { + domainid: accountObj.domainid, + account: accountObj.name + }; $.ajax({ - url: createURL("enableAccount&domainid=" + accountObj.domainid + "&account=" + accountObj.name), - dataType: "json", + url: createURL('enableAccount'), + data: data, async: true, success: function(json) { args.response.success({data: json.enableaccountresponse.account}); @@ -496,9 +582,12 @@ } }, action: function(args) { + var data = { + id: args.context.accounts[0].id + }; $.ajax({ - url: createURL("deleteAccount&id=" + args.context.accounts[0].id), - dataType: "json", + url: createURL('deleteAccount'), + data: data, async: true, success: function(json) { var jid = json.deleteaccountresponse.jobid; @@ -552,27 +641,57 @@ }, vmLimit: { label: 'label.instance.limits', - isEditable: true + isEditable: function(context) { + if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin + return true; + else + return false; + } }, ipLimit: { label: 'label.ip.limits', - isEditable: true + isEditable: function(context) { + if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin + return true; + else + return false; + } }, volumeLimit: { label: 'label.volume.limits', - isEditable: true + isEditable: function(context) { + if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin + return true; + else + return false; + } }, snapshotLimit: { label: 'label.snapshot.limits', - isEditable: true + isEditable: function(context) { + if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin + return true; + else + return false; + } }, templateLimit: { label: 'label.template.limits', - isEditable: true + isEditable: function(context) { + if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin + return true; + else + return false; + } }, vpcLimit: { label: 'VPC limits', - isEditable: true + isEditable: function(context) { + if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin + return true; + else + return false; + } }, vmtotal: { label: 'label.total.of.vm' }, @@ -599,15 +718,21 @@ ], dataProvider: function(args) { + var data = { + id: args.context.accounts[0].id + }; $.ajax({ - url: createURL("listAccounts&id=" + args.context.accounts[0].id), - dataType: "json", + url: createURL('listAccounts'), + data: data, success: function(json) { var accountObj = json.listaccountsresponse.account[0]; - + var data = { + domainid: accountObj.domainid, + account: accountObj.name + }; $.ajax({ - url: createURL("listResourceLimits&domainid=" + accountObj.domainid + "&account=" + todb(accountObj.name)), - dataType: "json", + url: createURL('listResourceLimits'), + data: data, success: function(json) { var limits = json.listresourcelimitsresponse.resourcelimit; if (limits != null) { @@ -717,16 +842,19 @@ fields: { username: { label: 'label.username', - validation: { required: true } + validation: { required: true }, + docID: 'helpUserUsername' }, password: { label: 'label.password', isPassword: true, validation: { required: true }, - id: 'password' + id: 'password', + docID: 'helpUserPassword' }, 'password-confirm': { label: 'label.confirm.password', + docID: 'helpUserConfirmPassword', validation: { required: true, equalTo: '#password' @@ -735,18 +863,22 @@ }, email: { label: 'label.email', + docID: 'helpUserEmail', validation: { required: true, email: true } }, firstname: { label: 'label.first.name', + docID: 'helpUserFirstName', validation: { required: true } }, lastname: { label: 'label.last.name', + docID: 'helpUserLastName', validation: { required: true } }, timezone: { label: 'label.timezone', + docID: 'helpUserTimezone', select: function(args) { var items = []; items.push({id: "", description: ""}); @@ -1097,12 +1229,8 @@ if (jsonObj.state == 'Destroyed') return []; if(isAdmin()) { - if(jsonObj.id != systemAccountId && jsonObj.id != adminAccountId) { - //allowedActions.push("edit"); - if (jsonObj.accounttype == roleTypeUser || jsonObj.accounttype == roleTypeDomainAdmin) { - //allowedActions.push("updateResourceLimits"); - allowedActions.push("edit"); - } + allowedActions.push("edit"); //updating networkdomain is allowed on any account, including system-generated default admin account + if(!(jsonObj.domain == "ROOT" && jsonObj.name == "admin" && jsonObj.accounttype == 1)) { //if not system-generated default admin account if(jsonObj.state == "enabled") { allowedActions.push("disable"); allowedActions.push("lock"); @@ -1127,7 +1255,7 @@ allowedActions.push("edit"); allowedActions.push("changePassword"); allowedActions.push("generateKeys"); - if(jsonObj.id != systemUserId && jsonObj.id != adminUserId) { + if(!(jsonObj.domain == "ROOT" && jsonObj.account == "admin" && jsonObj.accounttype == 1)) { //if not system-generated default admin account user if(jsonObj.state == "enabled") allowedActions.push("disable"); if(jsonObj.state == "disabled") diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index 1d2dbe8f438..de3bd7317e7 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -36,19 +36,20 @@ /** * Dashboard */ - dashboard: {}, - //'dashboard-user': {}, + dashboard: {}, instances: {}, storage: {}, network: {}, templates: {}, events: {}, + projects: {}, accounts: {}, - domains: {}, - system: {}, - projects: {}, - 'global-settings': {}, - configuration: {} + + domains: {}, //domain-admin and root-admin only + + system: {}, //root-admin only + 'global-settings': {}, //root-admin only + configuration: {} //root-admin only } }); diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 96b6fb9ab83..6b41cb995a6 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -59,14 +59,17 @@ fields: { name: { label: 'label.name', + docID: 'helpComputeOfferingName', validation: { required: true } }, description: { label: 'label.description', + docID: 'helpComputeOfferingDescription', validation: { required: true } }, storageType: { label: 'label.storage.type', + docID: 'helpComputeOfferingStorageType', select: function(args) { var items = []; items.push({id: 'shared', description: 'shared'}); @@ -76,6 +79,7 @@ }, cpuNumber: { label: 'label.num.cpu.cores', + docID: 'helpComputeOfferingCPUCores', validation: { required: true, number: true @@ -83,6 +87,7 @@ }, cpuSpeed: { label: 'label.cpu.mhz', + docID: 'helpComputeOfferingCPUMHz', validation: { required: true, number: true @@ -90,6 +95,7 @@ }, memory: { label: 'label.memory.mb', + docID: 'helpComputeOfferingMemory', validation: { required: true, number: true @@ -97,6 +103,7 @@ }, networkRate: { label: 'label.network.rate', + docID: 'helpComputeOfferingNetworkRate', validation: { required: false, //optional number: true @@ -104,28 +111,34 @@ }, offerHA: { label: 'label.offer.ha', + docID: 'helpComputeOfferingHA', isBoolean: true, isChecked: false }, storageTags: { - label: 'label.storage.tags' + label: 'label.storage.tags', + docID: 'helpComputeOfferingStorageType' }, hostTags: { - label: 'label.host.tags' + label: 'label.host.tags', + docID: 'helpComputeOfferingHostTags' }, cpuCap: { label: 'label.CPU.cap', isBoolean: true, - isChecked: false + isChecked: false, + docID: 'helpComputeOfferingCPUCap' }, isPublic: { label: 'label.public', isBoolean: true, isReverse: true, - isChecked: true + isChecked: true, + docID: 'helpComputeOfferingPublic' }, domainId: { label: 'label.domain', + docID: 'helpComputeOfferingDomain', dependsOn: 'isPublic', select: function(args) { $.ajax({ @@ -383,14 +396,17 @@ fields: { name: { label: 'label.name', - validation: { required: true } + validation: { required: true }, + docID: 'helpSystemOfferingName' }, description: { label: 'label.description', - validation: { required: true } + validation: { required: true }, + docID: 'helpSystemOfferingDescription' }, systemvmtype: { label: 'label.system.vm.type', + docID: 'helpSystemOfferingVMType', select: function(args) { var items = []; items.push({id: 'domainrouter', description: dictionary['label.domain.router']}); @@ -401,6 +417,7 @@ }, storageType: { label: 'label.storage.type', + docID: 'helpSystemOfferingStorageType', select: function(args) { var items = []; items.push({id: 'shared', description: 'shared'}); @@ -410,6 +427,7 @@ }, cpuNumber: { label: 'label.num.cpu.cores', + docID: 'helpSystemOfferingCPUCores', validation: { required: true, number: true @@ -417,6 +435,7 @@ }, cpuSpeed: { label: 'label.cpu.mhz', + docID: 'helpSystemOfferingCPUMHz', validation: { required: true, number: true @@ -424,6 +443,7 @@ }, memory: { label: 'label.memory.mb', + docID: 'helpSystemOfferingMemory', validation: { required: true, number: true @@ -431,6 +451,7 @@ }, networkRate: { label: 'label.network.rate', + docID: 'helpSystemOfferingNetworkRate', validation: { required: false, //optional number: true @@ -438,25 +459,30 @@ }, offerHA: { label: 'label.offer.ha', + docID: 'helpSystemOfferingHA', isBoolean: true, isChecked: false }, storageTags: { - label: 'label.storage.tags' + label: 'label.storage.tags', + docID: 'helpSystemOfferingStorageTags' }, hostTags: { - label: 'label.host.tags' + label: 'label.host.tags', + docID: 'helpSystemOfferingHostTags' }, cpuCap: { label: 'label.CPU.cap', isBoolean: true, - isChecked: false + isChecked: false, + docID: 'helpSystemOfferingCPUCap' }, isPublic: { label: 'label.public', isBoolean: true, isReverse: true, - isChecked: true + isChecked: true, + docID: 'helpSystemOfferingPublic' }, domainId: { label: 'label.domain', @@ -768,14 +794,17 @@ fields: { name: { label: 'label.name', + docID: 'helpDiskOfferingName', validation: { required: true } }, description: { label: 'label.description', + docID: 'helpDiskOfferingDescription', validation: { required: true } }, storageType: { label: 'label.storage.type', + docID: 'helpDiskOfferingStorageType', select: function(args) { var items = []; items.push({id: 'shared', description: 'shared'}); @@ -785,23 +814,27 @@ }, isCustomized: { label: 'label.custom.disk.size', + docID: 'helpDiskOfferingCustomDiskSize', isBoolean: true, isReverse: true, isChecked: false }, disksize: { label: 'label.disk.size.gb', + docID: 'helpDiskOfferingDiskSize', dependsOn: 'isCustomized', validation: { required: true, number: true } }, tags: { - label: 'label.storage.tags' + label: 'label.storage.tags', + docID: 'helpDiskOfferingStorageTags' }, isPublic: { label: 'label.public', isBoolean: true, isReverse: true, - isChecked: true + isChecked: true, + docID: 'helpDiskOfferingPublic' }, domainId: { label: 'label.domain', @@ -1132,7 +1165,9 @@ $(':ui-dialog').dialog('option', 'position', 'center'); - //hide/show service fields upon guestIpType(Shared/Isolated), zoneType(Advanced/Basic), having VpcVirtualRouter or not ***** (begin) ***** + //CS-16612 show all services regardless of guestIpType(Shared/Isolated) + /* + //hide/show service fields upon guestIpType(Shared/Isolated), having VpcVirtualRouter or not ***** (begin) ***** var serviceFieldsToHide = []; if($guestTypeField.val() == 'Shared') { //Shared network offering serviceFieldsToHide = [ @@ -1197,8 +1232,18 @@ } } } - //hide/show service fields upon guestIpType(Shared/Isolated), zoneType(Advanced/Basic), having VpcVirtualRouter or not ***** (end) ***** - + //hide/show service fields upon guestIpType(Shared/Isolated), having VpcVirtualRouter or not ***** (end) ***** + */ + + + //show LB InlineMode dropdown only when (1)LB Service is checked (2)Service Provider is F5 + if((args.$form.find('.form-item[rel=\"service.Lb.isEnabled\"]').find('input[type=checkbox]').is(':checked') == true) + &&(args.$form.find('.form-item[rel=\"service.Lb.provider\"]').find('select').val() == 'F5BigIp')) { + args.$form.find('.form-item[rel=\"service.Lb.inlineModeDropdown\"]').css('display', 'inline-block'); + } + else { + args.$form.find('.form-item[rel=\"service.Lb.inlineModeDropdown\"]').hide(); + } //show LB Isolation dropdown only when (1)LB Service is checked (2)Service Provider is Netscaler OR F5 (3)Guest IP Type is Isolated if((args.$form.find('.form-item[rel=\"service.Lb.isEnabled\"]').find('input[type=checkbox]').is(':checked') == true) @@ -1238,11 +1283,11 @@ args.$form.change(); }, fields: { - name: { label: 'label.name', validation: { required: true } }, + name: { label: 'label.name', validation: { required: true }, docID: 'helpNetworkOfferingName' }, displayText: { label: 'label.description', validation: { required: true } }, - networkRate: { label: 'label.network.rate' }, + networkRate: { label: 'label.network.rate.megabytes', docID: 'helpNetworkOfferingNetworkRate' }, /* trafficType: { @@ -1259,6 +1304,7 @@ guestIpType: { label: 'label.guest.type', + docID: 'helpNetworkOfferingGuestType', select: function(args) { args.response.success({ data: [ @@ -1280,7 +1326,7 @@ } }, - specifyVlan: { label: 'label.specify.vlan', isBoolean: true }, + specifyVlan: { label: 'label.specify.vlan', isBoolean: true, docID: 'helpNetworkOfferingSpecifyVLAN' }, useVpc: { label: 'VPC', @@ -1331,6 +1377,7 @@ case 'PortForwarding': serviceDisplayName = 'Port Forwarding'; break; case 'SecurityGroup': serviceDisplayName = 'Security Groups'; break; case 'UserData': serviceDisplayName = 'User Data'; break; + case 'Connectivity': serviceDisplayName = 'Virtual Networking'; break; default: serviceDisplayName = serviceName; break; } @@ -1483,6 +1530,12 @@ isHidden: true, isBoolean: true }, + associatePublicIP: { + label: 'Associate IP', + isBoolean: true, + isHidden: true, + dependsOn: 'service.Lb.elasticLbCheckbox' + }, "service.Lb.lbIsolationDropdown": { label: 'label.LB.isolation', isHidden: true, @@ -1494,7 +1547,16 @@ ] }) } - }, + }, + "service.Lb.inlineModeDropdown": { + label: 'Mode', + select: function(args) { + var items = []; + items.push({id: "false", description: "side by side"}); + items.push({id: "true", description: "inline"}); + args.response.success({data: items}); + } + }, "service.StaticNat.elasticIpCheckbox" : { label: "label.elastic.IP", isHidden: true, @@ -1557,6 +1619,14 @@ inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'ElasticLb'; inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = true; //because this checkbox's value == "on" serviceCapabilityIndex++; + } + else if ((key == 'service.Lb.inlineModeDropdown') && ("Lb" in serviceProviderMap) && (serviceProviderMap.Lb == "F5BigIp")) { + if(value == 'true') { //CS-16605 do not pass parameter if value is 'false'(side by side) + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'lb'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'InlineMode'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = value; + serviceCapabilityIndex++; + } } else if ((key == 'service.Lb.lbIsolationDropdown') && ("Lb" in serviceProviderMap)) { inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'lb'; @@ -1603,6 +1673,12 @@ } else { inputData['conservemode'] = false; } + + if (inputData['associatePublicIP'] == 'on') { + inputData['associatePublicIP'] = true; + } else { + inputData['associatePublicIP'] = false; + } // Make service provider map var serviceProviderIndex = 0; diff --git a/ui/scripts/dashboard.js b/ui/scripts/dashboard.js index ad67dff1e53..5f49e616b65 100644 --- a/ui/scripts/dashboard.js +++ b/ui/scripts/dashboard.js @@ -31,6 +31,9 @@ instances: function(data) { $.ajax({ url: createURL('listVirtualMachines'), + data: { + listAll: true + }, success: function(json) { var instances = json.listvirtualmachinesresponse.virtualmachine ? json.listvirtualmachinesresponse.virtualmachine : []; diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js new file mode 100755 index 00000000000..56d919d485a --- /dev/null +++ b/ui/scripts/docs.js @@ -0,0 +1,750 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. +cloudStack.docs = { + // Add account + helpAccountUsername: { + desc: 'Any desired login ID. Must be unique in the current domain. The same username can exist in other domains, including sub-domains.', + externalLink: '' + }, + helpAccountPassword: { + desc: 'Any desired password', + externalLink: '' + }, + helpAccountConfirmPassword: { + desc: 'Type the same password again', + externalLink: '' + }, + helpAccountEmail: { + desc: 'The account\'s email address', + externalLink: '' + }, + helpAccountFirstName: { + desc: 'The first name, also known as the given name, of a person; or the first part of the entity represented by the account, such as a customer or department', + externalLink: '' + }, + helpAccountLastName: { + desc: 'The last name, also known as the family name, of a person; or the second part of the name of a customer or department', + externalLink: '' + }, + helpAccountDomain: { + desc: 'Domain in which the account is to be created', + externalLink: '' + }, + helpAccountAccount: { + desc: 'Multiple users can exist in an account. Set the parent account name here.', + externalLink: '' + }, + helpAccountType: { + desc: 'Root admin can access all resources. Domain admin can access the domain\'s users, but not physical servers. User sees only their own resources, such as VMs.', + externalLink: '' + }, + helpAccountTimezone: { + desc: 'Set the time zone that corresponds to the account\'s locale', + externalLink: '' + }, + helpAccountNetworkDomain: { + desc: 'If you want to assign a special domain name to the account\'s guest VM network, specify the DNS suffix', + externalLink: '' + }, + // Add cluster + helpClusterZone: { + desc: 'The zone in which you want to create the cluster', + externalLink: '' + }, + helpClusterHypervisor: { + desc: 'The type of hypervisor software that runs on the hosts in this cluster. All hosts in a cluster run the same hypervisor.', + externalLink: '' + }, + helpClusterPod: { + desc: 'The pod in which you want to create the cluster', + externalLink: '' + }, + helpClusterName: { + desc: 'Any desired cluster name. Used for display only.', + externalLink: '' + }, + helpClustervCenterHost: { + desc: 'The hostname or IP address of the vCenter server', + externalLink: '' + }, + helpClustervCenterUsername: { + desc: 'ID of a user with all administrative privileges on vCenter', + externalLink: '' + }, + helpClustervCenterPassword: { + desc: 'Password of the user in Username', + externalLink: '' + }, + helpClustervCenterDatacenter: { + desc: 'The vCenter datacenter that the cluster is in. For example, cloud.dc.VM', + externalLink: '' + }, + // Add compute offering + helpComputeOfferingName: { + desc: 'Any desired name for the offering', + externalLink: '' + }, + helpComputeOfferingDescription: { + desc: 'A short description of the offering that can be displayed to users', + externalLink: '' + }, + helpComputeOfferingStorageType: { + desc: 'Type of disk for the VM. Local storage is attached to the hypervisor host where the VM is running. Shared storage is accessible via NFS.', + externalLink: '' + }, + helpComputeOfferingCPUCores: { + desc: 'The number of cores which should be allocated to a VM with this offering', + externalLink: '' + }, + helpComputeOfferingCPUMHz: { + desc: 'The CPU speed of the cores that the VM is allocated. For example, 2000 provides a 2 GHz clock.', + externalLink: '' + }, + helpComputeOfferingMemory: { + desc: 'The amount of memory in megabytes to allocate for the system VM. For example, 2048 provides 2 GB RAM.', + externalLink: '' + }, + helpComputeOfferingNetworkRate: { + desc: 'Allowed data transfer rate in MB per second', + externalLink: '' + }, + helpComputeOfferingHA: { + desc: 'If yes, the administrator can choose to have the VM be monitored and as highly available as possible', + externalLink: '' + }, + helpComputeOfferingStorageTags: { + desc: 'Comma-separated list of attributes that should be associated with the primary storage used by the VM. For example "ssd,blue".', + externalLink: '' + }, + helpComputeOfferingHostTags: { + desc: 'Any tags that you use to organize your hosts', + externalLink: '' + }, + helpComputeOfferingCPUCap: { + desc: 'If yes, the system will limit the level of CPU usage even if spare capacity is available', + externalLink: '' + }, + helpComputeOfferingPublic: { + desc: 'Yes makes the offering available to all domains. No limits the scope to a subdomain; you will be prompted for the subdomain\'s name.', + externalLink: '' + }, + helpComputeOfferingDomain: { + desc: 'The domain to associate this compute offering with' + }, + // Add disk offering + helpDiskOfferingName: { + desc: 'Any desired name for the offering', + externalLink: '' + }, + helpDiskOfferingDescription: { + desc: 'A short description of the offering that can be displayed to users', + externalLink: '' + }, + helpDiskOfferingStorageType: { + desc: 'Type of disk for the VM. Local is attached to the hypervisor host where the VM is running. Shared is storage accessible via NFS.', + externalLink: '' + }, + helpDiskOfferingCustomDiskSize: { + desc: 'If checked, the user can set their own disk size. If not checked, the root administrator must define a value in Disk Size.', + externalLink: '' + }, + helpDiskOfferingDiskSize: { + desc: 'Appears only if Custom Disk Size is not selected. Define the volume size in GB.', + externalLink: '' + }, + helpDiskOfferingStorageTags: { + desc: 'Comma-separated list of attributes that should be associated with the primary storage for this disk. For example "ssd,blue".', + externalLink: '' + }, + helpDiskOfferingPublic: { + desc: 'Yes makes the offering available to all domains. No limits the scope to a subdomain; you will be prompted for the subdomain\'s name.', + externalLink: '' + }, + // Add domain + helpDomainName: { + desc: 'Any desired name for the new sub-domain. Must be unique within the current domain.', + externalLink: '' + }, + helpDomainNetworkDomain: { + desc: 'If you want to assign a special domain name to this domain\'s guest VM network, specify the DNS suffix', + externalLink: '' + }, + // Add F5 + helpF5IPAddress: { + desc: 'The IP address of the device', + externalLink: '' + }, + helpF5Username: { + desc: 'A user ID with valid authentication credentials that provide to access the device', + externalLink: '' + }, + helpF5Password: { + desc: 'The password for the user ID provided in Username', + externalLink: '' + }, + helpF5Type: { + desc: 'The type of device that is being added', + externalLink: '' + }, + helpF5PublicInterface: { + desc: 'Interface of device that is configured to be part of the public network', + externalLink: '' + }, + helpF5PrivateInterface: { + desc: 'Interface of device that is configured to be part of the private network', + externalLink: '' + }, + helpF5Retries: { + desc: 'Number of times to attempt a command on the device before considering the operation failed. Default is 2.', + externalLink: '' + }, + helpF5Mode: { + desc: 'Side by side mode is supported for the F5.', + externalLink: '' + }, + helpF5Dedicated: { + desc: 'Check this box to dedicate the device to a single account. The value in the Capacity field will be ignored.', + externalLink: '' + }, + helpF5Capacity: { + desc: 'Number of guest networks/accounts that will share this device', + externalLink: '' + }, + // Add guest network + helpGuestNetworkName: { + desc: 'The name of the network. This will be user-visible.', + externalLink: '' + }, + helpGuestNetworkDisplayText: { + desc: 'The description of the network. This will be user-visible.', + externalLink: '' + }, + helpGuestNetworkZone: { + desc: 'The name of the zone this network applies to. The administrator must configure the IP range for the guest networks in each zone.', + externalLink: '' + }, + helpGuestNetworkNetworkOffering: { + desc: 'If the administrator has configured multiple network offerings, select the one you want to use for this network', + externalLink: '' + }, + helpGuestNetworkGateway: { + desc: 'The gateway that the guests should use.', + externalLink: '' + }, + helpGuestNetworkNetmask: { + desc: 'The netmask in use on the subnet the guests will use.', + externalLink: '' + }, + // Add guest network from zone + helpGuestNetworkZoneName: { + desc: 'The name of the network. This will be user-visible.', + externalLink: '' + }, + helpGuestNetworkZoneDescription: { + desc: 'The description of the network. This will be user-visible.', + externalLink: '' + }, + helpGuestNetworkZoneVLANID: { + desc: 'The VLAN tag for this network', + externalLink: '' + }, + helpGuestNetworkZoneScope: { + desc: 'Scope', + externalLink: '' + }, + helpGuestNetworkZoneNetworkOffering: { + desc: 'If the administrator has configured multiple network offerings, select the one you want to use for this network', + externalLink: '' + }, + helpGuestNetworkZoneGateway: { + desc: 'The gateway that the guests should use.', + externalLink: '' + }, + helpGuestNetworkZoneNetmask: { + desc: 'The netmask in use on the subnet the guests will use.', + externalLink: '' + }, + helpGuestNetworkZoneStartIP: { + desc: 'The first IP address to define a range that can be assigned to guests. We strongly recommend the use of multiple NICs.', + externalLink: '' + }, + helpGuestNetworkZoneEndIP: { + desc: 'The final IP address to define a range that can be assigned to guests. We strongly recommend the use of multiple NICs.', + externalLink: '' + }, + helpGuestNetworkZoneNetworkDomain: { + desc: 'If you want to assign a special domain name to this guest VM network, specify the DNS suffix', + externalLink: '' + }, + // Add host + helpHostZone: { + desc: 'The zone where you want to add the host', + externalLink: '' + }, + helpHostPod: { + desc: 'The pod where you want to add the host', + externalLink: '' + }, + helpHostCluster: { + desc: 'The cluster where you want to add the host', + externalLink: '' + }, + helpHostName: { + desc: 'The DNS name or IP address of the host', + externalLink: '' + }, + helpHostUsername: { + desc: 'Usually root', + externalLink: '' + }, + helpHostPassword: { + desc: 'The password for the user named in Username. The password was set during hypervisor installation on the host.', + externalLink: '' + }, + helpHostTags: { + desc: 'Any labels that you use to categorize hosts for ease of maintenance or to enable HA.', + externalLink: '' + }, + // Add Netscaler + helpNetScalerIPAddress: { + desc: 'The IP address of the device', + externalLink: '' + }, + helpNetScalerUsername: { + desc: 'A user ID with valid authentication credentials that provide to access the device', + externalLink: '' + }, + helpNetScalerPassword: { + desc: 'The password for the user ID provided in Username', + externalLink: '' + }, + helpNetScalerType: { + desc: 'The type of device that is being added', + externalLink: '' + }, + helpNetScalerPublicInterface: { + desc: 'Interface of device that is configured to be part of the public network', + externalLink: '' + }, + helpNetScalerPrivateInterface: { + desc: 'Interface of device that is configured to be part of the private network', + externalLink: '' + }, + helpNetScalerRetries: { + desc: 'Number of times to attempt a command on the device before considering the operation failed. Default is 2.', + externalLink: '' + }, + helpNetScalerDedicated: { + desc: 'Check this box to dedicate the device to a single account. The value in the Capacity field will be ignored.', + externalLink: '' + }, + helpNetScalerCapacity: { + desc: 'Number of guest networks/accounts that will share this device', + externalLink: '' + }, + // Add network offering + helpNetworkOfferingName: { + desc: 'Any desired name for the network offering', + externalLink: '' + }, + helpNetworkOfferingNetworkRate: { + desc: 'Allowed data transfer rate in MB per second', + externalLink: '' + }, + helpNetworkOfferingTrafficType: { + desc: 'The type of network traffic that will be carried on the network', + externalLink: '' + }, + helpNetworkOfferingGuestType: { + desc: 'Choose whether the guest network is isolated or shared.', + externalLink: '' + }, + helpNetworkOfferingSpecifyVLAN: { + desc: '(Isolated guest networks only) Indicate whether a VLAN should be specified when this offering is used', + externalLink: '' + }, + // Add pod + helpPodZone: { + desc: 'The zone where you want to add the pod', + externalLink: '' + }, + helpPodName: { + desc: 'Set a name for the pod', + externalLink: '' + }, + helpPodGateway: { + desc: 'The gateway for the hosts in the pod', + externalLink: '' + }, + helpPodNetmask: { + desc: 'The network prefix that defines the pod\'s subnet. Use CIDR notation.', + externalLink: '' + }, + helpPodStartIP: { + desc: 'The first IP address to define a range in the management network that is used to manage various system VMs', + externalLink: '' + }, + helpPodEndIP: { + desc: 'The last IP address to define a range in the management network that is used to manage various system VMs', + externalLink: '' + }, + // Add primary storage + helpPrimaryStorageZone: { + desc: 'The zone in which you want to create the primary storage', + externalLink: '' + }, + helpPrimaryStoragePod: { + desc: 'The pod in which you want to create the primary storage', + externalLink: '' + }, + helpPrimaryStorageCluster: { + desc: 'The cluster in which you want to create the primary storage', + externalLink: '' + }, + helpPrimaryStorageName: { + desc: 'The name of the storage device', + externalLink: '' + }, + helpPrimaryStorageProtocol: { + desc: 'For XenServer, choose NFS, iSCSI, or PreSetup. For KVM, choose NFS or SharedMountPoint. For vSphere, choose VMFS (iSCSI or FiberChannel) or NFS.', + externalLink: '' + }, + helpPrimaryStorageServer: { + desc: 'NFS, iSCSI, or PreSetup: IP address or DNS name of the storage device. VMFS: IP address or DNS name of the vCenter server.', + externalLink: '' + }, + helpPrimaryStoragePath: { + desc: 'NFS: exported path from the server. VMFS: /datacenter name/datastore name. SharedMountPoint: path where primary storage is mounted, such as "/mnt/primary"', + externalLink: '' + }, + helpPrimaryStorageSRNameLabel: { + desc: 'The name-label of the SR that has been set up independently of the cloud management system', + externalLink: '' + }, + helpPrimaryStorageTargetIQN: { + desc: 'In iSCSI, this is the IQN of the target. For example, iqn.1986-03.com.sun:02:01ec9bb549-1271378984', + externalLink: '' + }, + helpPrimaryStorageLun: { + desc: 'In iSCSI, this is the LUN number. For example, 3.', + externalLink: '' + }, + helpPrimaryStorageTags: { + desc: 'Comma-separated list of tags for this storage device. Must be the same set or a superset of the tags on your disk offerings.', + externalLink: '' + }, + // Add secondary storage + helpSecondaryStorageZone: { + desc: 'The zone in which you want to create the secondary storage', + externalLink: '' + }, + helpSecondaryStorageNFSServer: { + desc: 'The IP address of the server', + externalLink: '' + }, + helpSecondaryStoragePath: { + desc: 'The exported path from the server', + externalLink: '' + }, + // Add SRX + helpSRXIPAddress: { + desc: 'The IP address of the device', + externalLink: '' + }, + helpSRXUsername: { + desc: 'A user ID with valid authentication credentials that provide to access the device', + externalLink: '' + }, + helpSRXPassword: { + desc: 'The password for the user ID provided in Username', + externalLink: '' + }, + helpSRXType: { + desc: 'The type of device that is being added', + externalLink: '' + }, + helpSRXPublicInterface: { + desc: 'Interface of device that is configured to be part of the public network. For example, ge-0/0/2', + externalLink: '' + }, + helpSRXPrivateInterface: { + desc: 'Interface of device that is configured to be part of the private network. For example, ge-0/0/1', + externalLink: '' + }, + helpSRXUsageInterface: { + desc: 'Interface used to meter traffic. If you don\'t want to use the public interface, specify a different interface name here.', + externalLink: '' + }, + helpSRXRetries: { + desc: 'Number of times to attempt a command on the device before considering the operation failed. Default is 2.', + externalLink: '' + }, + helpSRXTimeout: { + desc: 'The time to wait for a command on the SRX before considering it failed. Default is 300 seconds.', + externalLink: '' + }, + helpSRXMode: { + desc: 'Side by side mode is supported for the SRX.', + externalLink: '' + }, + helpSRXPublicNetwork: { + desc: 'The name of the public network on the SRX. For example, trust.', + externalLink: '' + }, + helpSRXPrivateNetwork: { + desc: 'The name of the private network on the SRX. For example, untrust.', + externalLink: '' + }, + helpSRXDedicated: { + desc: 'Check this box to dedicate the device to a single account. The value in the Capacity field will be ignored.', + externalLink: '' + }, + helpSRXCapacity: { + desc: 'Number of guest networks/accounts that will share this device', + externalLink: '' + }, + // Add system service offering + helpSystemOfferingName: { + desc: 'Any desired name for the offering', + externalLink: '' + }, + helpSystemOfferingDescription: { + desc: 'A short description of the offering that can be displayed to the root administrator', + externalLink: '' + }, + helpSystemOfferingVMType: { + desc: 'The type of system VM that is being offered', + externalLink: '' + }, + helpSystemOfferingStorageType: { + desc: 'Type of disk for the system VM. Local storage is attached to the host where the system VM is running. Shared storage is accessible via NFS.', + externalLink: '' + }, + helpSystemOfferingCPUCores: { + desc: 'The number of cores which should be allocated to a system VM with this offering', + externalLink: '' + }, + helpSystemOfferingCPUMHz: { + desc: 'The CPU speed of the cores that the system VM is allocated. For example, 2000 would provide for a 2 GHz clock.', + externalLink: '' + }, + helpSystemOfferingMemory: { + desc: 'The amount of memory in megabytes to allocate for the system VM. For example, 2048 provides 2 GB RAM.', + externalLink: '' + }, + helpSystemOfferingNetworkRate: { + desc: 'Allowed data transfer rate in MB per second', + externalLink: '' + }, + helpSystemOfferingHA: { + desc: 'If yes, the administrator can choose to have the system VM be monitored and as highly available as possible', + externalLink: '' + }, + helpSystemOfferingStorageTags: { + desc: 'Comma-separated list of attributes that should be associated with the primary storage used by the system VM. For example "ssd,blue".', + externalLink: '' + }, + helpSystemOfferingHostTags: { + desc: 'Any tags that you use to organize your hosts', + externalLink: '' + }, + helpSystemOfferingCPUCap: { + desc: 'If yes, the system will limit the level of CPU usage even if spare capacity is available', + externalLink: '' + }, + helpSystemOfferingPublic: { + desc: 'Yes makes the offering available to all domains. No limits the scope to a subdomain; you will be prompted for the subdomain\'s name.', + externalLink: '' + }, + // Add tier + helpTierName: { + desc: 'A unique name for the tier', + externalLink: '' + }, + helpTierNetworkOffering: { + desc: 'If the administrator has configured multiple network offerings, select the one you want to use for this tier', + externalLink: '' + }, + helpTierGateway: { + desc: 'The gateway for the tier. Must be in the Super CIDR range of the VPC and not overlapping the CIDR of any other tier in this VPC.', + externalLink: '' + }, + helpTierNetmask: { + desc: 'Netmask for the tier. For example, with VPC CIDR of 10.0.0.0/16 and network tier CIDR of 10.0.1.0/24, gateway is 10.0.1.1 and netmask is 255.255.255.0', + externalLink: '' + }, + // Add user + helpUserUsername: { + desc: 'Any desired user ID. Must be unique in the current domain. The same username can exist in other domains, including sub-domains.', + externalLink: '' + }, + helpUserPassword: { + desc: 'Any desired user password', + externalLink: '' + }, + helpUserConfirmPassword: { + desc: 'Type the same password again', + externalLink: '' + }, + helpUserEmail: { + desc: 'The user\'s email address', + externalLink: '' + }, + helpUserFirstName: { + desc: 'The user\'s first name, also known as the given name', + externalLink: '' + }, + helpUserLastName: { + desc: 'The user\'s last name, also known as the family name', + externalLink: '' + }, + helpUserTimezone: { + desc: 'Set the time zone that corresponds to the user\'s locale', + externalLink: '' + }, + // Add volume + helpVolumeName: { + desc: 'Give the volume a unique name so you can find it later.', + externalLink: '' + }, + helpVolumeAvailabilityZone: { + desc: 'Where do you want the storage to reside? This should be close to the VM that will use the volume.', + externalLink: '' + }, + helpVolumeDiskOffering: { + desc: 'Choose the characteristics of the storage.', + externalLink: '' + }, + // Add VPC + helpVPCName: { + desc: 'A name for the new VPC', + externalLink: '' + }, + helpVPCDescription: { + desc: 'Display text about the VPC', + externalLink: '' + }, + helpVPCZone: { + desc: 'Zone where you want the VPC to be available', + externalLink: '' + }, + helpVPCSuperCIDR: { + desc: 'CIDR range for all the tiers within a VPC. Each tier\'s CIDR must be within the Super CIDR.', + externalLink: '' + }, + helpVPCDomain: { + desc: 'If you want to assign a special domain name to this VPC\'s guest VM network, specify the DNS suffix', + externalLink: '' + }, + // Add VPC gateway + helpVPCGatewayPhysicalNetwork: { + desc: 'Name of a physical network that has been created in the zone', + externalLink: '' + }, + helpVPCGatewayVLAN: { + desc: 'The VLAN associated with the VPC gateway', + externalLink: '' + }, + helpVPCGatewayIP: { + desc: 'The IP address associated with the VPC gateway', + externalLink: '' + }, + helpVPCGatewayGateway: { + desc: 'The gateway through which the traffic is routed to and from the VPC', + externalLink: '' + }, + helpVPCGatewayNetmask: { + desc: 'The netmask associated with the VPC gateway', + externalLink: '' + }, + // Copy template + helpCopyTemplateDestination: { + desc: 'The zone to which you want to copy the template', + externalLink: '' + }, + // Register template + helpRegisterTemplate: { + desc: '', + externalLink: '' + }, + // Register template + helpRegisterTemplateName: { + desc: 'A unique name for the template. This will be visible to users, so choose something descriptive.', + externalLink: '' + }, + helpRegisterTemplateDescription: { + desc: 'Display text describing the template. This will be visible to users, so choose something descriptive.', + externalLink: '' + }, + helpRegisterTemplateURL: { + desc: 'The Management Server will download the file from the specified URL, such as http://my.web.server/filename.vhd.gz', + externalLink: '' + }, + helpRegisterTemplateZone: { + desc: 'Choose the zone where you want the template to be available, or All Zones to make it available throughout the cloud', + externalLink: '' + }, + helpRegisterTemplateHypervisor: { + desc: 'The hypervisor software from which this template is being imported; this determines the value of Format', + externalLink: '' + }, + helpRegisterTemplateFormat: { + desc: 'The data format of the template upload file', + externalLink: '' + }, + helpRegisterTemplateOSType: { + desc: 'Operating system of the VM represented by the template. If the OS type of the template is not listed, choose Other.', + externalLink: '' + }, + helpRegisterTemplateExtractable: { + desc: 'Whether the template is extractable or not', + externalLink: '' + }, + helpRegisterTemplatePasswordEnabled: { + desc: 'Check this if the template has the password change script installed.', + externalLink: '' + }, + helpRegisterTemplatePublic: { + desc: 'Check this to make the template accessible to all users. The template will appear in the Community Templates list.', + externalLink: '' + }, + helpRegisterTemplateFeatured: { + desc: 'Check this to make the template more prominent for users. The template will appear in the Featured Templates list.', + externalLink: '' + }, + // Upload volume + helpUploadVolumeName: { + desc: 'A unique name for the volume. This will be visible to users, so choose something descriptive.', + externalLink: '' + }, + helpUploadVolumeZone: { + desc: 'Choose the zone where you want to store the volume. VMs running on hosts in this zone can attach the volume.', + externalLink: '' + }, + helpUploadVolumeFormat: { + desc: 'The disk image format of the volume. XenServer is VHD, VMware is OVA, and KVM is QCOW2.', + externalLink: '' + }, + helpUploadVolumeURL: { + desc: 'Secure HTTP or HTTPS URL that can be used to get the disk. File type must match Format. For example, if Format is VHD, http://yourFileServerIP/userdata/myDataDisk.vhd', + externalLink: '' + }, + helpUploadVolumeChecksum: { + desc: 'Use the hash that you created at the start of the volume upload procedure', + externalLink: '' + } +}; diff --git a/ui/scripts/domains.js b/ui/scripts/domains.js index 3383c574e61..e6633397925 100644 --- a/ui/scripts/domains.js +++ b/ui/scripts/domains.js @@ -97,66 +97,92 @@ }, action: function(args) { var domainObj; - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&networkdomain=" + todb(args.data.networkdomain)); + + var data = { + id: args.context.domains[0].id, + networkdomain: args.data.networkdomain + }; + + if(args.data.name != null) { + $.extend(data, { + name: args.data.name + }); + } + $.ajax({ - url: createURL("updateDomain&id=" + args.context.domains[0].id + array1.join("")), + url: createURL("updateDomain"), async: false, - dataType: "json", + data: data, success: function(json) { domainObj = json.updatedomainresponse.domain; } }); - $.ajax({ - url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=0&max=" + args.data.vmLimit), - dataType: "json", - async: false, - success: function(json) { - domainObj["vmLimit"] = args.data.vmLimit; - } - }); - $.ajax({ - url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=1&max=" + args.data.ipLimit), - dataType: "json", - async: false, - success: function(json) { - domainObj["ipLimit"] = args.data.ipLimit; - } - }); - $.ajax({ - url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=2&max=" + args.data.volumeLimit), - dataType: "json", - async: false, - success: function(json) { - domainObj["volumeLimit"] = args.data.volumeLimit; - } - }); - $.ajax({ - url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=3&max=" + args.data.snapshotLimit), - dataType: "json", - async: false, - success: function(json) { - domainObj["snapshotLimit"] = args.data.snapshotLimit; - } - }); - $.ajax({ - url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=4&max=" + args.data.templateLimit), - dataType: "json", - async: false, - success: function(json) { - domainObj["templateLimit"] = args.data.templateLimit; - } - }); - $.ajax({ - url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=7&max=" + args.data.vpcLimit), - dataType: "json", - async: false, - success: function(json) { - domainObj["vpcLimit"] = args.data.vpcLimit; - } - }); + if(args.data.vmLimit != null) { + $.ajax({ + url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=0&max=" + args.data.vmLimit), + dataType: "json", + async: false, + success: function(json) { + domainObj["vmLimit"] = args.data.vmLimit; + } + }); + } + + if(args.data.ipLimit != null) { + $.ajax({ + url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=1&max=" + args.data.ipLimit), + dataType: "json", + async: false, + success: function(json) { + domainObj["ipLimit"] = args.data.ipLimit; + } + }); + } + + if(args.data.volumeLimit != null) { + $.ajax({ + url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=2&max=" + args.data.volumeLimit), + dataType: "json", + async: false, + success: function(json) { + domainObj["volumeLimit"] = args.data.volumeLimit; + } + }); + } + + if(args.data.snapshotLimit != null) { + $.ajax({ + url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=3&max=" + args.data.snapshotLimit), + dataType: "json", + async: false, + success: function(json) { + domainObj["snapshotLimit"] = args.data.snapshotLimit; + } + }); + } + + if(args.data.templateLimit != null) { + $.ajax({ + url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=4&max=" + args.data.templateLimit), + dataType: "json", + async: false, + success: function(json) { + domainObj["templateLimit"] = args.data.templateLimit; + } + }); + } + + if(args.data.vpcLimit != null) { + $.ajax({ + url: createURL("updateResourceLimit&domainid=" + args.context.domains[0].id + "&resourceType=7&max=" + args.data.vpcLimit), + dataType: "json", + async: false, + success: function(json) { + domainObj["vpcLimit"] = args.data.vpcLimit; + } + }); + } args.response.success({data: domainObj}); } @@ -200,10 +226,12 @@ fields: { name: { label: 'label.name', + docID: 'helpDomainName', validation: { required: true } }, networkdomain: { label: 'label.network.domain', + docID: 'helpDomainNetworkDomain', validation: { required: false } } } @@ -243,7 +271,15 @@ title: 'label.details', fields: [ { - name: { label: 'label.name', isEditable: true } + name: { + label: 'label.name', + isEditable: function(context) { + if(context.domains[0].level != 0) //ROOT domain (whose level is 0) is not allowed to change domain name + return true; + else + return false; + } + } }, { id: { label: 'ID' }, @@ -256,27 +292,57 @@ }, vmLimit: { label: 'label.instance.limits', - isEditable: true + isEditable: function(context) { + if(context.domains[0].level != 0) //ROOT domain (whose level is 0) is not allowed to updateResourceLimits + return true; + else + return false; + } }, ipLimit: { label: 'label.ip.limits', - isEditable: true + isEditable: function(context) { + if(context.domains[0].level != 0) //ROOT domain (whose level is 0) is not allowed to updateResourceLimits + return true; + else + return false; + } }, volumeLimit: { label: 'label.volume.limits', - isEditable: true + isEditable: function(context) { + if(context.domains[0].level != 0) //ROOT domain (whose level is 0) is not allowed to updateResourceLimits + return true; + else + return false; + } }, snapshotLimit: { label: 'label.snapshot.limits', - isEditable: true + isEditable: function(context) { + if(context.domains[0].level != 0) //ROOT domain (whose level is 0) is not allowed to updateResourceLimits + return true; + else + return false; + } }, templateLimit: { label: 'label.template.limits', - isEditable: true + isEditable: function(context) { + if(context.domains[0].level != 0) //ROOT domain (whose level is 0) is not allowed to updateResourceLimits + return true; + else + return false; + } }, vpcLimit: { label: 'VPC limits', - isEditable: true + isEditable: function(context) { + if(context.domains[0].level != 0) //ROOT domain (whose level is 0) is not allowed to updateResourceLimits + return true; + else + return false; + } }, accountTotal: { label: 'label.accounts' }, vmTotal: { label: 'label.instances' }, @@ -288,7 +354,9 @@ $.ajax({ url: createURL("listAccounts&domainid=" + domainObj.id), async: false, - dataType: "json", + data: { + details: 'min' + }, success: function(json) { var items = json.listaccountsresponse.account; var total; @@ -297,10 +365,21 @@ else total = 0; domainObj["accountTotal"] = total; + var itemsAcc; + var totalVMs=0; + var totalVolumes=0; + for(var i=0;i 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } + + advSearchFields: { + level: { + label: 'label.level', + select: function(args) { + args.response.success({ + data: [ + {id: '', description: ''}, + {id: 'INFO', description: 'INFO'}, + {id: 'WARN', description: 'WARN'}, + {id: 'ERROR', description: 'ERROR'} + ] + }); } + }, + + domainid: { + label: 'Domain', + select: function(args) { + if(isAdmin() || isDomainAdmin()) { + $.ajax({ + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, + success: function(json) { + var array1 = [{id: '', description: ''}]; + var domains = json.listdomainsresponse.domain; + if(domains != null && domains.length > 0) { + for(var i = 0; i < domains.length; i++) { + array1.push({id: domains[i].id, description: domains[i].path}); + } + } + args.response.success({ + data: array1 + }); + } + }); + } + else { + args.response.success({ + data: null + }); + } + }, + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + + account: { + label: 'Account', + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } } + /* + , + startdate: { + label: 'Start Date', + isDatepicker: true + }, + enddate: { + label: 'End Date', + isDatepicker: true + } + */ + }, + + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); $.ajax({ - url: createURL("listEvents&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", - async: true, + url: createURL('listEvents'), + data: data, success: function(json) { var items = json.listeventsresponse.event; args.response.success({data:items}); @@ -70,9 +137,15 @@ title: 'label.details', fields: [ { - type: { label: 'label.type' }, - description: { label: 'label.description' }, - created: { label: 'label.date', converter: cloudStack.converters.toLocalDate } + description: { label: 'label.description' }, + state: { label: 'label.state' }, + level: { label: 'label.level' }, + type: { label: 'label.type' }, + domain: { label: 'label.domain' }, + account: { label: 'label.account' }, + username: { label: 'label.initiated.by' }, + created: { label: 'label.date', converter: cloudStack.converters.toLocalDate }, + id: { label: 'label.id' } } ], dataProvider: function(args) { @@ -102,20 +175,12 @@ sent: { label: 'label.date', converter: cloudStack.converters.toLocalDate } }, dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } + var data = {}; + listViewDataProvider(args, data); + $.ajax({ - url: createURL("listAlerts&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", + url: createURL('listAlerts'), + data: data, async: true, success: function(json) { var items = json.listalertsresponse.alert; diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index 5e4423fbf59..b35369db9d7 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -523,7 +523,11 @@ if(args.context.networks != null) { //from VPC tier array1.push("&networkIds=" + args.context.networks[0].id); array1.push("&domainid=" + args.context.vpc[0].domainid); - array1.push("&account=" + args.context.vpc[0].account); + + if(args.context.vpc[0].account != null) + array1.push("&account=" + args.context.vpc[0].account); + else if(args.context.vpc[0].projectid != null) + array1.push("&projectid=" + args.context.vpc[0].projectid); } } diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index b18d44c6bbc..68e081eed80 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -42,9 +42,10 @@ } return hiddenFields; }, - fields: { - displayname: { label: 'label.display.name' }, + fields: { + name: { label: 'label.name' }, instancename: { label: 'label.internal.name' }, + displayname: { label: 'label.display.name' }, zonename: { label: 'label.zone.name' }, state: { label: 'label.state', @@ -56,7 +57,84 @@ } } }, + + advSearchFields: { + name: { label: 'Name' }, + zoneid: { + label: 'Zone', + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); + } + }, + + domainid: { + label: 'Domain', + select: function(args) { + if(isAdmin() || isDomainAdmin()) { + $.ajax({ + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, + success: function(json) { + var array1 = [{id: '', description: ''}]; + var domains = json.listdomainsresponse.domain; + if(domains != null && domains.length > 0) { + for(var i = 0; i < domains.length; i++) { + array1.push({id: domains[i].id, description: domains[i].path}); + } + } + args.response.success({ + data: array1 + }); + } + }); + } + else { + args.response.success({ + data: null + }); + } + }, + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + account: { + label: 'Account', + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + // List view actions actions: { // Add instance wizard @@ -75,235 +153,54 @@ notification: { poll: pollAsyncJobResult } - }, - start: { - label: 'label.action.start.instance' , - action: function(args) { - $.ajax({ - url: createURL("startVirtualMachine&id=" + args.context.instances[0].id), - dataType: "json", - async: true, - success: function(json) { - var jid = json.startvirtualmachineresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.virtualmachine; - }, - getActionFilter: function() { - return vmActionfilter; - } - } - } - ); - } - }); - }, - messages: { - confirm: function(args) { - return 'message.action.start.instance'; - }, - notification: function(args) { - return 'label.action.start.instance'; - }, - complete: function(args) { - if(args.password != null) { - alert('Password of the VM is ' + args.password); - } - return 'label.action.start.instance'; - } - }, - notification: { - poll: pollAsyncJobResult - } - }, - stop: { - label: 'label.action.stop.instance', - addRow: 'false', - createForm: { - title: 'label.action.stop.instance', - desc: 'message.action.stop.instance', - fields: { - forced: { - label: 'force.stop', - isBoolean: true, - isChecked: false - } - } - }, - action: function(args) { - var array1 = []; - array1.push("&forced=" + (args.data.forced == "on")); - $.ajax({ - url: createURL("stopVirtualMachine&id=" + args.context.instances[0].id + array1.join("")), - dataType: "json", - async: true, - success: function(json) { - var jid = json.stopvirtualmachineresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.virtualmachine; - }, - getActionFilter: function() { - return vmActionfilter; - } - } - } - ); - } - }); - }, - messages: { - confirm: function(args) { - return 'message.action.stop.instance'; - }, - - notification: function(args) { - return 'label.action.stop.instance'; - } - }, - notification: { - poll: pollAsyncJobResult - } - }, - restart: { - label: 'instances.actions.reboot.label', - action: function(args) { - $.ajax({ - url: createURL("rebootVirtualMachine&id=" + args.context.instances[0].id), - dataType: "json", - async: true, - success: function(json) { - var jid = json.rebootvirtualmachineresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.virtualmachine; - }, - getActionFilter: function() { - return vmActionfilter; - } - } - } - ); - } - }); - }, - messages: { - confirm: function(args) { - return 'message.action.reboot.instance'; - }, - notification: function(args) { - return 'instances.actions.reboot.label'; - } - }, - notification: { - poll: pollAsyncJobResult - } - }, - destroy: { - label: 'label.action.destroy.instance', - messages: { - confirm: function(args) { - return 'message.action.destroy.instance'; - }, - notification: function(args) { - return 'label.action.destroy.instance'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("destroyVirtualMachine&id=" + args.context.instances[0].id), - dataType: "json", - async: true, - success: function(json) { - var jid = json.destroyvirtualmachineresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.virtualmachine; - }, - getActionFilter: function() { - return vmActionfilter; - } - } - } - ); - } - }); - }, - notification: { - poll: pollAsyncJobResult - } - }, - restore: { - label: 'label.action.restore.instance', - messages: { - confirm: function(args) { - return 'message.action.restore.instance'; - }, - notification: function(args) { - return 'label.action.restore.instance'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("recoverVirtualMachine&id=" + args.context.instances[0].id), - dataType: "json", - async: true, - success: function(json) { - var item = json.recovervirtualmachineresponse.virtualmachine; - args.response.success({data:item}); - } - }); - } } }, dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.kind != null) { - switch(args.filterBy.kind) { - case "all": - array1.push("&listAll=true"); - break; - case "mine": - if (!args.context.projects) array1.push("&domainid=" + g_domainid + "&account=" + g_account); - break; - case "running": - array1.push("&listAll=true&state=Running"); - break; - case "stopped": - array1.push("&listAll=true&state=Stopped"); - break; - case "destroyed": - array1.push("&listAll=true&state=Destroyed"); - break; - } - } - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - - if("hosts" in args.context) - array1.push("&hostid=" + args.context.hosts[0].id); - + var data = {}; + listViewDataProvider(args, data); + + if(args.filterBy != null) { //filter dropdown + if(args.filterBy.kind != null) { + switch(args.filterBy.kind) { + case "all": + break; + case "mine": + if (!args.context.projects) { + $.extend(data, { + domainid: g_domainid, + account: g_account + }); + } + break; + case "running": + $.extend(data, { + state: 'Running' + }); + break; + case "stopped": + $.extend(data, { + state: 'Stopped' + }); + break; + case "destroyed": + $.extend(data, { + state: 'Destroyed' + }); + break; + } + } + } + + if("hosts" in args.context) { + $.extend(data, { + hostid: args.context.hosts[0].id + }); + } + $.ajax({ - url: createURL("listVirtualMachines&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", - async: true, + url: createURL('listVirtualMachines'), + data: data, success: function(json) { var items = json.listvirtualmachinesresponse.virtualmachine; @@ -402,6 +299,7 @@ }, stop: { label: 'label.action.stop.instance', + compactLabel: 'label.stop', createForm: { title: 'Stop instance', desc: 'message.action.stop.instance', @@ -451,6 +349,7 @@ }, restart: { label: 'label.action.reboot.instance', + compactLabel: 'label.reboot', action: function(args) { $.ajax({ url: createURL("rebootVirtualMachine&id=" + args.context.instances[0].id), @@ -487,6 +386,7 @@ }, destroy: { label: 'label.action.destroy.instance', + compactLabel: 'label.destroy', messages: { confirm: function(args) { return 'message.action.destroy.instance'; @@ -523,6 +423,7 @@ }, restore: { label: 'label.action.restore.instance', + compactLabel: 'label.restore', messages: { confirm: function(args) { return 'message.action.restore.instance'; @@ -550,19 +451,23 @@ }, edit: { - label: 'Edit', + label: 'label.edit', action: function(args) { - var array1 = []; - if(args.data.displayname != args.context.instances[0].displayname) - array1.push("&displayName=" + args.data.displayname); - - array1.push("&group=" + args.data.group); - array1.push("&ostypeid=" + args.data.guestosid); - //array1.push("&haenable=" + haenable); + var data = { + id: args.context.instances[0].id, + group: args.data.group, + ostypeid: args.data.guestosid + }; + + if(args.data.displayname != args.context.instances[0].displayname) { + $.extend(data, { + displayName: args.data.displayname + }); + } $.ajax({ - url: createURL("updateVirtualMachine&id=" + args.context.instances[0].id + array1.join("")), - dataType: "json", + url: createURL('updateVirtualMachine'), + data: data, success: function(json) { var item = json.updatevirtualmachineresponse.virtualmachine; args.response.success({data:item}); @@ -848,31 +753,19 @@ url: { label: 'image.directory', validation: { required: true } } } }, - action: function(args) { - /* - var isValid = true; - isValid &= validateString("Name", $thisDialog.find("#create_template_name"), $thisDialog.find("#create_template_name_errormsg")); - isValid &= validateString("Display Text", $thisDialog.find("#create_template_desc"), $thisDialog.find("#create_template_desc_errormsg")); - isValid &= validateString("Image Directory", $thisDialog.find("#image_directory"), $thisDialog.find("#image_directory_errormsg"), false); //image directory is required when creating template from VM whose hypervisor is BareMetal - if (!isValid) - return; - $thisDialog.dialog("close"); - */ - - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displayText=" + todb(args.data.displayText)); - array1.push("&osTypeId=" + args.data.osTypeId); - - //array1.push("&isPublic=" + args.data.isPublic); - array1.push("&isPublic=" + (args.data.isPublic=="on")); //temporary, before Brian fixes it. - - array1.push("&url=" + todb(args.data.url)); - + action: function(args) { + var data = { + virtualmachineid: args.context.instances[0].id, + name: args.data.name, + displayText: args.data.displayText, + osTypeId: args.data.osTypeId, + isPublic: (args.data.isPublic=="on"), + url: args.data.url + }; + $.ajax({ - url: createURL("createTemplate&virtualmachineid=" + args.context.instances[0].id + array1.join("")), - dataType: "json", - async: true, + url: createURL('createTemplate'), + data: data, success: function(json) { var jid = json.createtemplateresponse.jobid; args.response.success( @@ -897,6 +790,7 @@ migrate: { label: 'label.migrate.instance.to.host', + compactLabel: 'label.migrate.to.host', messages: { confirm: function(args) { return 'message.migrate.instance.to.host'; @@ -975,6 +869,7 @@ migrateToAnotherStorage: { label: 'label.migrate.instance.to.ps', + compactLabel: 'label.migrate.to.storage', messages: { confirm: function(args) { return 'message.migrate.instance.to.ps'; @@ -1079,14 +974,14 @@ fields: [ { displayname: { label: 'label.display.name', isEditable: true }, - instancename: { label: 'label.internal.name' }, + name: { label: 'label.host.name' }, state: { label: 'label.state', pollAgainIfValueIsIn: { 'Starting': 1, 'Stopping': 1 }, - pollAgainFn: function(context) { //??? + pollAgainFn: function(context) { var toClearInterval = false; $.ajax({ url: createURL("listVirtualMachines&id=" + context.instances[0].id), diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 1a7769a42cb..08307010482 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -16,6 +16,25 @@ // under the License. (function(cloudStack, $) { + var ingressEgressDataMap = function(elem) { + var elemData = { + id: elem.ruleid, + protocol: elem.protocol, + startport: elem.startport, + endport: elem.endport, + cidr: elem.cidr ? elem.cidr : ''.concat(elem.account, ' - ', elem.securitygroupname) + }; + + if (elemData.startport == 0 && elemData.endport) { + elemData.startport = '0'; + } else if (elem.icmptype && elem.icmpcode) { + elemData.startport = elem.icmptype; + elemData.endport = elem.icmpcode; + } + + return elemData; + }; + var ipChangeNotice = function() { cloudStack.dialog.confirm({ message: 'message.ip.address.changed', @@ -191,7 +210,8 @@ url: createURL('listNetworks', { ignoreProject: true }), data: { supportedServices: 'SecurityGroup', - listAll: true + listAll: true, + details: 'min' }, async: false, success: function(data) { @@ -207,6 +227,7 @@ sectionsToShow.push('vpc'); sectionsToShow.push('vpnCustomerGateway'); } + if(havingSecurityGroupNetwork == true) sectionsToShow.push('securityGroups'); @@ -251,12 +272,12 @@ title: 'label.add.guest.network', desc: 'message.add.guest.network', fields: { - name: { label: 'label.name', validation: { required: true } }, - displayText: { label: 'label.display.text', validation: { required: true }}, + name: { label: 'label.name', validation: { required: true }, docID: 'helpGuestNetworkName' }, + displayText: { label: 'label.display.text', validation: { required: true }, docID: 'helpGuestNetworkDisplayText'}, zoneId: { label: 'label.zone', validation: { required: true }, - + docID: 'helpGuestNetworkZone', select: function(args) { $.ajax({ @@ -281,26 +302,42 @@ networkOfferingId: { label: 'label.network.offering', validation: { required: true }, - dependsOn: 'zoneId', - select: function(args) { + dependsOn: 'zoneId', + docID: 'helpGuestNetworkNetworkOffering', + select: function(args) { $.ajax({ - url: createURL('listNetworkOfferings&zoneid=' + args.zoneId), + url: createURL('listVPCs'), data: { - guestiptype: 'Isolated', - supportedServices: 'SourceNat', - specifyvlan: false, - state: 'Enabled' + listAll: true }, success: function(json) { - networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; - args.response.success({ - data: $.map(networkOfferingObjs, function(zone) { - return { - id: zone.id, - description: zone.name - }; - }) - }); + var items = json.listvpcsresponse.vpc; + var baseUrl = 'listNetworkOfferings&zoneid=' + args.zoneId; + var listUrl; + if(items != null && items.length > 0) + listUrl = baseUrl; + else + listUrl = baseUrl + '&forVpc=false'; + $.ajax({ + url: createURL(listUrl), + data: { + guestiptype: 'Isolated', + supportedServices: 'SourceNat', + specifyvlan: false, + state: 'Enabled' + }, + success: function(json) { + networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; + args.response.success({ + data: $.map(networkOfferingObjs, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); } }); } @@ -311,6 +348,7 @@ dependsOn: 'networkOfferingId', select: function(args) { var networkOfferingObj; + var $form = args.$select.closest('form'); $(networkOfferingObjs).each(function(key, value) { if(value.id == args.networkOfferingId) { networkOfferingObj = value; @@ -322,7 +360,8 @@ $.ajax({ url: createURL('listVPCs'), data: { - listAll: true + listAll: true, + details: 'min' }, success: function(json) { var items = json.listvpcsresponse.vpc; @@ -338,40 +377,50 @@ args.response.success({ data: data }); } }); + $form.find('.form-item[rel=networkDomain]').hide(); } else { args.$select.closest('.form-item').hide(); + $form.find('.form-item[rel=networkDomain]').show(); args.response.success({ data: null }); } } }, - guestGateway: { label: 'label.guest.gateway' }, - guestNetmask: { label: 'label.guest.netmask' } + guestGateway: { label: 'label.guest.gateway', docID: 'helpGuestNetworkGateway' }, + guestNetmask: { label: 'label.guest.netmask', docID: 'helpGuestNetworkNetmask' }, + networkDomain: { label: 'label.network.domain' } } }, action: function(args) { - var dataObj = { - zoneId: args.data.zoneId, - name: args.data.name, - displayText: args.data.displayText, - networkOfferingId: args.data.networkOfferingId - }; + var dataObj = { + zoneId: args.data.zoneId, + name: args.data.name, + displayText: args.data.displayText, + networkOfferingId: args.data.networkOfferingId + }; + if(args.data.guestGateway != null && args.data.guestGateway.length > 0) { - $.extend(dataObj, { - gateway: args.data.guestGateway - }); - } + $.extend(dataObj, { + gateway: args.data.guestGateway + }); + } if(args.data.guestNetmask != null && args.data.guestNetmask.length > 0) { - $.extend(dataObj, { - netmask: args.data.guestNetmask - }); - } - if(args.$form.find('.form-item[rel=vpcid]').css("display") != "none") { - $.extend(dataObj, { - vpcid: args.data.vpcid - }); - } + $.extend(dataObj, { + netmask: args.data.guestNetmask + }); + } + if(args.$form.find('.form-item[rel=vpcid]').css("display") != "none") { + $.extend(dataObj, { + vpcid: args.data.vpcid + }); + } + if(args.data.networkDomain != null && args.data.networkDomain.length > 0 && args.$form.find('.form-item[rel=vpcid]').css("display") == "none") { + $.extend(dataObj, { + networkDomain: args.data.networkDomain + }); + } + $.ajax({ url: createURL('createNetwork'), data: dataObj, @@ -393,41 +442,94 @@ id: 'networks', fields: { name: { label: 'label.name' }, - account: { label: 'label.account' }, - //zonename: { label: 'label.zone' }, - type: { label: 'label.type' }, - vlan: { label: 'label.vlan' }, - cidr: { label: 'label.cidr' } - /* - state: { - label: 'label.state', - indicator: { - 'Implemented': 'on', - 'Setup': 'on', - 'Allocated': 'on', - 'Destroyed': 'off' - } - } - */ + account: { label: 'label.account' }, + type: { label: 'label.type' }, + cidr: { label: 'label.cidr' } }, - dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } + + advSearchFields: { + zoneid: { + label: 'Zone', + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); + } + }, + + domainid: { + label: 'Domain', + select: function(args) { + if(isAdmin() || isDomainAdmin()) { + $.ajax({ + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, + success: function(json) { + var array1 = [{id: '', description: ''}]; + var domains = json.listdomainsresponse.domain; + if(domains != null && domains.length > 0) { + for(var i = 0; i < domains.length; i++) { + array1.push({id: domains[i].id, description: domains[i].path}); + } + } + args.response.success({ + data: array1 + }); + } + }); + } + else { + args.response.success({ + data: null + }); + } + }, + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + + account: { + label: 'Account', + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + $.ajax({ - url: createURL("listNetworks&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - data: { - listAll: true - }, - dataType: 'json', + url: createURL('listNetworks'), + data: data, async: false, success: function(data) { args.response.success({ @@ -453,46 +555,12 @@ if(services == null) return false; - if(args.context.networks[0].type == "Isolated") { - for(var i=0; i < services.length; i++) { - var service = services[i]; - if(service.name == "SourceNat") { - return true; - } - } - } - else if(args.context.networks[0].type == "Shared") { - var havingSecurityGroupService = false; - var havingElasticIpCapability = false; - var havingElasticLbCapability = false; - - for(var i=0; i < services.length; i++) { - var service = services[i]; - if(service.name == "SecurityGroup") { - havingSecurityGroupService = true; - } - else if(service.name == "StaticNat") { - $(service.capability).each(function(){ - if(this.name == "ElasticIp" && this.value == "true") { - havingElasticIpCapability = true; - return false; //break $.each() loop - } - }); - } - else if(service.name == "Lb") { - $(service.capability).each(function(){ - if(this.name == "ElasticLb" && this.value == "true") { - havingElasticLbCapability = true; - return false; //break $.each() loop - } - }); - } - } - - if(havingSecurityGroupService == true && havingElasticIpCapability == true && havingElasticLbCapability == true) + // IP addresses supported for both isolated and shared networks w/ source NAT enabled + for(var i=0; i < services.length; i++) { + var service = services[i]; + if(service.name == "SourceNat") { return true; - else - return false; + } } return false; @@ -507,26 +575,36 @@ } }, action: function(args) { - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displaytext=" + todb(args.data.displaytext)); - + var data = { + id: args.context.networks[0].id, + name: args.data.name, + displaytext: args.data.displaytext, + }; + //args.data.networkdomain is null when networkdomain field is hidden - if(args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain) - array1.push("&networkdomain=" + todb(args.data.networkdomain)); + if(args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain) { + $.extend(data, { + networkdomain: args.data.networkdomain + }); + } //args.data.networkofferingid is null when networkofferingid field is hidden if(args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) { - array1.push("&networkofferingid=" + todb(args.data.networkofferingid)); + $.extend(data, { + networkofferingid: args.data.networkofferingid + }); if(args.context.networks[0].type == "Isolated") { //Isolated network cloudStack.dialog.confirm({ message: 'Do you want to keep the current guest network CIDR unchanged?', - action: function() { //"Yes" button is clicked - array1.push("&changecidr=false"); + action: function() { //"Yes" button is clicked + $.extend(data, { + changecidr: false + }); + $.ajax({ - url: createURL("updateNetwork&id=" + args.context.networks[0].id + array1.join("")), - dataType: "json", + url: createURL('updateNetwork'), + data: data, success: function(json) { var jid = json.updatenetworkresponse.jobid; args.response.success( @@ -542,11 +620,14 @@ } }); }, - cancelAction: function() { //"Cancel" button is clicked - array1.push("&changecidr=true"); + cancelAction: function() { //"Cancel" button is clicked + $.extend(data, { + changecidr: true + }); + $.ajax({ - url: createURL("updateNetwork&id=" + args.context.networks[0].id + array1.join("")), - dataType: "json", + url: createURL('updateNetwork'), + data: data, success: function(json) { var jid = json.updatenetworkresponse.jobid; args.response.success( @@ -568,8 +649,8 @@ } $.ajax({ - url: createURL("updateNetwork&id=" + args.context.networks[0].id + array1.join("")), - dataType: "json", + url: createURL('updateNetwork'), + data: data, success: function(json) { var jid = json.updatenetworkresponse.jobid; args.response.success( @@ -604,15 +685,9 @@ success: function(json){ zoneObj = json.listzonesresponse.zone[0]; } - }); - if(zoneObj.networktype == "Basic") { - args.$form.find('.form-item[rel=cleanup]').find('input').removeAttr('checked'); //unchecked - args.$form.find('.form-item[rel=cleanup]').hide(); //hidden - } - else { - args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked - args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown - } + }); + args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked + args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown }, fields: { cleanup: { @@ -686,30 +761,41 @@ tabFilter: function(args) { var networkOfferingHavingELB = false; + var hasNetworkACL = false; + $.ajax({ url: createURL("listNetworkOfferings&id=" + args.context.networks[0].networkofferingid), dataType: "json", async: false, success: function(json) { var networkoffering = json.listnetworkofferingsresponse.networkoffering[0]; + $(networkoffering.service).each(function(){ var thisService = this; - if(thisService.name == "Lb") { + + if (thisService.name == 'NetworkACL') { + hasNetworkACL = true; + } else if (thisService.name == "Lb") { $(thisService.capability).each(function(){ - if(this.name == "ElasticLb" && this.value == "true") { + if (this.name == "ElasticLb" && this.value == "true") { networkOfferingHavingELB = true; - return false; //break $.each() loop } }); - return false; //break $.each() loop } }); } }); var hiddenTabs = []; - if(networkOfferingHavingELB == false) + + if (!networkOfferingHavingELB) { hiddenTabs.push("addloadBalancer"); + } + + if (!hasNetworkACL) { + hiddenTabs.push('egressRules'); + } + return hiddenTabs; }, @@ -752,7 +838,19 @@ hiddenFields.push("networkdomain"); } return hiddenFields; + }, + + preFilter: function(args) { + var hiddenFields; + if(isAdmin()) { + hiddenFields = []; + } + else { + hiddenFields = ["vlan"]; + } + return hiddenFields; }, + fields: [ { name: { @@ -782,9 +880,7 @@ return "No"; } }, - vlan: { label: 'label.vlan.id' }, - - networkofferingname: { label: 'label.network.offering' }, + vlan: { label: 'label.vlan.id' }, networkofferingid: { label: 'label.network.offering', @@ -1181,10 +1277,8 @@ }, dataProvider: function(args) { - var data = { - page: args.page, - pageSize: pageSize - }; + var data = {}; + listViewDataProvider(args, data); if (g_supportELB == "guest") // IPs are allocated on guest network $.extend(data, { @@ -1199,28 +1293,17 @@ if (args.context.networks) { $.extend(data, { associatedNetworkId: args.context.networks[0].id }); + + } + + if("vpc" in args.context) { + $.extend(data, { + vpcid: args.context.vpc[0].id + }); } - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - - if("vpc" in args.context) { - $.extend(data, { - vpcid: args.context.vpc[0].id - }); - } - $.ajax({ - url: createURL("listPublicIpAddresses&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + url: createURL('listPublicIpAddresses'), data: data, dataType: "json", async: true, @@ -1641,25 +1724,27 @@ tabs: { details: { title: 'label.details', - - preFilter: function(args) { - var hiddenFields = []; - var zoneObj; - $.ajax({ - url: createURL("listZones&id=" + args.context.ipAddresses[0].zoneid), - dataType: "json", - async: false, - success: function(json) { - zoneObj = json.listzonesresponse.zone[0]; - } - }); - if(zoneObj.networktype == "Advanced") { - hiddenFields.push("issystem"); - hiddenFields.push("purpose"); - } - return hiddenFields; - }, - + preFilter: function(args) { + var hiddenFields = []; + var zoneObj; + $.ajax({ + url: createURL("listZones&id=" + args.context.ipAddresses[0].zoneid), + dataType: "json", + async: false, + success: function(json) { + zoneObj = json.listzonesresponse.zone[0]; + } + }); + if(zoneObj.networktype == "Advanced") { + hiddenFields.push("issystem"); + hiddenFields.push("purpose"); + } + + if(!isAdmin()) { + hiddenFields.push("vlanname"); + } + return hiddenFields; + }, fields: [ { ipaddress: { label: 'label.ip' } @@ -2719,14 +2804,16 @@ //'private-ports': { privateport: { edit: true, - label: 'label.private.port' + label: 'label.private.port', //range: ['privateport', 'privateendport'] //Bug 13427 - Don't allow port forwarding ranges in the CreatePortForwardingRule API + range: ['privateport', 'privateendport'] //Bug 16344 (restore port range back) (http://bugs.cloudstack.org/browse/CS-16344) }, //'public-ports': { publicport: { edit: true, - label: 'label.public.port' + label: 'label.public.port', //range: ['publicport', 'publicendport'] //Bug 13427 - Don't allow port forwarding ranges in the CreatePortForwardingRule API + range: ['publicport', 'publicendport'] //Bug 16344 (restore port range back) (http://bugs.cloudstack.org/browse/CS-16344) }, 'protocol': { label: 'label.protocol', @@ -2749,25 +2836,28 @@ add: { label: 'label.add.vm', - action: function(args) { - var data = { - ipaddressid: args.context.ipAddresses[0].id, - privateport: args.data.privateport, - publicport: args.data.publicport, - protocol: args.data.protocol, - virtualmachineid: args.itemData[0].id, - openfirewall: false - }; - - if('vpc' in args.context) { //from VPC section - if(args.data.tier == null) { - args.response.error('Tier is required'); - return; - } + + action: function(args) { + var data = { + ipaddressid: args.context.ipAddresses[0].id, + privateport: args.data.privateport, + privateendport: args.data.privateendport, + publicport: args.data.publicport, + publicendport: args.data.publicendport, + protocol: args.data.protocol, + virtualmachineid: args.itemData[0].id, + openfirewall: false + }; + + if('vpc' in args.context) { //from VPC section + if(args.data.tier == null) { + args.response.error('Tier is required'); + return; + } $.extend(data, { - networkid: args.data.tier - }); - } + networkid: args.data.tier + }); + } else { //from Guest Network section $.extend(data, { networkid: args.context.networks[0].id @@ -2983,7 +3073,9 @@ url: createURL('removeVpnUser'), data: { username: args.context.multiRule[0].username, - id: args.context.multiRule[0].domainid + id: args.context.multiRule[0].domainid, + account: args.context.ipAddresses[0].account, + domainid: args.context.ipAddresses[0].domainid }, dataType: 'json', async: true, @@ -3091,23 +3183,18 @@ } }, + advSearchFields: { + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } + var data = {}; + listViewDataProvider(args, data); $.ajax({ - url: createURL("listSecurityGroups&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", - async: true, + url: createURL('listSecurityGroups'), + data: data, success: function(json) { var items = json.listsecuritygroupsresponse.securitygroup; args.response.success({ @@ -3319,15 +3406,7 @@ data: $.map( data.listsecuritygroupsresponse.securitygroup[0].ingressrule ? data.listsecuritygroupsresponse.securitygroup[0].ingressrule : [], - function(elem) { - return { - id: elem.ruleid, - protocol: elem.protocol, - startport: elem.startport ? elem.startport : elem.icmptype, - endport: elem.endport ? elem.endport : elem.icmpcode, - cidr: elem.cidr ? elem.cidr : ''.concat(elem.account, ' - ', elem.securitygroupname) - }; - } + ingressEgressDataMap ) }); } @@ -3496,15 +3575,7 @@ data: $.map( data.listsecuritygroupsresponse.securitygroup[0].egressrule ? data.listsecuritygroupsresponse.securitygroup[0].egressrule : [], - function(elem) { - return { - id: elem.ruleid, - protocol: elem.protocol, - startport: elem.startport ? elem.startport : elem.icmptype, - endport: elem.endport ? elem.endport : elem.icmpcode, - cidr: elem.cidr ? elem.cidr : ''.concat(elem.account, ' - ', elem.securitygroupname) - }; - } + ingressEgressDataMap ) }); } @@ -3569,23 +3640,91 @@ cidr: { label: 'label.cidr' }, state: {label: 'label.state', indicator: { 'Enabled': 'on', 'Disabled': 'off'}} }, - dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; + + advSearchFields: { + name: { label: 'Name' }, + zoneid: { + label: 'Zone', + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); + } + }, + + domainid: { + label: 'Domain', + select: function(args) { + if(isAdmin() || isDomainAdmin()) { + $.ajax({ + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, + success: function(json) { + var array1 = [{id: '', description: ''}]; + var domains = json.listdomainsresponse.domain; + if(domains != null && domains.length > 0) { + for(var i = 0; i < domains.length; i++) { + array1.push({id: domains[i].id, description: domains[i].path}); + } + } + args.response.success({ + data: array1 + }); + } + }); } + else { + args.response.success({ + data: null + }); + } + }, + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; } - } + }, + account: { + label: 'Account', + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + $.ajax({ - url: createURL("listVPCs&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", - async: true, + url: createURL('listVPCs'), + data: data, success: function(json) { var items = json.listvpcsresponse.vpc; args.response.success({data:items}); @@ -3608,16 +3747,19 @@ } }, fields: { - name: { - label: 'label.name', - validation: { required: true } - }, + name: { + label: 'label.name', + docID: 'helpVPCName', + validation: { required: true } + }, displaytext: { label: 'label.description', + docID: 'helpVPCDescription', validation: { required: true } }, zoneid: { label: 'label.zone', + docID: 'helpVPCZone', validation: { required: true }, select: function(args) { var data = { listAll: true }; @@ -3643,9 +3785,11 @@ }, cidr: { label: 'label.super.cidr.for.guest.networks', + docID: 'helpVPCSuperCIDR', validation: { required: true } }, networkdomain: { + docID: 'helpVPCDomain', label: 'label.DNS.domain.for.guest.networks' } } @@ -3715,7 +3859,7 @@ name: 'label.details', actions: { configureVpc: { - label: 'label.edit.vpc', + label: 'label.configure', textLabel: 'label.configure', action: { custom: cloudStack.uiCustom.vpc(cloudStack.vpc) @@ -3949,22 +4093,14 @@ cidrlist: { label: 'label.CIDR.list' }, ipsecpsk: { label: 'label.IPsec.preshared.key' } }, - dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - + + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + $.ajax({ - url: createURL("listVpnCustomerGateways&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", + url: createURL('listVpnCustomerGateways'), + data: data, async: true, success: function(json) { var items = json.listvpncustomergatewaysresponse.vpncustomergateway; diff --git a/ui/scripts/projects.js b/ui/scripts/projects.js index bb73ce1455f..34c57c6aae7 100644 --- a/ui/scripts/projects.js +++ b/ui/scripts/projects.js @@ -622,29 +622,72 @@ } }, + advSearchFields: { + name: { label: 'label.name' }, + displaytext: { label: 'label.display.text' }, + + domainid: { + label: 'Domain', + select: function(args) { + if(isAdmin() || isDomainAdmin()) { + $.ajax({ + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, + success: function(json) { + var array1 = [{id: '', description: ''}]; + var domains = json.listdomainsresponse.domain; + if(domains != null && domains.length > 0) { + for(var i = 0; i < domains.length; i++) { + array1.push({id: domains[i].id, description: domains[i].path}); + } + } + args.response.success({ + data: array1 + }); + } + }); + } + else { + args.response.success({ + data: null + }); + } + }, + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + + account: { + label: 'Account', + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + } + }, + dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - - var apiCmd = "listProjects&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + '&listAll=true'; - + var data = {}; + listViewDataProvider(args, data); + if (isDomainAdmin()) { - apiCmd += '&domainid=' + args.context.users[0].domainid; + $.extend(data, { + domainid: args.context.users[0].domainid + }); } $.ajax({ - url: createURL(apiCmd, { ignoreProject: true }), - dataType: 'json', - async: true, + url: createURL('listProjects', { ignoreProject: true }), + data: data, success: function(data) { args.response.success({ data: data.listprojectsresponse.project, diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index ebc0ad8df71..5e187ed1b82 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -264,14 +264,18 @@ cloudStack.actionFilter = { guestNetwork: function(args) { var jsonObj = args.context.item; var allowedActions = []; - + if(jsonObj.type == 'Isolated') { allowedActions.push('edit'); //only Isolated network can be upgraded + allowedActions.push('restart'); + allowedActions.push('remove'); } - - allowedActions.push('restart'); - allowedActions.push('remove'); - + else if(jsonObj.type == 'Shared') { + if(isAdmin()) { + allowedActions.push('restart'); + allowedActions.push('remove'); + } + } return allowedActions; } } @@ -400,6 +404,7 @@ cloudStack.converters = { case 2: return cloudStack.converters.convertBytes(value); case 3: return cloudStack.converters.convertBytes(value); case 6: return cloudStack.converters.convertBytes(value); + case 9: return cloudStack.converters.convertBytes(value); case 11: return cloudStack.converters.convertBytes(value); } @@ -407,6 +412,48 @@ cloudStack.converters = { } } +//data parameter passed to API call in listView +function listViewDataProvider(args, data) { + //search + if(args.filterBy != null) { + if(args.filterBy.advSearch != null && typeof(args.filterBy.advSearch) == "object") { //advanced search + for(var key in args.filterBy.advSearch) { + if(key == 'tagKey' && args.filterBy.advSearch[key].length > 0) { + $.extend(data, { + 'tags[0].key': args.filterBy.advSearch[key] + }); + } + else if(key == 'tagValue' && args.filterBy.advSearch[key].length > 0) { + $.extend(data, { + 'tags[0].value': args.filterBy.advSearch[key] + }); + } + else if(args.filterBy.advSearch[key] != null && args.filterBy.advSearch[key].length > 0) { + data[key] = args.filterBy.advSearch[key]; //do NOT use $.extend(data, { key: args.filterBy.advSearch[key] }); which will treat key variable as "key" string + } + } + } + else if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { //basic search + switch(args.filterBy.search.by) { + case "name": + if(args.filterBy.search.value.length > 0) { + $.extend(data, { + keyword: args.filterBy.search.value + }); + } + break; + } + } + } + + //pagination + $.extend(data, { + listAll: true, + page: args.page, + pagesize: pageSize + }); +} + //find service object in network object function ipFindNetworkServiceByName(pName, networkObj) { if(networkObj == null) @@ -651,10 +698,10 @@ cloudStack.api = { var resourceId = args.context[contextId][0].id; $.ajax({ - url: createURL( - 'createTags&tags[0].key=' + data.key + '&tags[0].value=' + data.value - ), + url: createURL('createTags'), data: { + 'tags[0].key': data.key, + 'tags[0].value': data.value, resourceIds: resourceId, resourceType: resourceType }, @@ -675,10 +722,10 @@ cloudStack.api = { var resourceId = args.context[contextId][0].id; $.ajax({ - url: createURL( - 'deleteTags&tags[0].key=' + data.key + '&tags[0].value=' + data.value - ), + url: createURL('deleteTags'), data: { + 'tags[0].key': data.key, + 'tags[0].value': data.value, resourceIds: resourceId, resourceType: resourceType }, diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index 8e1f0bd1b48..dd813781522 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -49,7 +49,7 @@ } */ }, - + // List view actions actions: { // Add volume @@ -70,11 +70,13 @@ desc: 'message.add.volume', fields: { name: { + docID: 'helpVolumeName', label: 'label.name', validation: { required: true } }, availabilityZone: { label: 'label.availability.zone', + docID: 'helpVolumeAvailabilityZone', select: function(args) { $.ajax({ url: createURL("listZones&available=true"), @@ -89,6 +91,7 @@ }, diskOffering: { label: 'label.disk.offering', + docID: 'helpVolumeDiskOffering', select: function(args) { $.ajax({ url: createURL("listDiskOfferings"), @@ -138,20 +141,22 @@ }, action: function(args) { - var array1 = []; - array1.push("&name=" + args.data.name); - array1.push("&zoneId=" + args.data.availabilityZone); - array1.push("&diskOfferingId=" + args.data.diskOffering); - + var data = { + name: args.data.name, + zoneId: args.data.availabilityZone, + diskOfferingId: args.data.diskOffering + }; + // if(thisDialog.find("#size_container").css("display") != "none") { //wait for Brian to include $form in args if (selectedDiskOfferingObj.iscustomized == true) { - array1.push("&size=" + args.data.diskSize); + $.extend(data, { + size: args.data.diskSize + }); } $.ajax({ - url: createURL("createVolume" + array1.join("")), - dataType: "json", - async: true, + url: createURL('createVolume'), + data: data, success: function(json) { var jid = json.createvolumeresponse.jobid; args.response.success( @@ -191,10 +196,12 @@ fields: { name: { label: 'label.name', - validation: { required: true } + validation: { required: true }, + docID: 'helpUploadVolumeName' }, availabilityZone: { label: 'label.availability.zone', + docID: 'helpUploadVolumeZone', select: function(args) { $.ajax({ url: createURL("listZones&available=true"), @@ -209,6 +216,7 @@ }, format: { label: 'label.format', + docID: 'helpUploadVolumeFormat', select: function(args) { var items = []; items.push({ id: 'RAW', description: 'RAW' }); @@ -220,27 +228,33 @@ }, url: { label: 'label.url', + docID: 'helpUploadVolumeURL', validation: { required: true } }, checksum : { + docID: 'helpUploadVolumeChecksum', label: 'label.checksum' } } }, action: function(args) { - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&zoneId=" + args.data.availabilityZone); - array1.push("&format=" + args.data.format); - array1.push("&url=" + todb(args.data.url)); - if(args.data.checksum != null && args.data.checksum.length > 0) - array1.push("&checksum=" + todb(args.data.checksum)); + var data = { + name: args.data.name, + zoneId: args.data.availabilityZone, + format: args.data.format, + url: args.data.url + }; + + if(args.data.checksum != null && args.data.checksum.length > 0) { + $.extend(data, { + checksum: args.data.checksum + }); + } $.ajax({ - url: createURL("uploadVolume" + array1.join("")), - dataType: "json", - async: true, + url: createURL('uploadVolume'), + data: data, success: function(json) { var jid = json.uploadvolumeresponse.jobid; args.response.success( @@ -265,34 +279,102 @@ notification: { poll: pollAsyncJobResult } - } - + } }, + + advSearchFields: { + name: { label: 'Name' }, + zoneid: { + label: 'Zone', + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); + } + }, + + domainid: { + label: 'Domain', + select: function(args) { + if(isAdmin() || isDomainAdmin()) { + $.ajax({ + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, + success: function(json) { + var array1 = [{id: '', description: ''}]; + var domains = json.listdomainsresponse.domain; + if(domains != null && domains.length > 0) { + for(var i = 0; i < domains.length; i++) { + array1.push({id: domains[i].id, description: domains[i].path}); + } + } + args.response.success({ + data: array1 + }); + } + }); + } + else { + args.response.success({ + data: null + }); + } + }, + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + + account: { + label: 'Account', + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - - var apiCmd = "listVolumes&listAll=true&page=" + args.page + "&pagesize=" + pageSize+ array1.join(""); + var data = {}; + listViewDataProvider(args, data); + if(args.context != null) { if("instances" in args.context) { - apiCmd += "&virtualMachineId=" + args.context.instances[0].id; + $.extend(data, { + virtualMachineId: args.context.instances[0].id + }); } } $.ajax({ - url: createURL(apiCmd), - dataType: "json", - async: true, + url: createURL('listVolumes'), + data: data, success: function(json) { var items = json.listvolumesresponse.volume; args.response.success({ @@ -796,28 +878,24 @@ } }, action: function(args) { - /* - var isValid = true; - isValid &= validateString("Name", $thisDialog.find("#create_template_name"), $thisDialog.find("#create_template_name_errormsg")); - isValid &= validateString("Display Text", $thisDialog.find("#create_template_desc"), $thisDialog.find("#create_template_desc_errormsg")); - if (!isValid) - return; - $thisDialog.dialog("close"); - */ - - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displayText=" + todb(args.data.displayText)); - array1.push("&osTypeId=" + args.data.osTypeId); - array1.push("&isPublic=" + (args.data.isPublic=="on")); - array1.push("&passwordEnabled=" + (args.data.isPasswordEnabled=="on")); - if(args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") - array1.push("&isfeatured=" + (args.data.isFeatured == "on")); + var data = { + volumeId: args.context.volumes[0].id, + name: args.data.name, + displayText: args.data.displayText, + osTypeId: args.data.osTypeId, + isPublic: (args.data.isPublic=="on"), + passwordEnabled: (args.data.isPasswordEnabled=="on") + }; + + if(args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") { + $.extend(data, { + isfeatured: (args.data.isFeatured == "on") + }); + } $.ajax({ - url: createURL("createTemplate&volumeId=" + args.context.volumes[0].id + array1.join("")), - dataType: "json", - async: true, + url: createURL('createTemplate'), + data: data, success: function(json) { var jid = json.createtemplateresponse.jobid; args.response.success( @@ -956,7 +1034,7 @@ pollAgainIfValueIsIn: { 'UploadNotStarted': 1 }, - pollAgainFn: function(context) { //??? + pollAgainFn: function(context) { var toClearInterval = false; $.ajax({ url: createURL("listVolumes&id=" + context.volumes[0].id), @@ -972,6 +1050,7 @@ return toClearInterval; } }, + status: {label: 'label.status'}, type: { label: 'label.type' }, storagetype: { label: 'label.storage.type' }, hypervisor: { label: 'label.hypervisor' }, @@ -1051,30 +1130,75 @@ } }, - dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - - var apiCmd = "listSnapshots&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join(""); + advSearchFields: { + name: { label: 'Name' }, + + domainid: { + label: 'Domain', + select: function(args) { + if(isAdmin() || isDomainAdmin()) { + $.ajax({ + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, + success: function(json) { + var array1 = [{id: '', description: ''}]; + var domains = json.listdomainsresponse.domain; + if(domains != null && domains.length > 0) { + for(var i = 0; i < domains.length; i++) { + array1.push({id: domains[i].id, description: domains[i].path}); + } + } + args.response.success({ + data: array1 + }); + } + }); + } + else { + args.response.success({ + data: null + }); + } + }, + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + + account: { + label: 'Account', + isHidden: function(args) { + if(isAdmin() || isDomainAdmin()) + return false; + else + return true; + } + }, + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + if(args.context != null) { if("volumes" in args.context) { - apiCmd += "&volumeid=" + args.context.volumes[0].id; + $.extend(data, { + volumeid: args.context.volumes[0].id + }); } } $.ajax({ - url: createURL(apiCmd), - dataType: "json", - async: true, + url: createURL('listSnapshots'), + data: data, success: function(json) { var items = json.listsnapshotsresponse.snapshot; args.response.success({ @@ -1127,26 +1251,18 @@ } }, action: function(args) { - /* - var isValid = true; - isValid &= validateString("Name", $thisDialog.find("#create_template_name"), $thisDialog.find("#create_template_name_errormsg")); - isValid &= validateString("Display Text", $thisDialog.find("#create_template_desc"), $thisDialog.find("#create_template_desc_errormsg")); - if (!isValid) - return; - $thisDialog.dialog("close"); - */ - - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displayText=" + todb(args.data.displayText)); - array1.push("&osTypeId=" + args.data.osTypeId); - array1.push("&isPublic=" + (args.data.isPublic=="on")); - array1.push("&passwordEnabled=" + (args.data.isPasswordEnabled=="on")); - + var data = { + snapshotid: args.context.snapshots[0].id, + name: args.data.name, + displayText: args.data.displayText, + osTypeId: args.data.osTypeId, + isPublic: (args.data.isPublic=="on"), + passwordEnabled: (args.data.isPasswordEnabled=="on") + }; + $.ajax({ - url: createURL("createTemplate&snapshotid=" + args.context.snapshots[0].id + array1.join("")), - dataType: "json", - async: true, + url: createURL('createTemplate'), + data: data, success: function(json) { var jid = json.createtemplateresponse.jobid; args.response.success( @@ -1192,13 +1308,14 @@ } }, action: function(args) { - var array1 = []; - array1.push("&name=" + todb(args.data.name)); + var data = { + snapshotid: args.context.snapshots[0].id, + name: args.data.name + }; $.ajax({ - url: createURL("createVolume&snapshotid=" + args.context.snapshots[0].id + array1.join("")), - dataType: "json", - async: true, + url: createURL('createVolume'), + data: data, success: function(json) { var jid = json.createvolumeresponse.jobid; args.response.success( @@ -1340,6 +1457,7 @@ } } } + return allowedActions; }; @@ -1356,6 +1474,7 @@ allowedActions.push("createVolume"); } allowedActions.push("remove"); + return allowedActions; } diff --git a/ui/scripts/system.js b/ui/scripts/system.js index e71529ff444..4eadf097b36 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -273,13 +273,22 @@ $.ajax({ url: createURL('listRouters'), data: { - listAll: true + projectid: -1 }, success: function(json) { - dataFns.capacity($.extend(data, { - virtualRouterCount: json.listroutersresponse.count ? - json.listroutersresponse.count : 0 - })); + var total1 = json.listroutersresponse.count ? json.listroutersresponse.count : 0; + $.ajax({ + url: createURL('listRouters'), + data: { + listAll: true + }, + success: function(json) { + var total2 = json.listroutersresponse.count ? json.listroutersresponse.count : 0; + dataFns.capacity($.extend(data, { + virtualRouterCount: (total1 + total2) + })); + } + }); } }); }, @@ -328,6 +337,11 @@ }); }; + // re: CS-16413 -- Disable API calls + return args.response.success({ + data: {} + }); + dataFns.zoneCount({}); } }, @@ -759,7 +773,7 @@ selectedManagementNetworkObj.xennetworklabel = trafficType.xennetworklabel; selectedManagementNetworkObj.kvmnetworklabel = trafficType.kvmnetworklabel; selectedManagementNetworkObj.vmwarenetworklabel = trafficType.vmwarenetworklabel; - selectedPublicNetworkObj.ovmnetworklabel = trafficType.ovmnetworklabel; + selectedManagementNetworkObj.ovmnetworklabel = trafficType.ovmnetworklabel; args.response.success({ data: selectedManagementNetworkObj }); } }); @@ -1074,19 +1088,23 @@ fields: { name: { + docID: 'helpGuestNetworkZoneName', label: 'label.name', validation: { required: true } }, description: { label: 'label.description', + docID: 'helpGuestNetworkZoneDescription', validation: { required: true } }, vlanId: { - label: 'label.vlan.id' + label: 'label.vlan.id', + docID: 'helpGuestNetworkZoneVLANID' }, scope: { label: 'label.scope', + docID: 'helpGuestNetworkZoneScope', select: function(args) { var array1 = []; array1.push({id: 'zone-wide', description: 'All'}); @@ -1170,7 +1188,9 @@ args.response.success({data: items}); } }, - subdomainaccess: { label: 'label.subdomain.access', isBoolean: true, isHidden: true }, + subdomainaccess: { + label: 'label.subdomain.access', isBoolean: true, isHidden: true, + }, account: { label: 'label.account' }, projectId: { @@ -1195,6 +1215,7 @@ networkOfferingId: { label: 'label.network.offering', + docID: 'helpGuestNetworkZoneNetworkOffering', dependsOn: 'scope', select: function(args) { $.ajax({ @@ -1335,17 +1356,28 @@ } }, - guestGateway: { label: 'label.guest.gateway' }, - guestNetmask: { label: 'label.guest.netmask' }, + guestGateway: { + label: 'label.guest.gateway', + docID: 'helpGuestNetworkZoneGateway' + }, + guestNetmask: { + label: 'label.guest.netmask', + docID: 'helpGuestNetworkZoneNetmask' + }, guestStartIp: { label: 'label.guest.start.ip', - validation: { required: true } + validation: { required: true }, + docID: 'helpGuestNetworkZoneStartIP' }, guestEndIp: { label: 'label.guest.end.ip', - validation: { required: true } + validation: { required: true }, + docID: 'helpGuestNetworkZoneEndIP' }, - networkdomain: { label: 'label.network.domain' } + networkdomain: { + label: 'label.network.domain', + docID: 'helpGuestNetworkZoneNetworkDomain' + } } }, @@ -1446,8 +1478,9 @@ //need to make 2 listNetworks API call to get all guest networks from one physical network in Advanced zone var items = []; + //"listNetworks&projectid=-1": list guest networks under all projects (no matter who the owner is) $.ajax({ - url: createURL("listNetworks&listAll=true&trafficType=Guest&zoneId=" + selectedZoneObj.id + "&physicalnetworkid=" + selectedPhysicalNetworkObj.id + "&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + url: createURL("listNetworks&projectid=-1&trafficType=Guest&zoneId=" + selectedZoneObj.id + "&physicalnetworkid=" + selectedPhysicalNetworkObj.id + "&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), dataType: "json", async: false, success: function(json) { @@ -1461,6 +1494,7 @@ networkCollectionMap[this.id] = this.name; }); + //"listNetworks&listAll=true: list guest networks that are not under any project (no matter who the owner is) $.ajax({ url: createURL("listNetworks&listAll=true&trafficType=Guest&zoneId=" + selectedZoneObj.id + "&physicalnetworkid=" + selectedPhysicalNetworkObj.id + "&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), dataType: "json", @@ -1482,6 +1516,7 @@ detailView: { name: 'Guest network details', + noCompact: true, viewAll: { path: '_zone.guestIpRanges', label: 'label.ip.ranges', @@ -1784,10 +1819,24 @@ project: { label: 'label.project' } } ], - dataProvider: function(args) { + dataProvider: function(args) { + var data = { + id: args.context.networks[0].id + }; + if(args.context.networks[0].projectid != null) { + $.extend(data, { + projectid: -1 + }); + } + else { + $.extend(data, { + listAll: true //pass "&listAll=true" to "listNetworks&id=xxxxxxxx" for now before API gets fixed. + }); + } + $.ajax({ - url: createURL("listNetworks&id=" + args.context.networks[0].id + "&listAll=true"), //pass "&listAll=true" to "listNetworks&id=xxxxxxxx" for now before API gets fixed. - dataType: "json", + url: createURL("listNetworks"), + data: data, async: false, success: function(json) { selectedGuestNetworkObj = json.listnetworksresponse.network[0]; @@ -2255,6 +2304,7 @@ id: { label: 'label.id' }, projectid: { label: 'label.project.id' }, state: { label: 'label.state' }, + guestnetworkid: { label: 'label.network.id' }, publicip: { label: 'label.public.ip' }, guestipaddress: { label: 'label.guest.ip' }, linklocalip: { label: 'label.linklocal.ip' }, @@ -2286,6 +2336,47 @@ } }); } + }, + nics: { + title: 'label.nics', + multiple: true, + fields: [ + { + name: { label: 'label.name', header: true }, + type: { label: 'label.type' }, + traffictype: { label: 'label.traffic.type' }, + networkname: { label: 'label.network.name' }, + netmask: { label: 'label.netmask' }, + ipaddress: { label: 'label.ip.address' }, + id: { label: 'label.id' }, + networkid: { label: 'label.network.id' }, + isolationuri: { label: 'label.isolation.uri' }, + broadcasturi: { label: 'label.broadcast.uri' } + } + ], + dataProvider: function(args) { + $.ajax({ + url: createURL("listRouters&id=" + args.context.routers[0].id), + dataType: 'json', + async: true, + success: function(json) { + var jsonObj = json.listroutersresponse.router[0].nic; + + args.response.success({ + actionFilter: routerActionfilter, + data: $.map(jsonObj, function(nic, index) { + var name = 'NIC ' + (index + 1); + if (nic.isdefault) { + name += ' (' + _l('label.default') + ')'; + } + return $.extend(nic, { + name: name + }); + }) + }); + } + }); + } } } } @@ -2934,17 +3025,21 @@ preFilter: cloudStack.preFilter.addLoadBalancerDevice, fields: { ip: { - label: 'label.ip.address' + label: 'label.ip.address', + docID: 'helpNetScalerIPAddress' }, username: { - label: 'label.username' + label: 'label.username', + docID: 'helpNetScalerUsername' }, password: { label: 'label.password', - isPassword: true + isPassword: true, + docID: 'helpNetScalerPassword' }, networkdevicetype: { label: 'label.type', + docID: 'helpNetScalerType', select: function(args) { var items = []; items.push({id: "NetscalerMPXLoadBalancer", description: "NetScaler MPX LoadBalancer"}); @@ -2954,14 +3049,17 @@ } }, publicinterface: { - label: 'label.public.interface' + label: 'label.public.interface', + docID: 'helpNetScalerPublicInterface' }, privateinterface: { - label: 'label.private.interface' + label: 'label.private.interface', + docID: 'helpNetScalerPrivateInterface' }, numretries: { label: 'label.numretries', - defaultValue: '2' + defaultValue: '2', + docID: 'helpNetScalerRetries' }, // inline: { // label: 'Mode', @@ -2975,11 +3073,13 @@ dedicated: { label: 'label.dedicated', isBoolean: true, - isChecked: false + isChecked: false, + docID: 'helpNetScalerDedicated' }, capacity: { label: 'label.capacity', - validation: { required: false, number: true } + validation: { required: false, number: true }, + docID: 'helpNetScalerCapacity' } } }, @@ -3169,17 +3269,21 @@ preFilter: cloudStack.preFilter.addLoadBalancerDevice, fields: { ip: { - label: 'label.ip.address' + label: 'label.ip.address', + docID: 'helpF5IPAddress' }, username: { - label: 'label.username' + label: 'label.username', + docID: 'helpF5Username' }, password: { label: 'label.password', + docID: 'helpF5Password', isPassword: true }, networkdevicetype: { label: 'label.type', + docID: 'helpF5Type', select: function(args) { var items = []; items.push({id: "F5BigIpLoadBalancer", description: "F5 Big Ip Load Balancer"}); @@ -3187,31 +3291,40 @@ } }, publicinterface: { - label: 'label.public.interface' + label: 'label.public.interface', + docID: 'helpF5PublicInterface' }, privateinterface: { - label: 'label.private.interface' + label: 'label.private.interface', + docID: 'helpF5PrivateInterface' }, numretries: { label: 'label.numretries', + docID: 'helpF5Retries', defaultValue: '2' }, - // inline: { - // label: 'Mode', - // select: function(args) { - // var items = []; - // items.push({id: "false", description: "side by side"}); - // items.push({id: "true", description: "inline"}); - // args.response.success({data: items}); - // } - // }, + //Inline Mode has been moved from Add F5 Device to Create Network Offering (both backend and UI) + /* + inline: { + label: 'Mode', + docID: 'helpF5Mode', + select: function(args) { + var items = []; + items.push({id: "false", description: "side by side"}); + items.push({id: "true", description: "inline"}); + args.response.success({data: items}); + } + }, + */ dedicated: { label: 'label.dedicated', + docID: 'helpF5Dedicated', isBoolean: true, isChecked: false }, capacity: { label: 'label.capacity', + docID: 'helpF5Capacity', validation: { required: false, number: true } } } @@ -3401,17 +3514,21 @@ title: 'label.add.SRX.device', fields: { ip: { - label: 'label.ip.address' + label: 'label.ip.address', + docID: 'helpSRXIPAddress' }, username: { - label: 'label.username' + label: 'label.username', + docID: 'helpSRXUsername' }, password: { label: 'label.password', - isPassword: true + isPassword: true, + docID: 'helpSRXPassword' }, networkdevicetype: { label: 'label.type', + docID: 'helpSRXType', select: function(args) { var items = []; items.push({id: "JuniperSRXFirewall", description: "Juniper SRX Firewall"}); @@ -3419,47 +3536,57 @@ } }, publicinterface: { - label: 'label.public.interface' + label: 'label.public.interface', + docID: 'helpSRXPublicInterface' }, privateinterface: { - label: 'label.private.interface' + label: 'label.private.interface', + docID: 'helpSRXPrivateInterface' }, usageinterface: { - label: 'Usage interface' + label: 'Usage interface', + docID: 'helpSRXUsageInterface' }, numretries: { label: 'label.numretries', - defaultValue: '2' + defaultValue: '2', + docID: 'helpSRXRetries' }, timeout: { label: 'label.timeout', - defaultValue: '300' + defaultValue: '300', + docID: 'helpSRXTimeout' + }, + inline: { + label: 'Mode', + docID: 'helpSRXMode', + select: function(args) { + var items = []; + items.push({id: "false", description: "side by side"}); + items.push({id: "true", description: "inline"}); + args.response.success({data: items}); + } }, - // inline: { - // label: 'Mode', - // select: function(args) { - // var items = []; - // items.push({id: "false", description: "side by side"}); - // items.push({id: "true", description: "inline"}); - // args.response.success({data: items}); - // } - // }, publicnetwork: { label: 'label.public.network', - defaultValue: 'untrusted' + defaultValue: 'untrusted', + docID: 'helpSRXPublicNetwork' }, privatenetwork: { label: 'label.private.network', - defaultValue: 'trusted' + defaultValue: 'trusted', + docID: 'helpSRXPrivateNetwork' }, capacity: { label: 'label.capacity', - validation: { required: false, number: true } + validation: { required: false, number: true }, + docID: 'helpSRXCapacity' }, dedicated: { label: 'label.dedicated', isBoolean: true, - isChecked: false + isChecked: false, + docID: 'helpSRXDedicated' } } }, @@ -3719,7 +3846,213 @@ name: { label: 'label.name' }//, //state: { label: 'label.status' } //comment it for now, since dataProvider below doesn't get called by widget code after action is done } - } + }, + // Nicira Nvp provider detail view + niciraNvp: { + type: 'detailView', + id: 'niciraNvpProvider', + label: 'label.niciraNvp', + viewAll: { label: 'label.devices', path: '_zone.niciraNvpDevices' }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + state: { label: 'label.state' } + } + ], + dataProvider: function(args) { + refreshNspData("NiciraNvp"); + var providerObj; + $(nspHardcodingArray).each(function(){ + if(this.id == "niciraNvp") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('niciraNvp') + }); + } + } + }, + actions: { + add: { + label: 'label.add.NiciraNvp.device', + createForm: { + title: 'label.add.NiciraNvp.device', + preFilter: function(args) { }, // TODO What is this? + fields: { + host: { + label: 'label.ip.address' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + }, + numretries: { + label: 'label.numretries', + defaultValue: '2' + }, + transportzoneuuid: { + label: 'label.nicira.transportzoneuuid' + }, + l3gatewayserviceuuid: { + label: 'label.nicira.l3gatewayserviceuuid' + } + } + }, + action: function(args) { + if(nspMap["niciraNvp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NiciraNvp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNiciraNvpProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(addNiciraNvpProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["niciraNvp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + else { + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + }, + messages: { + notification: function(args) { + return 'label.add.NiciraNvp.device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["niciraNvp"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["niciraNvp"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["niciraNvp"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid + } + } + ); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + } + } + } } } }, @@ -3756,6 +4089,34 @@ } } }, + + dataProvider: function(args) { + var array1 = []; + if(args.filterBy != null) { + if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { + switch(args.filterBy.search.by) { + case "name": + if(args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; + } + } + } + + $.ajax({ + url: createURL("listZones&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: "json", + async: true, + success: function(json) { + zoneObjs = json.listzonesresponse.zone; + args.response.success({ + actionFilter: zoneActionfilter, + data:zoneObjs + }); + } + }); + }, + actions: { add: { label: 'label.add.zone', @@ -3840,127 +4201,98 @@ } }); } - }, - - enable: { - label: 'label.action.enable.zone', - messages: { - confirm: function(args) { - return 'message.action.enable.zone'; - }, - notification: function(args) { - return 'label.action.enable.zone'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("updateZone&id=" + args.context.physicalResources[0].id + "&allocationstate=Enabled"), //embedded objects in listView is called physicalResources while embedded objects in detailView is called zones - dataType: "json", - async: true, - success: function(json) { - var item = json.updatezoneresponse.zone; - args.response.success({ - actionFilter: zoneActionfilter, - data:item - }); - } - }); - }, - notification: { - poll: function(args) { - args.complete(); - } - } - }, - - disable: { - label: 'label.action.disable.zone', - messages: { - confirm: function(args) { - return 'message.action.disable.zone'; - }, - notification: function(args) { - return 'label.action.disable.zone'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("updateZone&id=" + args.context.physicalResources[0].id + "&allocationstate=Disabled"), //embedded objects in listView is called physicalResources while embedded objects in detailView is called zones - dataType: "json", - async: true, - success: function(json) { - var item = json.updatezoneresponse.zone; - args.response.success({ - actionFilter: zoneActionfilter, - data:item - }); - } - }); - }, - notification: { - poll: function(args) { - args.complete(); - } - } - }, - - 'remove': { - label: 'label.action.delete.zone', - messages: { - confirm: function(args) { - return 'message.action.delete.zone'; - }, - notification: function(args) { - return 'label.action.delete.zone'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("deleteZone&id=" + args.context.physicalResources[0].id), //embedded objects in listView is called physicalResources while embedded objects in detailView is called zones - dataType: "json", - async: true, - success: function(json) { - args.response.success({data:{}}); - } - }); - }, - notification: { - poll: function(args) { args.complete(); } - } } - - }, - - dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - - $.ajax({ - url: createURL("listZones&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", - async: true, - success: function(json) { - zoneObjs = json.listzonesresponse.zone; - args.response.success({ - actionFilter: zoneActionfilter, - data:zoneObjs - }); - } - }); }, detailView: { isMaximized: true, actions: { + enable: { + label: 'label.action.enable.zone', + messages: { + confirm: function(args) { + return 'message.action.enable.zone'; + }, + notification: function(args) { + return 'label.action.enable.zone'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("updateZone&id=" + args.context.physicalResources[0].id + "&allocationstate=Enabled"), //embedded objects in listView is called physicalResources while embedded objects in detailView is called zones + dataType: "json", + async: true, + success: function(json) { + var item = json.updatezoneresponse.zone; + args.response.success({ + actionFilter: zoneActionfilter, + data:item + }); + } + }); + }, + notification: { + poll: function(args) { + args.complete(); + } + } + }, + + disable: { + label: 'label.action.disable.zone', + messages: { + confirm: function(args) { + return 'message.action.disable.zone'; + }, + notification: function(args) { + return 'label.action.disable.zone'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("updateZone&id=" + args.context.physicalResources[0].id + "&allocationstate=Disabled"), //embedded objects in listView is called physicalResources while embedded objects in detailView is called zones + dataType: "json", + async: true, + success: function(json) { + var item = json.updatezoneresponse.zone; + args.response.success({ + actionFilter: zoneActionfilter, + data:item + }); + } + }); + }, + notification: { + poll: function(args) { + args.complete(); + } + } + }, + + 'remove': { + label: 'label.action.delete.zone', + messages: { + confirm: function(args) { + return 'message.action.delete.zone'; + }, + notification: function(args) { + return 'label.action.delete.zone'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteZone&id=" + args.context.physicalResources[0].id), //embedded objects in listView is called physicalResources while embedded objects in detailView is called zones + dataType: "json", + async: true, + success: function(json) { + args.response.success({data:{}}); + } + }); + }, + notification: { + poll: function(args) { args.complete(); } + } + }, edit: { label: 'label.edit', action: function(args) { @@ -4034,7 +4366,10 @@ }, success: function(json) { selectedZoneObj = json.listzonesresponse.zone[0]; - args.response.success({ data: json.listzonesresponse.zone[0] }); + args.response.success({ + data: json.listzonesresponse.zone[0], + actionFilter: zoneActionfilter + }); } }); } @@ -4115,6 +4450,7 @@ }, detailView: { + noCompact: true, name: 'System VM details', actions: { start: { @@ -5176,6 +5512,7 @@ id: { label: 'label.id' }, projectid: { label: 'label.project.id' }, state: { label: 'label.state' }, + guestnetworkid: { label: 'label.network.id' }, publicip: { label: 'label.public.ip' }, guestipaddress: { label: 'label.guest.ip' }, linklocalip: { label: 'label.linklocal.ip' }, @@ -5208,6 +5545,47 @@ } }); } + }, + nics: { + title: 'label.nics', + multiple: true, + fields: [ + { + name: { label: 'label.name', header: true }, + type: { label: 'label.type' }, + traffictype: { label: 'label.traffic.type' }, + networkname: { label: 'label.network.name' }, + netmask: { label: 'label.netmask' }, + ipaddress: { label: 'label.ip.address' }, + id: { label: 'label.id' }, + networkid: { label: 'label.network.id' }, + isolationuri: { label: 'label.isolation.uri' }, + broadcasturi: { label: 'label.broadcast.uri' } + } + ], + dataProvider: function(args) { + $.ajax({ + url: createURL("listRouters&id=" + args.context.routers[0].id), + dataType: 'json', + async: true, + success: function(json) { + var jsonObj = json.listroutersresponse.router[0].nic; + + args.response.success({ + actionFilter: routerActionfilter, + data: $.map(jsonObj, function(nic, index) { + var name = 'NIC ' + (index + 1); + if (nic.isdefault) { + name += ' (' + _l('label.default') + ')'; + } + return $.extend(nic, { + name: name + }); + }) + }); + } + }); + } } } } @@ -5682,15 +6060,15 @@ label: 'label.numretries', defaultValue: '2' }, - // inline: { - // label: 'Mode', - // select: function(args) { - // var items = []; - // items.push({id: "false", description: "side by side"}); - // items.push({id: "true", description: "inline"}); - // args.response.success({data: items}); - // } - // }, + inline: { + label: 'Mode', + select: function(args) { + var items = []; + items.push({id: "false", description: "side by side"}); + items.push({id: "true", description: "inline"}); + args.response.success({data: items}); + } + }, dedicated: { label: 'label.dedicated', isBoolean: true, @@ -5874,15 +6252,18 @@ label: 'label.numretries', defaultValue: '2' }, - // inline: { - // label: 'Mode', - // select: function(args) { - // var items = []; - // items.push({id: "false", description: "side by side"}); - // items.push({id: "true", description: "inline"}); - // args.response.success({data: items}); - // } - // }, + //Inline Mode has been moved from Add F5 Device to Create Network Offering (both backend and UI) + /* + inline: { + label: 'Mode', + select: function(args) { + var items = []; + items.push({id: "false", description: "side by side"}); + items.push({id: "true", description: "inline"}); + args.response.success({data: items}); + } + }, + */ dedicated: { label: 'label.dedicated', isBoolean: true, @@ -6228,7 +6609,171 @@ } } }, - + // FIXME convert to nicira detailview + // NiciraNvp devices listView + niciraNvpDevices: { + id: 'niciraNvpDevices', + title: 'label.devices', + listView: { + id: 'niciraNvpDevices', + fields: { + hostname: { label: 'label.nicira.controller.address' }, + transportzoneuuid: { label: 'label.nicira.transportzoneuuid'}, + l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' } + }, + actions: { + add: { + label: 'label.add.NiciraNvp.device', + createForm: { + title: 'label.add.NiciraNvp.device', + preFilter: function(args) { }, // TODO What is this? + fields: { + host: { + label: 'label.ip.address' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + }, + numretries: { + label: 'label.numretries', + defaultValue: '2' + }, + transportzoneuuid: { + label: 'label.nicira.transportzoneuuid' + }, + l3gatewayserviceuuid: { + label: 'label.nicira.l3gatewayserviceuuid' + } + } + }, + action: function(args) { + if(nspMap["niciraNvp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NiciraNvp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNiciraNvpProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; // Job has not completed + } + else { + clearInterval(addNiciraNvpProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["niciraNvp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NiciraNvp failed. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + else { + addNiciraNvpDevice(args, selectedPhysicalNetworkObj, "addNiciraNvpDevice", "addniciranvpdeviceresponse", "niciranvpdevice") + } + }, + + messages: { + notification: function(args) { + return 'Added new Nicira Nvp Controller'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + dataProvider: function(args) { + $.ajax({ + url: createURL("listNiciraNvpDevices&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + data: { page: args.page, pageSize: pageSize }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listniciranvpdeviceresponse.niciranvpdevice; + args.response.success({data: items}); + } + }); + }, + detailView: { + name: 'Nicira Nvp details', + actions: { + 'remove': { + label: 'label.delete.NiciaNvp', + messages: { + confirm: function(args) { + return 'message.confirm.delete.NiciraNvp'; + }, + notification: function(args) { + return 'label.delete.NiciraNvp'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteNiciraNvpDevice&nvpdeviceid=" + args.context.niciraNvpDevices[0].nvpdeviceid), + dataType: "json", + async: true, + success: function(json) { + var jid = json.deleteniciranvpdeviceresponse.jobid; + args.response.success( + {_custom: + {jobId: jid} + } + ); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + nvpdeviceid: { label: 'label.id' }, + hostname: { label: 'label.ip.address' }, + transportzoneuuid: { label: 'label.nicira.transportzoneuuid' }, + l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' } + } + ], + dataProvider: function(args) { + $.ajax({ + url: createURL("listNiciraNvpDevices&nvpdeviceid=" + args.context.niciraNvpDevices[0].nvpdeviceid), + dataType: "json", + async: true, + success: function(json) { + var item = json.listniciranvpdeviceresponse.niciranvpdevice[0]; + args.response.success({data: item}); + } + }); + } + } + } + } + } + }, pods: { title: 'label.pods', listView: { @@ -6283,6 +6828,7 @@ fields: { zoneid: { label: 'Zone', + docID: 'helpPodZone', validation: { required: true }, select: function(args) { var data = args.context.zones ? @@ -6308,22 +6854,27 @@ }, podname: { label: 'label.pod.name', + docID: 'helpPodName', validation: { required: true } }, reservedSystemGateway: { label: 'label.reserved.system.gateway', + docID: 'helpPodGateway', validation: { required: true } }, reservedSystemNetmask: { label: 'label.reserved.system.netmask', + docID: 'helpPodNetmask', validation: { required: true } }, reservedSystemStartIp: { label: 'label.start.reserved.system.IP', + docID: 'helpPodStartIP', validation: { required: true } }, reservedSystemEndIp: { label: 'label.end.reserved.system.IP', + docID: 'helpPodEndIP', validation: { required: false } } } @@ -6638,6 +7189,7 @@ fields: { zoneid: { label: 'Zone', + docID: 'helpClusterZone', validation: { required: true }, select: function(args) { var data = args.context.zones ? @@ -6663,6 +7215,7 @@ }, hypervisor: { label: 'label.hypervisor', + docID: 'helpClusterHypervisor', select: function(args) { var vSwitchEnabled = false; @@ -6731,6 +7284,7 @@ }, podId: { label: 'label.pod', + docID: 'helpClusterPod', dependsOn: 'zoneid', select: function(args) { $.ajax({ @@ -6753,25 +7307,30 @@ }, name: { label: 'label.cluster.name', + docID: 'helpClusterName', validation: { required: true } }, //hypervisor==VMWare begins here vCenterHost: { label: 'label.vcenter.host', + docID: 'helpClustervCenterHost', validation: { required: true } }, vCenterUsername: { label: 'label.vcenter.username', + docID: 'helpClustervCenterUsername', validation: { required: true } }, vCenterPassword: { label: 'label.vcenter.password', + docID: 'helpClustervCenterPassword', validation: { required: true }, isPassword: true }, vCenterDatacenter: { label: 'label.vcenter.datacenter', + docID: 'helpClustervCenterDatacenter', validation: { required: true } }, vsmipaddress: { @@ -7304,6 +7863,7 @@ title: 'label.add.host', fields: { zoneid: { + docID: 'helpHostZone', label: 'Zone', validation: { required: true }, select: function(args) { @@ -7332,6 +7892,7 @@ //always appear (begin) podId: { label: 'label.pod', + docID: 'helpHostPod', validation: { required: true }, dependsOn: 'zoneid', select: function(args) { @@ -7356,6 +7917,7 @@ clusterId: { label: 'label.cluster', + docID: 'helpHostCluster', validation: { required: true }, dependsOn: 'podId', select: function(args) { @@ -7480,18 +8042,21 @@ //input_group="general" starts here hostname: { label: 'label.host.name', + docID: 'helpHostName', validation: { required: true }, isHidden: true }, username: { label: 'label.username', + docID: 'helpHostUsername', validation: { required: true }, isHidden: true }, password: { label: 'label.password', + docID: 'helpHostPassword', validation: { required: true }, isHidden: true, isPassword: true @@ -7546,6 +8111,7 @@ //always appear (begin) hosttags: { label: 'label.host.tags', + docID: 'helpHostTags', validation: { required: false } } //always appear (end) @@ -7642,7 +8208,7 @@ var array1 = []; array1.push("&hosttags=" + todb(args.data.hosttags)); - if (args.data.oscategoryid != null) + if (args.data.oscategoryid != null && args.data.oscategoryid.length > 0) array1.push("&osCategoryId=" + args.data.oscategoryid); $.ajax({ @@ -7859,13 +8425,12 @@ async: true, success: function(json) { var oscategoryObjs = json.listoscategoriesresponse.oscategory; - var items = []; + var items = [ + { id: '', description: _l('label.none') } + ]; $(oscategoryObjs).each(function() { - if(this.name == 'None') - items.unshift({ id: this.id, description: _l('label.none') }); - else - items.push({id: this.id, description: this.name}); - }); + items.push({id: this.id, description: this.name}); + }); args.response.success({data: items}); } }); @@ -7988,6 +8553,7 @@ fields: { zoneid: { label: 'Zone', + docID: 'helpPrimaryStorageZone', validation: { required: true }, select: function(args) { var data = args.context.zones ? @@ -8014,6 +8580,7 @@ podId: { label: 'label.pod', dependsOn: 'zoneid', + docID: 'helpPrimaryStoragePod', validation: { required: true }, select: function(args) { $.ajax({ @@ -8034,6 +8601,7 @@ clusterId: { label: 'label.cluster', + docID: 'helpPrimaryStorageCluster', validation: { required: true }, dependsOn: 'podId', select: function(args) { @@ -8058,11 +8626,13 @@ name: { label: 'label.name', + docID: 'helpPrimaryStorageName', validation: { required: true } }, protocol: { label: 'label.protocol', + docID: 'helpPrimaryStorageProtocol', validation: { required: true }, dependsOn: 'clusterId', select: function(args) { @@ -8315,6 +8885,7 @@ server: { label: 'label.server', + docID: 'helpPrimaryStorageServer', validation: { required: true }, isHidden: true }, @@ -8322,6 +8893,7 @@ //nfs path: { label: 'label.path', + docID: 'helpPrimaryStoragePath', validation: { required: true }, isHidden: true }, @@ -8329,11 +8901,13 @@ //iscsi iqn: { label: 'label.target.iqn', + docID: 'helpPrimaryStorageTargetIQN', validation: { required: true }, isHidden: true }, lun: { label: 'label.LUN.number', + docID: 'helpPrimaryStorageLun', validation: { required: true }, isHidden: true }, @@ -8382,6 +8956,7 @@ //always appear (begin) storageTags: { label: 'label.storage.tags', + docID: 'helpPrimaryStorageTags', validation: { required: false } } //always appear (end) @@ -8747,6 +9322,7 @@ fields: { zoneid: { label: 'Zone', + docID: 'helpSecondaryStorageZone', validation: { required: true }, select: function(args) { var data = args.context.zones ? @@ -8772,10 +9348,12 @@ }, nfsServer: { label: 'label.nfs.server', + docID: 'helpSecondaryStorageNFSServer', validation: { required: true } }, path: { label: 'label.path', + docID: 'helpSecondaryStoragePath', validation: { required: true } } } @@ -9243,6 +9821,40 @@ }); } + function addNiciraNvpDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { + var array1 = []; + array1.push("&physicalnetworkid=" + physicalNetworkObj.id); + array1.push("&username=" + todb(args.data.username)); + array1.push("&password=" + todb(args.data.password)); + array1.push("&hostname=" + todb(args.data.host)); + array1.push("&transportzoneuuid=" + todb(args.data.transportzoneuuid)); + + var l3GatewayServiceUuid = args.data.l3gatewayserviceuuid; + if(l3GatewayServiceUuid != null && l3GatewayServiceUuid.length > 0) { + array1.push("&l3gatewayserviceuuid=" + todb(args.data.l3gatewayserviceuuid)); + } + + $.ajax({ + url: createURL(apiCmd + array1.join("")), + dataType: "json", + success: function(json) { + var jid = json[apiCmdRes].jobid; + args.response.success( + {_custom: + {jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult[apiCmdObj]; + + return item; + } + } + } + ); + } + }); + } + + var afterCreateZonePhysicalNetworkTrafficTypes = function(args, newZoneObj, newPhysicalnetwork) { $.ajax({ url: createURL("updatePhysicalNetwork&state=Enabled&id=" + newPhysicalnetwork.id), @@ -9632,7 +10244,9 @@ if (jsonObj.resourcestate == "Enabled") { allowedActions.push("edit"); allowedActions.push("enableMaintenanceMode"); - allowedActions.push("forceReconnect"); + + if(jsonObj.state != "Disconnected") + allowedActions.push("forceReconnect"); } else if (jsonObj.resourcestate == "ErrorInMaintenance") { allowedActions.push("edit"); @@ -9840,6 +10454,9 @@ case "SecurityGroupProvider": nspMap["securityGroups"] = items[i]; break; + case "NiciraNvp": + nspMap["niciraNvp"] = items[i]; + break; } } } @@ -9856,7 +10473,12 @@ id: 'virtualRouter', name: 'Virtual Router', state: nspMap.virtualRouter ? nspMap.virtualRouter.state : 'Disabled' - } + }, + { + id: 'niciraNvp', + name: 'Nicira Nvp', + state: nspMap.niciraNvp ? nspMap.niciraNvp.state : 'Disabled' + } ]; if(selectedZoneObj.networktype == "Basic") { diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js index 7a99d79b4fc..f6c209a4a30 100644 --- a/ui/scripts/templates.js +++ b/ui/scripts/templates.js @@ -48,6 +48,36 @@ zonename: { label: 'label.zone' }, hypervisor: { label: 'label.hypervisor' } }, + + advSearchFields: { + name: { label: 'Name' }, + zoneid: { + label: 'Zone', + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); + } + }, + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + reorder: cloudStack.api.actions.sort('updateTemplate', 'templates'), actions: { add: { @@ -58,23 +88,28 @@ } }, createForm: { - title: 'label.action.register.template', + title: 'label.action.register.template', + docID:'helpNetworkOfferingName', preFilter: cloudStack.preFilter.createTemplate, fields: { name: { label: 'label.name', + docID:'helpRegisterTemplateName', validation: { required: true } }, description: { label: 'label.description', + docID: 'helpRegisterTemplateDescription', validation: { required: true } }, url: { label: 'URL', + docID: 'helpRegisterTemplateURL', validation: { required: true } }, zone: { label: 'label.zone', + docID: 'helpRegisterTemplateZone', select: function(args) { $.ajax({ url: createURL("listZones&available=true"), @@ -96,6 +131,7 @@ }, hypervisor: { label: 'label.hypervisor', + docID: 'helpRegisterTemplateHypervisor', dependsOn: 'zone', select: function(args) { if(args.zone == null) @@ -177,6 +213,7 @@ format: { label: 'label.format', + docID: 'helpRegisterTemplateFormat', dependsOn: 'hypervisor', select: function(args) { var items = []; @@ -206,6 +243,7 @@ osTypeId: { label: 'label.os.type', + docID: 'helpRegisterTemplateOSType', select: function(args) { $.ajax({ url: createURL("listOsTypes"), @@ -221,22 +259,26 @@ isExtractable: { label: "extractable", + docID: 'helpRegisterTemplateExtractable', isBoolean: true }, isPasswordEnabled: { label: "label.password.enabled", + docID: 'helpRegisterTemplatePasswordEnabled', isBoolean: true }, isPublic: { label: "label.public", + docID: 'helpRegisterTemplatePublic', isBoolean: true, isHidden: true }, isFeatured: { label: "label.featured", + docID: 'helpRegisterTemplateFeatured', isBoolean: true, isHidden: true } @@ -244,34 +286,51 @@ }, action: function(args) { - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displayText=" + todb(args.data.description)); - array1.push("&url=" + todb(args.data.url)); - array1.push("&zoneid=" + args.data.zone); - array1.push("&format=" + args.data.format); - array1.push("&isextractable=" + (args.data.isExtractable=="on")); - array1.push("&passwordEnabled=" + (args.data.isPasswordEnabled=="on")); - array1.push("&osTypeId=" + args.data.osTypeId); - array1.push("&hypervisor=" + args.data.hypervisor); - - if(args.$form.find('.form-item[rel=isPublic]').css("display") != "none") - array1.push("&ispublic=" + (args.data.isPublic == "on")); - if(args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") - array1.push("&isfeatured=" + (args.data.isFeatured == "on")); + var data = { + name: args.data.name, + displayText: args.data.description, + url: args.data.url, + zoneid: args.data.zone, + format: args.data.format, + isextractable: (args.data.isExtractable=="on"), + passwordEnabled: (args.data.isPasswordEnabled=="on"), + osTypeId: args.data.osTypeId, + hypervisor: args.data.hypervisor + }; + + if(args.$form.find('.form-item[rel=isPublic]').css("display") != "none") { + $.extend(data, { + ispublic: (args.data.isPublic == "on") + }); + } + + if(args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") { + $.extend(data, { + isfeatured: (args.data.isFeatured == "on") + }); + } //VMware only (starts here) - if(args.$form.find('.form-item[rel=rootDiskControllerType]').css("display") != "none" && args.data.rootDiskControllerType != "") - array1.push("&details[0].rootDiskController=" + args.data.rootDiskControllerType); - if(args.$form.find('.form-item[rel=nicAdapterType]').css("display") != "none" && args.data.nicAdapterType != "") - array1.push("&details[0].nicAdapter=" + args.data.nicAdapterType); - if(args.$form.find('.form-item[rel=keyboardType]').css("display") != "none" && args.data.keyboardType != "") - array1.push("&details[0].keyboard=" + args.data.keyboardType); + if(args.$form.find('.form-item[rel=rootDiskControllerType]').css("display") != "none" && args.data.rootDiskControllerType != "") { + $.extend(data, { + 'details[0].rootDiskController': args.data.rootDiskControllerType + }); + } + if(args.$form.find('.form-item[rel=nicAdapterType]').css("display") != "none" && args.data.nicAdapterType != "") { + $.extend(data, { + 'details[0].nicAdapter': args.data.nicAdapterType + }); + } + if(args.$form.find('.form-item[rel=keyboardType]').css("display") != "none" && args.data.keyboardType != "") { + $.extend(data, { + 'details[0].keyboard': args.data.keyboardType + }); + } //VMware only (ends here) $.ajax({ - url: createURL("registerTemplate" + array1.join("")), - dataType: "json", + url: createURL('registerTemplate'), + data: data, success: function(json) { var items = json.registertemplateresponse.template; //items might have more than one array element if it's create templates for all zones. args.response.success({data:items[0]}); @@ -301,43 +360,44 @@ } }, - dataProvider: function(args) { - var array1 = []; + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + var ignoreProject = false; - if(args.filterBy != null) { + if(args.filterBy != null) { //filter dropdown if(args.filterBy.kind != null) { switch(args.filterBy.kind) { case "all": ignoreProject = true; - array1.push("&templatefilter=all"); + $.extend(data, { + templatefilter: 'all' + }); break; case "mine": - array1.push("&templatefilter=self"); + $.extend(data, { + templatefilter: 'self' + }); break; case "featured": ignoreProject = true; - array1.push("&templatefilter=featured"); + $.extend(data, { + templatefilter: 'featured' + }); break; case "community": ignoreProject = true; - array1.push("&templatefilter=community"); + $.extend(data, { + templatefilter: 'community' + }); break; } - } - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } + } } + $.ajax({ - url: createURL("listTemplates&page=" + args.page + "&pagesize=" + pageSize + array1.join(""), - { ignoreProject: ignoreProject }), - dataType: "json", - async: true, + url: createURL('listTemplates', { ignoreProject: ignoreProject }), + data: data, success: function(json) { var items = json.listtemplatesresponse.template; args.response.success({ @@ -354,54 +414,83 @@ edit: { label: 'label.edit', action: function(args) { - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displaytext=" + todb(args.data.displaytext)); - array1.push("&ostypeid=" + args.data.ostypeid); - array1.push("&passwordenabled=" + (args.data.passwordenabled=="on")); + //***** updateTemplate ***** + var data = { + id: args.context.templates[0].id, + zoneid: args.context.templates[0].zoneid, + name: args.data.name, + displaytext: args.data.displaytext, + ostypeid: args.data.ostypeid, + passwordenabled: (args.data.passwordenabled=="on") + }; $.ajax({ - url: createURL("updateTemplate&id=" + args.context.templates[0].id + "&zoneid=" + args.context.templates[0].zoneid + array1.join("")), - dataType: "json", + url: createURL('updateTemplate'), + data: data, async: false, success: function(json) { //API returns an incomplete embedded object (some properties are missing in the embedded template object) } - }); - - var array2 = []; - - //array2.push("&ispublic=" + (args.data.ispublic=="on")); - if(args.data.ispublic == "on") - array2.push("&ispublic=true"); - else if(args.data.ispublic == "off") - array2.push("&ispublic=false"); - //if args.data.ispublic is undefined, do not pass ispublic to API call. + }); - if(args.data.isfeatured == "on") - array2.push("&isfeatured=true"); - else if(args.data.isfeatured == "off") - array2.push("&isfeatured=false"); + + //***** updateTemplatePermissions ***** + var data = { + id: args.context.templates[0].id, + zoneid: args.context.templates[0].zoneid + }; + + //if args.data.ispublic is undefined, do not pass ispublic to API call. + if(args.data.ispublic == "on") { + $.extend(data, { + ispublic: true + }); + } + else if(args.data.ispublic == "off") { + $.extend(data, { + ispublic: false + }); + } //if args.data.isfeatured is undefined, do not pass isfeatured to API call. - - if(args.data.isextractable == "on") - array2.push("&isextractable=true"); - else if(args.data.isextractable == "off") - array2.push("&isextractable=false"); - //if args.data.isextractable is undefined, do not pass isextractable to API call. - + if(args.data.isfeatured == "on") { + $.extend(data, { + isfeatured: true + }); + } + else if(args.data.isfeatured == "off") { + $.extend(data, { + isfeatured: false + }); } + //if args.data.isextractable is undefined, do not pass isextractable to API call. + if(args.data.isextractable == "on") { + $.extend(data, { + isextractable: true + }); + } + else if(args.data.isextractable == "off") { + $.extend(data, { + isextractable: false + }); + } $.ajax({ - url: createURL("updateTemplatePermissions&id=" + args.context.templates[0].id + "&zoneid=" + args.context.templates[0].zoneid + array2.join("")), - dataType: "json", + url: createURL('updateTemplatePermissions'), + data: data, async: false, success: function(json) { //API doesn't return an embedded object } }); + + //***** listTemplates ***** //So, we call listTemplates API to get a complete template object + var data = { + id: args.context.templates[0].id, + zoneid: args.context.templates[0].zoneid, + templatefilter: 'self' + }; $.ajax({ - url: createURL("listTemplates&id=" + args.context.templates[0].id + "&zoneid=" + args.context.templates[0].zoneid + "&templatefilter=self"), - dataType: "json", + url: createURL('listTemplates'), + data: data, async: false, success: function(json){ var item = json.listtemplatesresponse.template; @@ -430,6 +519,7 @@ fields: { destinationZoneId: { label: 'label.destination.zone', + docID: 'helpCopyTemplateDestination', validation: { required: true }, select: function(args) { $.ajax({ @@ -828,25 +918,34 @@ action: function(args) { - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displayText=" + todb(args.data.description)); - array1.push("&url=" + todb(args.data.url)); - array1.push("&zoneid=" + args.data.zone); - array1.push("&isextractable=" + (args.data.isExtractable=="on")); - array1.push("&bootable=" + (args.data.isBootable=="on")); + var data = { + name: args.data.name, + displayText: args.data.description, + url: args.data.url, + zoneid: args.data.zone, + isextractable: (args.data.isExtractable=="on"), + bootable: (args.data.isBootable=="on") + }; - if(args.$form.find('.form-item[rel=osTypeId]').css("display") != "none") - array1.push("&osTypeId=" + args.data.osTypeId); - - if(args.$form.find('.form-item[rel=isPublic]').css("display") != "none") - array1.push("&ispublic=" + (args.data.isPublic == "on")); - if(args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") - array1.push("&isfeatured=" + (args.data.isFeatured == "on")); + if(args.$form.find('.form-item[rel=osTypeId]').css("display") != "none") { + $.extend(data, { + osTypeId: args.data.osTypeId + }); + } + if(args.$form.find('.form-item[rel=isPublic]').css("display") != "none") { + $.extend(data, { + ispublic: (args.data.isPublic == "on") + }); + } + if(args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") { + $.extend(data, { + isfeatured: (args.data.isFeatured == "on") + }); + } $.ajax({ - url: createURL("registerIso" + array1.join("")), - dataType: "json", + url: createURL('registerIso'), + data: data, success: function(json) { var items = json.registerisoresponse.iso; //items might have more than one array element if it's create ISOs for all zones. args.response.success({data:items[0]}); @@ -876,43 +975,73 @@ } }, + advSearchFields: { + name: { label: 'Name' }, + zoneid: { + label: 'Zone', + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); + } + }, + tagKey: { label: 'Tag Key' }, + tagValue: { label: 'Tag Value' } + }, + dataProvider: function(args) { - var array1 = []; + var data = {}; + listViewDataProvider(args, data); + var ignoreProject = false; - if(args.filterBy != null) { + if(args.filterBy != null) { //filter dropdown if(args.filterBy.kind != null) { switch(args.filterBy.kind) { case "all": ignoreProject = true; - array1.push("&isofilter=all"); + $.extend(data, { + isofilter: 'all' + }); break; case "mine": - array1.push("&isofilter=self"); + $.extend(data, { + isofilter: 'self' + }); break; case "featured": ignoreProject = true; - array1.push("&isofilter=featured"); + $.extend(data, { + isofilter: 'featured' + }); break; case "community": ignoreProject = true; - array1.push("&isofilter=community"); + $.extend(data, { + isofilter: 'community' + }); break; } - } - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } + } + } $.ajax({ - url: createURL("listIsos&page=" + args.page + "&pagesize=" + pageSize + array1.join(""), { ignoreProject: ignoreProject }), - dataType: "json", - async: true, + url: createURL('listIsos', { ignoreProject: ignoreProject }), + data: data, success: function(json) { var items = json.listisosresponse.iso; args.response.success({ @@ -929,36 +1058,81 @@ edit: { label: 'label.edit', action: function(args) { - var array1 = []; - array1.push("&name=" + todb(args.data.name)); - array1.push("&displaytext=" + todb(args.data.displaytext)); - array1.push("&ostypeid=" + args.data.ostypeid); + //***** updateIso ***** + var data = { + id: args.context.isos[0].id, + zoneid: args.context.isos[0].zoneid, + name: args.data.name, + displaytext: args.data.displaytext, + ostypeid: args.data.ostypeid + }; $.ajax({ - url: createURL("updateIso&id=" + args.context.isos[0].id + "&zoneid=" + args.context.isos[0].zoneid + array1.join("")), - dataType: "json", + url: createURL('updateIso'), + data: data, async: false, success: function(json) { //updateIso API returns an incomplete ISO object (isextractable and isfeatured are missing) } }); - var array2 = []; - array2.push("&ispublic=" + (args.data.ispublic=="on")); - array2.push("&isfeatured=" + (args.data.isfeatured=="on")); - array2.push("&isextractable=" + (args.data.isextractable=="on")); + + //***** updateIsoPermissions ***** + var data = { + id: args.context.isos[0].id, + zoneid: args.context.isos[0].zoneid, + }; + //if args.data.ispublic is undefined, do not pass ispublic to API call. + if(args.data.ispublic == "on") { + $.extend(data, { + ispublic: true + }); + } + else if(args.data.ispublic == "off") { + $.extend(data, { + ispublic: false + }); + } + //if args.data.isfeatured is undefined, do not pass isfeatured to API call. + if(args.data.isfeatured == "on") { + $.extend(data, { + isfeatured: true + }); + } + else if(args.data.isfeatured == "off") { + $.extend(data, { + isfeatured: false + }); } + //if args.data.isextractable is undefined, do not pass isextractable to API call. + if(args.data.isextractable == "on") { + $.extend(data, { + isextractable: true + }); + } + else if(args.data.isextractable == "off") { + $.extend(data, { + isextractable: false + }); + } $.ajax({ - url: createURL("updateIsoPermissions&id=" + args.context.isos[0].id + "&zoneid=" + args.context.isos[0].zoneid + array2.join("")), - dataType: "json", + url: createURL('updateIsoPermissions'), + data: data, async: false, success: function(json) { //updateIsoPermissions API doesn't return ISO object } }); + + //***** listIsos ***** //So, we call listIsos API to get a complete ISO object + var data = { + id: args.context.isos[0].id, + zoneid: args.context.isos[0].zoneid, + isofilter: 'self' + }; $.ajax({ - url: createURL("listIsos&id=" + args.context.isos[0].id + "&zoneid=" + args.context.isos[0].zoneid + "&isofilter=self"), - dataType: "json", + url: createURL('listIsos'), + data: data, async: false, success: function(json){ var item = json.listisosresponse.iso; diff --git a/ui/scripts/ui-custom/enableStaticNAT.js b/ui/scripts/ui-custom/enableStaticNAT.js index 405813e7a39..47d5dd298db 100644 --- a/ui/scripts/ui-custom/enableStaticNAT.js +++ b/ui/scripts/ui-custom/enableStaticNAT.js @@ -89,7 +89,9 @@ } var complete = args.complete; + var start = args.start; + start(); $dataList.fadeOut(function() { action({ tierID: $dataList.find('.tier-select select').val(), diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js index 5ac8a22f95e..6a9a0570d2d 100644 --- a/ui/scripts/ui-custom/instanceWizard.js +++ b/ui/scripts/ui-custom/instanceWizard.js @@ -264,6 +264,25 @@ }, { 'wizard-field': 'template' }); + var $templateHypervisor = $step.find('input[type=hidden][wizard-field=hypervisor]'); + + // Get hypervisor from template + if (type == 'featuredtemplates' || type == 'communitytemplates' || type == 'mytemplates') { + $selects.each(function() { + var $select = $(this); + var template = $.grep(args.data.templates[type], function(tmpl, v) { + return tmpl.id == $select.find('input').val(); + })[0]; + + $select.change(function() { + $templateHypervisor + .attr('disabled', false) + .val(template.hypervisor); + }); + }); + } else { + $templateHypervisor.attr('disabled', 'disabled'); + } if (type == 'featuredisos' || type == 'communityisos' || type == 'myisos') { // Create hypervisor select @@ -635,45 +654,50 @@ }, 'review': function($step, formData) { - $step.find('[wizard-field]').each(function() { - var field = $(this).attr('wizard-field'); - var fieldName; - var $input = $wizard.find('[wizard-field=' + field + ']').filter(function() { - return $(this).is(':selected') || $(this).is(':checked'); - }); + $step.find('[wizard-field]').each(function() { + var field = $(this).attr('wizard-field'); + var fieldName; + var $input = $wizard.find('[wizard-field=' + field + ']').filter(function() { + return ($(this).is(':selected') || + $(this).is(':checked') || + $(this).attr('type') == 'hidden') && + $(this).is(':not(:disabled)'); + }); - if ($input.is('option')) { - fieldName = $input.html(); - } else if ($input.is('input[type=radio]')) { + if ($input.is('option')) { + fieldName = $input.html(); + } else if ($input.is('input[type=radio]')) { // Choosen New network as default if ($input.parents('div.new-network').size()) { fieldName = $input.closest('div.new-network').find('input[name="new-network-name"]').val(); - // Choosen Network from existed + // Choosen Network from existed } else if ($input.parents('div.my-networks').size()) { fieldName = $input.closest('div.select').find('.select-desc .name').html(); } else { - fieldName = $input.parent().find('.select-desc .name').html(); - } + fieldName = $input.parent().find('.select-desc .name').html(); + } } else if ($input.eq(0).is('input[type=checkbox]')) { fieldName = ''; $input.each(function(index) { if (index != 0) fieldName += '
      '; fieldName += $(this).next('div.select-desc').find('.name').html(); }); + } else if ($input.is('input[type=hidden]')) { + fieldName = $input.val(); + } + + if (fieldName) { + $(this).html(fieldName); + } else { + $(this).html('(' + _l('label.none') + ')'); } - if (fieldName) { - $(this).html(fieldName); - } else { - $(this).html('(' + _l('label.none') + ')'); - } - var conditionalFieldFrom = $(this).attr('conditional-field'); if (conditionalFieldFrom) { if ($wizard.find('.'+conditionalFieldFrom).css('display') == 'block') { - $(this).closest('div.select').show(); + $(this).closest('div.select').show(); } else { - $(this).closest('div.select').hide(); + $(this).closest('div.select').hide(); } } }); diff --git a/ui/scripts/ui-custom/zoneChart.js b/ui/scripts/ui-custom/zoneChart.js index dcc6dacc6c5..12ba6aa6edc 100644 --- a/ui/scripts/ui-custom/zoneChart.js +++ b/ui/scripts/ui-custom/zoneChart.js @@ -307,6 +307,7 @@ args.response.success({ actionFilter: actionFilter, data: data }); }, detailView: { + noCompact: true, tabs: { network: { title: 'Network', diff --git a/ui/scripts/ui/dialog.js b/ui/scripts/ui/dialog.js index 2d22637f6d5..89da8bb3a5b 100644 --- a/ui/scripts/ui/dialog.js +++ b/ui/scripts/ui/dialog.js @@ -65,9 +65,14 @@ var $formItem = $('
      ') .addClass('form-item') .attr({ rel: key }); - - if (field.hidden || field.isHidden) $formItem.hide(); - + + if(field.isHidden != null) { + if (typeof(field.isHidden) == 'boolean' && field.isHidden == true) + $formItem.hide(); + else if (typeof(field.isHidden) == 'function' && field.isHidden() == true) + $formItem.hide(); + } + $formItem.appendTo($form); //Handling Escape KeyPress events @@ -91,10 +96,7 @@ closeOnEscape: false }); */ // Label field - - //if( field.label == 'label.network.offering' || field.label == 'label.guest.gateway') - // debugger; - + var $name = $('
      ').addClass('name') .appendTo($formItem) .append( @@ -198,9 +200,8 @@ selectFn = field.select; $input = $('').attr({ - type: 'text', - name: field.range[0] - }), + } else if (field.isDatepicker) { //jQuery datepicker + $input = $('').attr({ + name: key, + type: 'text' + }).appendTo($value); - // Range end - $('').attr({ - type: 'text', - name: field.range[1] - }) - ).appendTo( - $('
      ').addClass('range-edit').appendTo($value) - ); + if (field.defaultValue) { + $input.val(field.defaultValue); + } + if (field.id) { + $input.attr('id', field.id); + } + $input.addClass("disallowSpecialCharacters"); + $input.datepicker({dateFormat: 'yy-mm-dd'}); + + } else if(field.range) { //2 text fields on the same line (e.g. port range: startPort - endPort) + $input = $.merge( + // Range start + $('').attr({ + type: 'text', + name: field.range[0] + }), - $input.wrap($('
      ').addClass('range-item')); - } else { - $input = $('').attr({ - name: key, - type: field.password || field.isPassword ? 'password' : 'text' - }).appendTo($value); + // Range end + $('').attr({ + type: 'text', + name: field.range[1] + }) + ).appendTo( + $('
      ').addClass('range-edit').appendTo($value) + ); + $input.wrap($('
      ').addClass('range-item')); + $input.addClass("disallowSpecialCharacters"); + + } else { //text field + $input = $('').attr({ + name: key, + type: field.password || field.isPassword ? 'password' : 'text' + }).appendTo($value); - if (field.defaultValue) { - $input.val(field.defaultValue); - } - if (field.id) { - $input.attr('id', field.id); - } - } + if (field.defaultValue) { + $input.val(field.defaultValue); + } + if (field.id) { + $input.attr('id', field.id); + } $input.addClass("disallowSpecialCharacters"); } @@ -347,10 +362,23 @@ else $input.data('validation-rules', {}); - var fieldLabel = field.label; - var inputId = $input.attr('id') ? $input.attr('id') : fieldLabel.replace(/\./g,'_'); - $input.attr('id', inputId); - $name.find('label').attr('for', inputId); + var fieldLabel = field.label; + var inputId = $input.attr('id') ? $input.attr('id') : fieldLabel.replace(/\./g,'_'); + + $input.attr('id', inputId); + $name.find('label').attr('for', inputId); + + // Tooltip + if (field.docID) { + $input.toolTip({ + docID: field.docID, + tooltip:'.tooltip-box', + mode:'focus' + }); + } + /* $input.blur(function() { + console.log('tooltip remove->' + $input.attr('name')); + });*/ }); var getFormValues = function() { @@ -402,6 +430,7 @@ return $formContainer.dialog({ dialogClass: 'create-form', closeOnEscape: false, + draggable: false, width: 400, title: _l(args.form.title), open: function() { @@ -417,9 +446,12 @@ if (!complete($formContainer)) { return false; } $('div.overlay').remove(); + $('.tooltip-box').remove(); $formContainer.remove(); $(this).dialog('destroy'); + $('.hovered-elem').hide(); + return true; } }, @@ -428,8 +460,11 @@ 'class': 'cancel', click: function() { $('div.overlay').remove(); + $('.tooltip-box').remove(); $formContainer.remove(); $(this).dialog('destroy'); + + $('.hovered-elem').hide(); } } ] @@ -498,6 +533,7 @@ $(this).dialog('destroy'); $('div.overlay').remove(); if (args.cancelAction) { args.cancelAction(); } + $('.hovered-elem').hide(); } }, { @@ -507,6 +543,7 @@ args.action(); $(this).dialog('destroy'); $('div.overlay').remove(); + $('.hovered-elem').hide(); } } ] @@ -533,6 +570,7 @@ click: function() { $(this).dialog('destroy'); if (args.clickAction) args.clickAction(); + $('.hovered-elem').hide(); } } ] diff --git a/ui/scripts/ui/widgets/cloudBrowser.js b/ui/scripts/ui/widgets/cloudBrowser.js index 2cd0169b0c4..47fbd0a08b5 100644 --- a/ui/scripts/ui/widgets/cloudBrowser.js +++ b/ui/scripts/ui/widgets/cloudBrowser.js @@ -362,11 +362,37 @@ var $hiddenPanels = data.panel.siblings().filter(function(){ return $(this).index() > data.panel.index(); }); + var $targetPanel = data.panel.filter(':first'); + var $targetBreadcrumb = _breadcrumb.filter($targetPanel); + var $panelWrapper = $('
      ').addClass('panel panel-highlight-wrapper'); $hiddenPanels.addClass('mouseover-hidden'); - setTimeout(function() { - $('.mouseover-hidden').fadeOut('fast'); - }, 1000); + + $browser.data('browser-panel-highlight-timer', setTimeout(function() { + $('#browser').addClass('panel-highlight'); + $('.overlay').remove(); + + // Setup panel and wrapper positioning + $panelWrapper + .css({ + left: $targetPanel.position().left + }) + .width($targetPanel.width()); + $targetPanel + .wrap($panelWrapper); + $panelWrapper + .zIndex(10000) + .overlay(); + $targetPanel.filter(':last').addClass('highlighted'); + + // Setup breadcrumbs + $targetBreadcrumb.each(function() { + $(this).data('breadcrumb-original-zindex', $(this).zIndex()); + }); + $targetBreadcrumb.zIndex(10001); + + $hiddenPanels.hide(); + }, 1000)); } } )); @@ -375,9 +401,26 @@ 'cloudBrowser', { 'breadcrumb': function($target, $browser, data) { - var $getHiddenPanels = $browser.find('.panel.mouseover-hidden'); - + var $getHiddenPanels = $browser.find('.panel.mouseover-hidden'); + var $visiblePanels = $getHiddenPanels.siblings(); + var $visibleBreadcrumbs = _breadcrumb.filter($visiblePanels); + + clearTimeout($browser.data('browser-panel-highlight-timer')); + $('#browser').removeClass('panel-highlight'); + $('#browser .panel').removeClass('highlighted'); + $('#browser .panel.panel-highlight-wrapper').each(function() { + var $wrapper = $(this); + var $panel = $wrapper.find('.panel'); + + $wrapper.after($panel); + $wrapper.remove(); + }); $getHiddenPanels.removeClass('mouseover-hidden').show(); + $visibleBreadcrumbs.each(function() { + $(this).zIndex($(this).data('breadcrumb-original-zindex')); + }); + $('.overlay').remove(); + $('#browser .panel > .highlight-arrow').remove(); } } )); diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js index fc2ae459243..4fc2689ab4e 100644 --- a/ui/scripts/ui/widgets/detailView.js +++ b/ui/scripts/ui/widgets/detailView.js @@ -21,6 +21,9 @@ if (!$row) return; var $listView = $row.closest('.list-view'); + + if (!$listView.parents('html').size()) return; + var $newRow; var jsonObj = $row.data('json-obj'); @@ -94,17 +97,28 @@ if (!options) options = {}; var $form = options.$form; + var viewArgs = $detailView.data('view-args'); + var $loading = $('
      ').addClass('loading-overlay'); + + var setLoadingState = function() { + if (viewArgs && viewArgs.onPerformAction) { + viewArgs.onPerformAction(); + } + + $detailView.addClass('detail-view-loading-state'); + $detailView.prepend($loading); + }; if (customAction && !noAdd) { customAction({ context: context, $detailView: $detailView, + start: setLoadingState, complete: function(args) { - // Set loading appearance - var $loading = $('
      ').addClass('loading-overlay'); - - $detailView.prepend($loading); - + if (!$detailView.hasClass('detail-view-loading-state')) { + setLoadingState(); + } + args = args ? args : {}; var $item = args.$item; @@ -119,9 +133,14 @@ // Success function(args) { - if (!$detailView.is(':visible')) return; + if (viewArgs && viewArgs.onActionComplete) { + viewArgs.onActionComplete(); + } + + if (!$detailView.parents('html').size()) return; $loading.remove(); + $detailView.removeClass('detail-view-loading-state'); replaceListViewItem($detailView, args.data); if (!noRefresh) { @@ -162,10 +181,10 @@ cloudStack.ui.notifications.add( notification, function(args2) { //name parameter as "args2" instead of "args" to avoid override "args" from success: function(args) { - if ($detailView.is(':visible')) { + if ($detailView.parents('html').size()) { $loading.remove(); - if (!noRefresh) { + if (!noRefresh && !viewArgs.compact) { updateTabContent(args.data? args.data : args2.data); } } @@ -180,6 +199,10 @@ })); replaceListViewItem($detailView, args.data ? args.data : args2.data); + + if (viewArgs && viewArgs.onActionComplete) { + viewArgs.onActionComplete(); + } }, {}, @@ -202,6 +225,10 @@ } } }); + + if (viewArgs && viewArgs.onPerformAction) { + viewArgs.onPerformAction(); + } } }; @@ -646,11 +673,16 @@ }); $.each(actions, function(key, value) { - if ($.inArray(key, allowedActions) == -1) return true; + if ($.inArray(key, allowedActions) == -1 || + (key == 'edit' && options.compact)) return true; var $action = $('
      ') .addClass('action').addClass(key) - .appendTo($actions.find('div.buttons')); + .appendTo($actions.find('div.buttons')) + .attr({ + title: _l(value.label), + alt: _l(value.label) + }); var $actionLink = $('') .attr({ href: '#', @@ -664,11 +696,17 @@ ) .appendTo($action); - if (value.textLabel) { + if (value.textLabel || options.compact) { $action .addClass('single text') .prepend( - $('').addClass('label').html(_l(value.textLabel)) + $('').addClass('label').html( + _l( + options.compact ? + (value.compactLabel ? + value.compactLabel : value.label) : value.textLabel + ) + ) ); } @@ -789,7 +827,7 @@ // Set up editable metadata if(typeof(value.isEditable) == 'function') - $value.data('detail-view-is-editable', value.isEditable()); + $value.data('detail-view-is-editable', value.isEditable(context)); else //typeof(value.isEditable) == 'boolean' or 'undefined' $value.data('detail-view-is-editable', value.isEditable); if (value.select) { @@ -835,8 +873,9 @@ $actions = makeActionButtons(detailViewArgs.actions, { actionFilter: actionFilter, data: data, - context: $detailView.data('view-args').context - }); + context: $detailView.data('view-args').context, + compact: detailViewArgs.compact + }).prependTo($firstRow.closest('div.detail-group').closest('.details')); // 'View all' button var showViewAll = detailViewArgs.viewAll ? @@ -912,9 +951,11 @@ { activeTab: targetTabID } ); - $tabContent.append( - $('
      ').addClass('loading-overlay') - ); + if (!$detailView.data('view-args').compact) { + $tabContent.append( + $('
      ').addClass('loading-overlay') + ); + } return dataProvider({ tab: targetTabID, @@ -960,7 +1001,9 @@ actionFilter: actionFilter }).appendTo($tabContent); - if (tabs.tags) { + if (tabs.tags && + $detailView.data('view-args') && + !$detailView.data('view-args').compact) { $('
      ').tagger( $.extend(true, {}, tabs.tags, { context: $detailView.data('view-args').context @@ -968,6 +1011,10 @@ ).appendTo($detailView.find('.main-groups')); } + if ($detailView.data('view-args').onLoad) { + $detailView.data('view-args').onLoad($detailView); + } + return true; }, error: function() { @@ -986,6 +1033,7 @@ var tabFilter = options.tabFilter; var context = options.context ? options.context : {}; var updateContext = $detailView.data('view-args').updateContext; + var compact = options.compact; if (updateContext) { $.extend($detailView.data('view-args').context, updateContext({ @@ -1001,10 +1049,17 @@ ); } - if (tabFilter) { + if (tabFilter && !compact) { removedTabs = tabFilter({ context: context }); + } else if (compact) { + removedTabs = $.grep( + $.map( + tabs, + function(value, key) { return key; } + ), function(tab, index) { return index > 0; } + ); } $.each(tabs, function(key, value) { @@ -1059,9 +1114,12 @@ $.fn.detailView = function(args, options) { var $detailView = this; - + var compact = args.compact; + var $toolbar = makeToolbar(); + var $tabs; + if (options == 'refresh') { - var $tabs = replaceTabs($detailView, args.tabs, { + $tabs = replaceTabs($detailView, args.tabs, { context: args.context, tabFilter: args.tabFilter }); @@ -1073,18 +1131,22 @@ $detailView.data('list-view-row', args.$listViewRow); } - // Create toolbar - var $toolbar = makeToolbar().appendTo($detailView); - - // Create tabs - var $tabs = makeTabs($detailView, args.tabs, { + $tabs = makeTabs($detailView, args.tabs, { + compact: compact, context: args.context, tabFilter: args.tabFilter - }).appendTo($detailView); + }); + + $tabs.appendTo($detailView); + + // Create toolbar + if (!compact) { + $toolbar.appendTo($detailView); + } } $detailView.tabs(); - + return $detailView; }; diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index fb1d8843bed..5281785b1a2 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -468,7 +468,12 @@ }; if (args.cancel) { //click Cancel button - showLabel(); + // showLabel(); + var oldVal = $label.html(); + $edit.hide(); + $label.fadeIn(); + $instanceRow.closest('div.data-table').dataTable('refresh'); + $editInput.val(_s(oldVal)); return false; } @@ -609,9 +614,12 @@ var $thead = $('').prependTo($table).append($('')); var reorder = options.reorder; - + var detailView = options.detailView; + var viewArgs = $table.closest('.list-view').data('view-args'); + var uiCustom = viewArgs.uiCustom; var hiddenFields = []; - if(preFilter != null) + + if (preFilter != null) hiddenFields = preFilter(); $.each(fields, function(key) { @@ -623,14 +631,18 @@ if ($th.index()) $th.addClass('reduced-hide'); $th.html(_l(field.label)); + + return true; }); + // Re-order row buttons if (reorder) { $thead.find('tr').append( $('').html(_l('label.order')).addClass('reorder-actions reduced-hide') ); } + // Actions column if (actions && renderActionCol(actions)) { $thead.find('tr').append( $('') @@ -639,40 +651,63 @@ ); } + // Quick view + if (detailView && + !$.isFunction(detailView) && + !detailView.noCompact && !uiCustom) { + $thead.find('tr').append( + $('') + .html(_l('label.quickview')) + .addClass('quick-view reduced-hide') + ); + } + return $thead; }; var createFilters = function($toolbar, filters) { if (!filters) return false; - var $filters = $('
      ').addClass('filters reduced-hide'); - $filters.append($('