diff --git a/build/developer.xml b/build/developer.xml index 6e516d23db2..8e928baa363 100755 --- a/build/developer.xml +++ b/build/developer.xml @@ -384,8 +384,8 @@ + - @@ -396,5 +396,9 @@ - + + + + + diff --git a/console-proxy/js/ajaxviewer.js b/console-proxy/js/ajaxviewer.js index 14c80fde5c1..3c49f9a701d 100644 --- a/console-proxy/js/ajaxviewer.js +++ b/console-proxy/js/ajaxviewer.js @@ -323,6 +323,10 @@ JsCookedKeyboardMapper.prototype.inputFeed = function(eventType, code, 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}); diff --git a/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java index 4a8b107efd8..30d11a8bbf5 100644 --- a/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java +++ b/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java @@ -619,12 +619,15 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } // untar OVA file at template directory - command = new Script("tar", 0, s_logger); + command = new Script("tar", 0, s_logger); + command.add("--no-same-owner"); command.add("-xf", installFullName); command.setWorkDir(installFullPath); - result = command.execute(); + s_logger.info("Executing command: " + command.toString()); + result = command.execute(); if(result != null) { - String msg = "unable to copy snapshot " + snapshotFullName + " to " + installFullPath; + String msg = "unable to untar snapshot " + snapshotFullName + " to " + + installFullPath; s_logger.error(msg); throw new Exception(msg); } @@ -702,8 +705,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { String srcFileName = getOVFFilePath(srcOVAFileName); if(srcFileName == null) { Script command = new Script("tar", 0, s_logger); + command.add("--no-same-owner"); command.add("-xf", srcOVAFileName); - command.setWorkDir(secondaryMountPoint + "/" + secStorageDir); + command.setWorkDir(secondaryMountPoint + "/" + secStorageDir); + s_logger.info("Executing command: " + command.toString()); String result = command.execute(); if(result != null) { String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName; diff --git a/core/src/com/cloud/storage/template/VmdkProcessor.java b/core/src/com/cloud/storage/template/VmdkProcessor.java index bd354642fdd..f3dbbda3fea 100644 --- a/core/src/com/cloud/storage/template/VmdkProcessor.java +++ b/core/src/com/cloud/storage/template/VmdkProcessor.java @@ -63,7 +63,8 @@ public class VmdkProcessor implements Processor { String templateFileFullPath = templatePath + templateName + "." + ImageFormat.OVA.getFileExtension(); File templateFile = new File(templateFileFullPath); - Script command = new Script("tar", 0, s_logger); + Script command = new Script("tar", 0, s_logger); + command.add("--no-same-owner", templateFileFullPath); command.add("-xf", templateFileFullPath); command.setWorkDir(templateFile.getParent()); String result = command.execute(); diff --git a/deps/cloud-libvirt-0.4.5.jar b/deps/cloud-libvirt-0.4.5.jar index a8ae3f2605d..9d0a1dfbe60 100644 Binary files a/deps/cloud-libvirt-0.4.5.jar and b/deps/cloud-libvirt-0.4.5.jar differ diff --git a/patches/systemvm/debian/config/root/firewall.sh b/patches/systemvm/debian/config/root/firewall.sh index 331de402f21..14e25ad22ba 100755 --- a/patches/systemvm/debian/config/root/firewall.sh +++ b/patches/systemvm/debian/config/root/firewall.sh @@ -78,9 +78,9 @@ tcp_or_udp_entry() { --destination-port $port -j DNAT \ --to-destination $instIp:$dport &>> $OUTFILE || [ "$op" == "-D" ]) && (sudo iptables -t mangle $op PREROUTING --proto $proto -i $dev -d $publicIp \ - --destination-port $port -j MARK --set-mark $tableNo) && + --destination-port $port -j MARK --set-mark $tableNo &>> $OUTFILE || [ "$op" == "-D" ]) && (sudo iptables -t mangle $op PREROUTING --proto $proto -i $dev -d $publicIp \ - --destination-port $port -m state --state NEW -j CONNMARK --save-mark) && + --destination-port $port -m state --state NEW -j CONNMARK --save-mark &>> $OUTFILE || [ "$op" == "-D" ]) && (sudo iptables -t nat $op OUTPUT --proto $proto -d $publicIp \ --destination-port $port -j DNAT \ --to-destination $instIp:$dport &>> $OUTFILE || [ "$op" == "-D" ]) && @@ -193,9 +193,9 @@ static_nat() { # shortcircuit the process if error and it is an append operation # continue if it is delete (sudo iptables -t mangle $op PREROUTING -i $dev -d $publicIp \ - -j MARK --set-mark $tableNo) && + -j MARK --set-mark $tableNo &>> $OUTFILE || [ "$op" == "-D" ]) && (sudo iptables -t mangle $op PREROUTING -i $dev -d $publicIp \ - -m state --state NEW -j CONNMARK --save-mark) && + -m state --state NEW -j CONNMARK --save-mark &>> $OUTFILE || [ "$op" == "-D" ]) && (sudo iptables -t nat $op PREROUTING -i $dev -d $publicIp -j DNAT \ --to-destination $instIp &>> $OUTFILE || [ "$op" == "-D" ]) && (sudo iptables $op FORWARD -i $dev -o eth0 -d $instIp -m state \ diff --git a/python/lib/cloudutils/serviceConfig.py b/python/lib/cloudutils/serviceConfig.py index e8f5f9bdbba..f9379020490 100755 --- a/python/lib/cloudutils/serviceConfig.py +++ b/python/lib/cloudutils/serviceConfig.py @@ -543,7 +543,16 @@ class firewallConfigBase(serviceCfgBase): pass if not status: - bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port) + redo = False + result = True + try: + result = bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port).isSuccess() + except: + redo = True + + if not result or redo: + bash("sleep 30") + bash("iptables -I INPUT -p tcp -m tcp --dport %s -j ACCEPT"%port) def config(self): try: diff --git a/python/lib/cloudutils/serviceConfigServer.py b/python/lib/cloudutils/serviceConfigServer.py index e80b1ed71bd..3e4c5931b7f 100644 --- a/python/lib/cloudutils/serviceConfigServer.py +++ b/python/lib/cloudutils/serviceConfigServer.py @@ -64,7 +64,13 @@ class cloudManagementConfig(serviceCfgBase): #distro like sl 6.1 needs this folder, or tomcat6 failed to start bash("mkdir /var/log/cloud-management/") - + #set max process per account is unlimited + if os.path.exists("/etc/security/limits.conf"): + cfo = configFileOps("/etc/security/limits.conf") + cfo.add_lines("cloud soft nproc -1\n") + cfo.add_lines("cloud hard nproc -1\n") + cfo.save() + try: self.syscfg.svo.disableService("tomcat6") except: diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 4e650b7709f..150f44e0977 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -397,6 +397,8 @@ def can_bridge_firewall(session, args): try: util.pread2(['iptables', '-N', 'BRIDGE-FIREWALL']) util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) util.pread2(['iptables', '-D', 'FORWARD', '-j', 'RH-Firewall-1-INPUT']) except: util.SMlog('Chain BRIDGE-FIREWALL already exists') diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index c56b51a7bc8..113b56310ce 100755 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -177,6 +177,8 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { HostVO host = _hostDao.findById(vm.getLastHostId()); if(host == null){ s_logger.debug("The last host of this VM cannot be found"); + }else if(avoid.shouldAvoid(host)){ + s_logger.debug("The last host of this VM is in avoid set"); }else{ if (host.getStatus() == Status.Up && host.getHostAllocationState() == Host.HostAllocationState.Enabled) { if(_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, cpuOverprovisioningFactor)){ diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 12865a2282c..f54703c3b2a 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -129,7 +129,6 @@ import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; -import com.cloud.utils.DateUtil; import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -645,60 +644,59 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene + ", clusters: " + avoids.getClustersToAvoid() + ", hosts: " + avoids.getHostsToAvoid()); } - - // edit plan if this vm's ROOT volume is in READY state already - List vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); - boolean planChangedByVolume = false; - boolean rootVolumeisRecreatable = false; - DataCenterDeployment originalPlan = plan; - for (VolumeVO vol : vols) { - // make sure if the templateId is unchanged. If it is changed, let planner - // reassign pool for the volume even if it ready. - Long volTemplateId = vol.getTemplateId(); - if (volTemplateId != null && volTemplateId.longValue() != template.getId()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool"); - } - continue; - } - StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); - if (!pool.isInMaintenance()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Root volume is ready, need to place VM in volume's cluster"); - } - long rootVolDcId = pool.getDataCenterId(); - Long rootVolPodId = pool.getPodId(); - Long rootVolClusterId = pool.getClusterId(); - if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){ - Long clusterIdSpecified = planToDeploy.getClusterId(); - if(clusterIdSpecified != null && rootVolClusterId != null){ - if(rootVolClusterId.longValue() != clusterIdSpecified.longValue()){ - //cannot satisfy the plan passed in to the planner - if (s_logger.isDebugEnabled()) { - s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: "+rootVolClusterId + ", cluster specified: "+clusterIdSpecified); - } - throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified); - } - } - plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId()); - }else{ - plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); - } - planChangedByVolume = true; - if(vol.isRecreatable()){ - rootVolumeisRecreatable = true; - } - - } - } - } - + boolean planChangedByVolume = false; + boolean reuseVolume = true; + DataCenterDeployment originalPlan = plan; + int retry = _retry; while (retry-- != 0) { // It's != so that it can match -1. + if(reuseVolume){ + // edit plan if this vm's ROOT volume is in READY state already + List vols = _volsDao.findReadyRootVolumesByInstance(vm.getId()); + for (VolumeVO vol : vols) { + // make sure if the templateId is unchanged. If it is changed, let planner + // reassign pool for the volume even if it ready. + Long volTemplateId = vol.getTemplateId(); + if (volTemplateId != null && volTemplateId.longValue() != template.getId()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(vol + " of " + vm + " is READY, but template ids don't match, let the planner reassign a new pool"); + } + continue; + } + + StoragePoolVO pool = _storagePoolDao.findById(vol.getPoolId()); + if (!pool.isInMaintenance()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Root volume is ready, need to place VM in volume's cluster"); + } + long rootVolDcId = pool.getDataCenterId(); + Long rootVolPodId = pool.getPodId(); + Long rootVolClusterId = pool.getClusterId(); + if(planToDeploy != null && planToDeploy.getDataCenterId() != 0){ + Long clusterIdSpecified = planToDeploy.getClusterId(); + if(clusterIdSpecified != null && rootVolClusterId != null){ + if(rootVolClusterId.longValue() != clusterIdSpecified.longValue()){ + //cannot satisfy the plan passed in to the planner + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cannot satisfy the deployment plan passed in since the ready Root volume is in different cluster. volume's cluster: "+rootVolClusterId + ", cluster specified: "+clusterIdSpecified); + } + throw new ResourceUnavailableException("Root volume is ready in different cluster, Deployment plan provided cannot be satisfied, unable to create a deployment for " + vm, Cluster.class, clusterIdSpecified); + } + } + plan = new DataCenterDeployment(planToDeploy.getDataCenterId(), planToDeploy.getPodId(), planToDeploy.getClusterId(), planToDeploy.getHostId(), vol.getPoolId()); + }else{ + plan = new DataCenterDeployment(rootVolDcId, rootVolPodId, rootVolClusterId, null, vol.getPoolId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug(vol + " is READY, changing deployment plan to use this pool's dcId: " + rootVolDcId + " , podId: " + rootVolPodId + " , and clusterId: " + rootVolClusterId); + } + planChangedByVolume = true; + } + } + } + } + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, account, params); DeployDestination dest = null; for (DeploymentPlanner planner : _planners) { @@ -715,12 +713,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } if (dest == null) { - if(planChangedByVolume){ - if(rootVolumeisRecreatable){ - plan = originalPlan; - planChangedByVolume = false; - continue; - } + if (planChangedByVolume) { + plan = originalPlan; + planChangedByVolume = false; + //do not enter volume reuse for next retry, since we want to look for resorces outside the volume's cluster + reuseVolume = false; + continue; } throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); } @@ -744,7 +742,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene if (vm.getHypervisorType() != HypervisorType.BareMetal) { _storageMgr.prepare(vmProfile, dest); } - + //since StorageMgr succeeded in volume creation, resue Volume for further tries until current cluster has capacity + if(!reuseVolume){ + reuseVolume = true; + } vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); VirtualMachineTO vmTO = hvGuru.implement(vmProfile); diff --git a/setup/apidoc/XmlToHtmlConverter.java b/setup/apidoc/XmlToHtmlConverter.java new file mode 100644 index 00000000000..455bd62352b --- /dev/null +++ b/setup/apidoc/XmlToHtmlConverter.java @@ -0,0 +1,142 @@ +// jdk1.4.1 +import javax.xml.transform.*; +import java.io.*; + +public class XmlToHtmlConverter extends XmlToHtmlConverterData { + + // To turn off generation of API docs for certain roles, comment out + // the appropriate populateFor*() line(s) below. + public static void main(String[] args) { + + XmlToHtmlConverter x = new XmlToHtmlConverter(); + x.populateForRootAdmin(); + x.populateForDomainAdmin(); + x.populateForUser(); + x.generateToc(); + x.generateIndividualCommandPages(); + } + + public void generateToc() { + try { + + TransformerFactory tFactory = TransformerFactory.newInstance(); + + // Generate the TOC for the API reference for User role + Transformer transformer = + tFactory.newTransformer + (new javax.xml.transform.stream.StreamSource + ("generatetocforuser.xsl")); + + // The XML to be transformed must be at the location below. + // Modify this path to match your own setup. + transformer.transform + (new javax.xml.transform.stream.StreamSource + ("regular_user/regularUserSummary.xml"), + // Modify this path to your own desired output location. + new javax.xml.transform.stream.StreamResult + ( new FileOutputStream("html/TOC_User.html"))); + + // Generate the TOC for root administrator role + Transformer transformer1 = + tFactory.newTransformer + (new javax.xml.transform.stream.StreamSource + ("generatetocforadmin.xsl")); + + // The XML to be transformed must be at the location below. + // Modify this path to match your own setup. + transformer1.transform + (new javax.xml.transform.stream.StreamSource + ("root_admin/rootAdminSummary.xml"), + // Modify this path to your own desired output location. + new javax.xml.transform.stream.StreamResult + ( new FileOutputStream("html/TOC_Root_Admin.html"))); + + // Generate the TOC for domain admin role + Transformer transformer2 = + tFactory.newTransformer + (new javax.xml.transform.stream.StreamSource + ("generatetocfordomainadmin.xsl")); + + // The XML to be transformed must be at the location below. + // Modify this path to match your own setup. + transformer2.transform + (new javax.xml.transform.stream.StreamSource + ("domain_admin/domainAdminSummary.xml"), + // Modify this path to your own desired output location. + new javax.xml.transform.stream.StreamResult + ( new FileOutputStream("html/TOC_Domain_Admin.html"))); + + } + catch (Exception e) { + e.printStackTrace( ); + } + } + + // Create man pages + public void generateIndividualCommandPages() { + for(String commandName : rootAdminCommandNames) { + + try { + + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = + tFactory.newTransformer + (new javax.xml.transform.stream.StreamSource + ("generateadmincommands.xsl")); + + transformer.transform + // Modify this path to the location of the input files on your system. + (new javax.xml.transform.stream.StreamSource + ("root_admin/"+commandName+".xml"), + // Modify this path with the desired output location. + new javax.xml.transform.stream.StreamResult + ( new FileOutputStream("html/root_admin/"+commandName+".html"))); + } catch (Exception e) { + e.printStackTrace( ); + } + } + + for(String commandName : domainAdminCommandNames) { + + try { + + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = + tFactory.newTransformer + (new javax.xml.transform.stream.StreamSource + ("generatedomainadmincommands.xsl")); + + transformer.transform + // Modify this path with the location of the input files on your system. + (new javax.xml.transform.stream.StreamSource + ("domain_admin/"+commandName+".xml"), + // Modify this path to the desired output location. + new javax.xml.transform.stream.StreamResult + ( new FileOutputStream("html/domain_admin/"+commandName+".html"))); + } catch (Exception e) { + e.printStackTrace( ); + } + } + + for(String commandName : userCommandNames) { + + try { + + TransformerFactory tFactory = TransformerFactory.newInstance(); + + Transformer transformer = + tFactory.newTransformer + (new javax.xml.transform.stream.StreamSource + ("generateusercommands.xsl")); + + transformer.transform + (new javax.xml.transform.stream.StreamSource + ("regular_user/"+commandName+".xml"), + new javax.xml.transform.stream.StreamResult + ( new FileOutputStream("html/user/"+commandName+".html"))); + } catch (Exception e) { + e.printStackTrace( ); + } + } + } +} diff --git a/setup/apidoc/build-apidoc.sh b/setup/apidoc/build-apidoc.sh index e8c61e2742e..52af2d281f3 100644 --- a/setup/apidoc/build-apidoc.sh +++ b/setup/apidoc/build-apidoc.sh @@ -24,6 +24,11 @@ TARGETJARDIR="$1" shift DEPSDIR="$1" shift +DISTDIR="$1" +shift + +thisdir=$(readlink -f $(dirname "$0")) + PATHSEP=':' if [[ $OSTYPE == "cygwin" ]] ; then @@ -41,9 +46,35 @@ for file in $DEPSDIR/*.jar; do CP=${CP}$PATHSEP$file done -java -cp $CP com.cloud.api.doc.ApiXmlDocWriter $* +java -cp $CP com.cloud.api.doc.ApiXmlDocWriter -d "$DISTDIR" $* if [ $? -ne 0 ] then exit 1 fi + +set -e +(cd "$DISTDIR/xmldoc" + cp "$thisdir"/*.java . + cp "$thisdir"/*.xsl . + sed -e 's,%API_HEADER%,User API,g' "$thisdir/generatetoc_header.xsl" >generatetocforuser.xsl + sed -e 's,%API_HEADER%,Root Admin API,g' "$thisdir/generatetoc_header.xsl" >generatetocforadmin.xsl + sed -e 's,%API_HEADER%,Domain Admin API,g' "$thisdir/generatetoc_header.xsl" >generatetocfordomainadmin.xsl + + python "$thisdir/gen_toc.py" $(find -type f) + + cat generatetocforuser_include.xsl >>generatetocforuser.xsl + cat generatetocforadmin_include.xsl >>generatetocforadmin.xsl + cat generatetocfordomainadmin_include.xsl >>generatetocfordomainadmin.xsl + + cat "$thisdir/generatetoc_footer.xsl" >>generatetocforuser.xsl + cat "$thisdir/generatetoc_footer.xsl" >>generatetocforadmin.xsl + cat "$thisdir/generatetoc_footer.xsl" >>generatetocfordomainadmin.xsl + + mkdir -p html/user html/domain_admin html/root_admin + cp -r "$thisdir/includes" html + cp -r "$thisdir/images" html + + javac -cp . *.java + java -cp . XmlToHtmlConverter +) diff --git a/setup/apidoc/gen_toc.py b/setup/apidoc/gen_toc.py new file mode 100644 index 00000000000..f0d6d2ed4c1 --- /dev/null +++ b/setup/apidoc/gen_toc.py @@ -0,0 +1,246 @@ +#!/usr/bin/python + +import os +import os.path +import sys +from xml.dom import minidom +from xml.parsers.expat import ExpatError + + +REGULAR_USER = 'u' +DOMAIN_ADMIN = 'd' +ROOT_ADMIN = 'r' + +user_to_func = { + REGULAR_USER: 'populateForUser', + DOMAIN_ADMIN: 'populateForDomainAdmin', + ROOT_ADMIN: 'populateForRootAdmin', + } + + +user_to_cns = { + REGULAR_USER: 'userCommandNames', + DOMAIN_ADMIN: 'domainAdminCommandNames', + ROOT_ADMIN: 'rootAdminCommandNames', + } + + +dirname_to_user = { + 'regular_user': REGULAR_USER, + 'domain_admin': DOMAIN_ADMIN, + 'root_admin': ROOT_ADMIN, + } + + +dirname_to_dirname = { + 'regular_user': 'user', + 'domain_admin': 'domain_admin', + 'root_admin': 'root_admin', + } + + +known_categories = { + 'Simulator': 'Simulator', + 'SystemVm': 'System VM', + 'VirtualMachine': 'Virtual Machine', + 'VM': 'Virtual Machine', + 'Domain': 'Domain', + 'Template': 'Template', + 'Iso': 'ISO', + 'Volume': 'Volume', + 'Vlan': 'VLAN', + 'IpAddress': 'Address', + 'PortForwarding': 'Firewall', + 'Firewall': 'Firewall', + 'StaticNat': 'NAT', + 'IpForwarding': 'NAT', + 'Host': 'Host', + 'Cluster': 'Cluster', + 'Account': 'Account', + 'Snapshot': 'Snapshot', + 'User': 'User', + 'Os': 'Guest OS', + 'ServiceOffering': 'Service Offering', + 'DiskOffering': 'Disk Offering', + 'LoadBalancer': 'Load Balancer', + 'Router': 'Router', + 'SystemVm': 'System VM', + 'Configuration': 'Configuration', + 'Capabilities': 'Configuration', + 'Pod': 'Pod', + 'Zone': 'Zone', + 'NetworkOffering': 'Network Offering', + 'Network': 'Network', + 'Vpn': 'VPN', + 'Limit': 'Limit', + 'ResourceCount': 'Limit', + 'CloudIdentifier': 'Cloud Identifier', + 'InstanceGroup': 'VM Group', + 'StorageMaintenance': 'Storage Pool', + 'StoragePool': 'Storage Pool', + 'SecurityGroup': 'Security Group', + 'SSH': 'SSH', + 'register': 'Registration', + 'AsyncJob': 'Async job', + 'Certificate': 'Certificate', + 'Hypervisor': 'Hypervisor', + 'Alert': 'Alert', + 'Event': 'Event', + 'login': 'Login', + 'logout': 'Logout', + 'Capacity': 'System Capacity', + 'NetworkDevice': 'Network Device', + 'ExternalLoadBalancer': 'Ext Load Balancer', + 'ExternalFirewall': 'Ext Firewall', + 'Usage': 'Usage', + 'TrafficMonitor': 'Usage', + 'TrafficType': 'Usage', + 'Product': 'Product', + 'LB': 'Load Balancer', + 'ldap': 'LDAP', + 'Swift': 'Swift', + 'SecondaryStorage': 'Host', + 'Project': 'Project', + 'Lun': 'Storage', + 'Pool': 'Pool', + } + + +categories = {} + + +def choose_category(fn): + for k, v in known_categories.iteritems(): + if k in fn: + return v + raise Exception(fn) + + +for f in sys.argv: + dirname, fn = os.path.split(f) + if not fn.endswith('.xml'): + continue + if fn.endswith('Summary.xml'): + continue + if fn.endswith('SummarySorted.xml'): + continue + if fn == 'alert_types.xml': + continue + if dirname.startswith('./'): + dirname = dirname[2:] + try: + dom = minidom.parse(file(f)) + name = dom.getElementsByTagName('name')[0].firstChild.data + isAsync = dom.getElementsByTagName('isAsync')[0].firstChild.data + category = choose_category(fn) + if category not in categories: + categories[category] = [] + categories[category].append({ + 'name': name, + 'dirname': dirname_to_dirname[dirname], + 'async': isAsync == 'true', + 'user': dirname_to_user[dirname], + }) + except ExpatError, e: + pass + except IndexError, e: + print fn + + +def xml_for(command): + name = command['name'] + async = command['async'] and ' (A)' or '' + dirname = command['dirname'] + return ''' +
  • %(async)s
  • +
    +''' % locals() + + +def write_xml(out, user): + with file(out, 'w') as f: + cat_strings = [] + + for category in categories.keys(): + strings = [] + for command in categories[category]: + if command['user'] == user: + strings.append(xml_for(command)) + if strings: + all_strings = ''.join(strings) + cat_strings.append((len(strings), category, all_strings)) + + cat_strings.sort(reverse=True) + + i = 0 + for _1, category, all_strings in cat_strings: + if i == 0: + print >>f, '
    ' + print >>f, '''
    +
    %(category)s
    +
      + +%(all_strings)s + +
    +
    + +''' % locals() + if i == 3: + print >>f, '
    ' + i = 0 + else: + i += 1 + if i != 0: + print >>f, '' + + +def java_for(command, user): + name = command['name'] + cns = user_to_cns[user] + return '''%(cns)s.add("%(name)s"); +''' % locals() + + +def java_for_user(user): + strings = [] + for category in categories.keys(): + for command in categories[category]: + if command['user'] == user: + strings.append(java_for(command, user)) + func = user_to_func[user] + all_strings = ''.join(strings) + return ''' + public void %(func)s() { + %(all_strings)s + } +''' % locals() + + +def write_java(out): + with file(out, 'w') as f: + print >>f, '''/* Generated using gen_toc.py. Do not edit. */ + +import java.util.HashSet; +import java.util.Set; + +public class XmlToHtmlConverterData { + + Set rootAdminCommandNames = new HashSet(); + Set domainAdminCommandNames = new HashSet(); + Set userCommandNames = new HashSet(); + +''' + print >>f, java_for_user(REGULAR_USER) + print >>f, java_for_user(ROOT_ADMIN) + print >>f, java_for_user(DOMAIN_ADMIN) + + print >>f, ''' +} +''' + + +write_xml('generatetocforuser_include.xsl', REGULAR_USER) +write_xml('generatetocforadmin_include.xsl', ROOT_ADMIN) +write_xml('generatetocfordomainadmin_include.xsl', DOMAIN_ADMIN) +write_java('XmlToHtmlConverterData.java') diff --git a/setup/apidoc/generateadmincommands.xsl b/setup/apidoc/generateadmincommands.xsl new file mode 100644 index 00000000000..063d2848dbd --- /dev/null +++ b/setup/apidoc/generateadmincommands.xsl @@ -0,0 +1,150 @@ + + + + + + + + + +CloudStack API Reference + + + +
    +
    +
    +
    +
    +
    + +
    +
    + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + + + + CloudStack 2.2.14 Root Admin API Reference + +

    +

    +

    +
    +
    + + +
    + +
    +
    +
    +

    Request parameters

    + + + + + + + + + + + + + + + + + + + + + +
    Parameter NameDescriptionRequired
    +
    + + +
    +

    Response Tags

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Response NameDescription
    + +
    + + +
    +
    + + +
    +
    + + + + + +
    +
    +
    + + +
    +
    + diff --git a/setup/apidoc/generatecommand.xsl b/setup/apidoc/generatecommand.xsl new file mode 100644 index 00000000000..e50d8c73e62 --- /dev/null +++ b/setup/apidoc/generatecommand.xsl @@ -0,0 +1,186 @@ + + + + + + + + + +CloudStack API Reference + + + +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    +
    +

    +
    + +
    +
    + + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    + +

    + +
    +
    + + +
    + +
    +
    +
    +

    Request parameters

    + + + + + + + + + + + + + + + +
    Parameter NameDescriptionRequired
    +
    + + +
    +

    Response Tags

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Response NameDescription
    + +
    + + +
    +
    + + +
    +
    + + + + + +
    +
    +
    + + +
    +
    + diff --git a/setup/apidoc/generatecustomcommand.xsl b/setup/apidoc/generatecustomcommand.xsl new file mode 100644 index 00000000000..16c6c64e87f --- /dev/null +++ b/setup/apidoc/generatecustomcommand.xsl @@ -0,0 +1,47 @@ + + + + +Cloudstack API + + + + + + + + + + + + + + + + +
    NameDescriptionRequest ParametersResponse Parameters
    + +
    Name:
    +Description: +
    Required:
    +
    +
    + +
    Name:
    +Description: + +
    Name:
    +Description: + +
    Name:
    +Description: +
    +
    +

    +
    +
    + +
    +
    + diff --git a/setup/apidoc/generatedomainadmincommands.xsl b/setup/apidoc/generatedomainadmincommands.xsl new file mode 100644 index 00000000000..ca4fbdf772a --- /dev/null +++ b/setup/apidoc/generatedomainadmincommands.xsl @@ -0,0 +1,152 @@ + + + + + + + + + +CloudStack API Reference + + + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    +
    + + + + CloudStack v2.2.14 Domain Admin API Reference + +

    +

    +

    +
    +
    + + +
    + +
    +
    +
    +

    Request parameters

    + + + + + + + + + + + + + + + + + + + + + +
    Parameter NameDescriptionRequired
    +
    + + +
    +

    Response Tags

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Response NameDescription
    + +
    + + +
    +
    + + +
    +
    + + + + + +
    +
    +
    + + +
    +
    + diff --git a/setup/apidoc/generategenericcommand.xsl b/setup/apidoc/generategenericcommand.xsl new file mode 100644 index 00000000000..bf055802f10 --- /dev/null +++ b/setup/apidoc/generategenericcommand.xsl @@ -0,0 +1,39 @@ + + + + +Cloudstack API + + + + + + + + + + + + + + + + +
    NameDescriptionRequest ParametersResponse Parameters
    + +
    Name:
    +Description: +
    Required:
    +
    +
    + +
    Name:
    +Description: +

    +
    +
    + +
    +
    + diff --git a/setup/apidoc/generatetoc.xsl b/setup/apidoc/generatetoc.xsl new file mode 100644 index 00000000000..ab209db8003 --- /dev/null +++ b/setup/apidoc/generatetoc.xsl @@ -0,0 +1,1128 @@ + + + + +Cloudstack API + + + +

    Cloudstack API Version 2.2

    +
    +

    Table of Contents

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Name

    Description

    OS Specific Commands



    OS Specific Command Descriptions



    Domain Specific Commands



    Domain Specific Command Descriptions



    Virtual Machine Specific Commands



    Virtual Machine Specific Command Descriptions



    Hypervisor Specific Commands



    Hypervisor Specific Command Descriptions



    Lun Specific Commands



    Lun Specific Command Descriptions



    Template Specific Commands



    Template Specific Command Descriptions



    Storage Pool Specific Commands



    Storage Pool Specific Command Descriptions



    Firewall Specific Commands



    Firewall Specific Command Descriptions



    VM Group Specific Commands



    VM Group Specific Command Descriptions



    Vlan Specific Commands



    Vlan Specific Command Descriptions



    Router Specific Commands



    Router Specific Command Descriptions



    Service Offering Specific Commands



    Service Offering Specific Command Descriptions



    Network Specific Commands



    Network Specific Command Descriptions



    Configuration Specific Commands



    Configuration Specific Command Descriptions



    Account Specific Commands



    Account Specific Command Descriptions



    Registration Specific Commands



    Registration Specific Command Descriptions



    Zone Specific Commands



    Zone Specific Command Descriptions



    Security Group Specific Commands



    Security Group Specific Command Descriptions



    Alert Specific Commands



    Alert Specific Command Descriptions



    Pod Specific Commands



    Pod Specific Command Descriptions



    Async job Specific Commands



    Async job Specific Command Descriptions



    Resource limit Specific Commands



    Resource limit Specific Command Descriptions



    Cloudstack Specific Commands



    Cloudstack Specific Command Descriptions



    Network Offering Specific Commands



    Network Offering Specific Command Descriptions



    Volume Specific Commands



    Volume Specific Command Descriptions



    Ip Address Specific Commands



    Ip Address Specific Command Descriptions



    VPN Specific Commands



    VPN Address Specific Command Descriptions



    Event Specific Commands



    Event Specific Command Descriptions



    Load Balancer Specific Commands



    Load Balancer Specific Command Descriptions



    Iso Specific Commands



    Iso Specific Command Descriptions



    Certificate Specific Commands



    Certificate Specific Command Descriptions



    Host Specific Commands



    Host Specific Command Descriptions



    Snapshot Specific Commands



    Snapshot Specific Command Descriptions



    Disk Offering Specific Commands



    Disk Offering Specific Command Descriptions



    NAT Specific Commands



    NAT Specific Command Descriptions



    Capacity Specific Commands



    Capacity Specific Command Descriptions



    User Specific Commands



    User Specific Command Descriptions



    System VM Specific Commands



    System VM Specific Command Descriptions



    + +
    +
    + diff --git a/setup/apidoc/generatetoc_footer.xsl b/setup/apidoc/generatetoc_footer.xsl new file mode 100644 index 00000000000..fc5bd393706 --- /dev/null +++ b/setup/apidoc/generatetoc_footer.xsl @@ -0,0 +1,32 @@ + + + + + + + + + + + + +
    + + + + + + diff --git a/setup/apidoc/generatetoc_header.xsl b/setup/apidoc/generatetoc_header.xsl new file mode 100644 index 00000000000..e69e3be4b4e --- /dev/null +++ b/setup/apidoc/generatetoc_header.xsl @@ -0,0 +1,52 @@ + + + + + + + + + +CloudStack API Reference + + + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    + +
    +
    + +

    CloudStack API Documentation (v2.2.14)

    +
    +
    +

    Using the CloudStack API

    +

    For information about how the APIs work, and tips on how to use them, see the + Developer's Guide.

    +
    +
    + +
    +

    %API_HEADER%

    + Commands available through the developer API URL and the integration API URL. +
    +

    (A) implies that the command is asynchronous.

    +

    (*) implies element has a child.

    +
    diff --git a/setup/apidoc/generateusercommands.xsl b/setup/apidoc/generateusercommands.xsl new file mode 100644 index 00000000000..143803c743f --- /dev/null +++ b/setup/apidoc/generateusercommands.xsl @@ -0,0 +1,150 @@ + + + + + + + + + +CloudStack API Reference + + + +
    +
    +
    +
    +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    +
    + + + + CloudStack v2.2.14 User API Reference + +

    +

    +

    +
    +
    + + +
    + +
    +
    +
    +

    Request parameters

    + + + + + + + + + + + + + + + + + + + + + +
    Parameter NameDescriptionRequired
    +
    + + +
    +

    Response Tags

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Response NameDescription
    + +
    + + +
    +
    + + +
    +
    + + + + + +
    +
    +
    + + +
    +
    + diff --git a/setup/apidoc/images/api_bullets.gif b/setup/apidoc/images/api_bullets.gif new file mode 100644 index 00000000000..a7ea2f6b9bc Binary files /dev/null and b/setup/apidoc/images/api_bullets.gif differ diff --git a/setup/apidoc/images/back_button.gif b/setup/apidoc/images/back_button.gif new file mode 100644 index 00000000000..509f2565ae4 Binary files /dev/null and b/setup/apidoc/images/back_button.gif differ diff --git a/setup/apidoc/images/back_button_hover.gif b/setup/apidoc/images/back_button_hover.gif new file mode 100644 index 00000000000..7316e8ec041 Binary files /dev/null and b/setup/apidoc/images/back_button_hover.gif differ diff --git a/setup/apidoc/images/cloudstack.png b/setup/apidoc/images/cloudstack.png new file mode 100644 index 00000000000..cc3c9d7d342 Binary files /dev/null and b/setup/apidoc/images/cloudstack.png differ diff --git a/setup/apidoc/images/ins_buttonshadow.gif b/setup/apidoc/images/ins_buttonshadow.gif new file mode 100644 index 00000000000..ac34ec859c9 Binary files /dev/null and b/setup/apidoc/images/ins_buttonshadow.gif differ diff --git a/setup/apidoc/images/insdownload_button.gif b/setup/apidoc/images/insdownload_button.gif new file mode 100644 index 00000000000..eb5cb5e700f Binary files /dev/null and b/setup/apidoc/images/insdownload_button.gif differ diff --git a/setup/apidoc/images/insdownload_button_hover.gif b/setup/apidoc/images/insdownload_button_hover.gif new file mode 100644 index 00000000000..424ab461f52 Binary files /dev/null and b/setup/apidoc/images/insdownload_button_hover.gif differ diff --git a/setup/apidoc/images/insjoincomm_button.gif b/setup/apidoc/images/insjoincomm_button.gif new file mode 100644 index 00000000000..f149c8506c1 Binary files /dev/null and b/setup/apidoc/images/insjoincomm_button.gif differ diff --git a/setup/apidoc/images/insjoincomm_button_hover.gif b/setup/apidoc/images/insjoincomm_button_hover.gif new file mode 100644 index 00000000000..74df0a60e64 Binary files /dev/null and b/setup/apidoc/images/insjoincomm_button_hover.gif differ diff --git a/setup/apidoc/includes/main.css b/setup/apidoc/includes/main.css new file mode 100644 index 00000000000..29804e876a4 --- /dev/null +++ b/setup/apidoc/includes/main.css @@ -0,0 +1,1073 @@ +@charset "UTF-8"; +/* CSS Document */ + + +*{ + margin:0; + padding:0; +} + +body{ + font-family:Arial, Helvetica, sans-serif; + font-size:12px; + color:#333; + font-weight:normal; + background:#FFF repeat top left; + margin:0; + padding:0; +} + + +#inside_wrapper { + width:auto; + height:auto; + margin:0; + padding:0; + overflow:hidden; +} + +#insidetopbg { + width:100%; + height:auto; + margin:0; + padding:0; + overflow:hidden; +} + +.uppermenu_panel { + width:100%; + height:auto; + float:left; + margin:0; + padding:0; +} +.uppermenu_box { + width:auto; + height:29px; + float:right; + margin:0; + padding:0; + +} + +.uppermenu { + width:300px; + height:auto; + float:left; + color:#FFF; + font-size:13px; + font-weight:normal; + text-align:left; + padding:0; + margin:4px 10px 0 0; +} + +.uppermenu a:link { + width:auto; + height:auto; + color:#54bfd3; + font-weight:normal; + text-align:left; + text-decoration:none; + margin:0 5px 0 5px; + +} + +.uppermenu a:visited { + width:auto; + height:auto; + color:#54bfd3; + font-weight:normal; + text-align:left; + text-decoration:none; + margin:0 5px 0 5px; + +} + +.uppermenu a:hover { + width:auto; + height:auto; + color:#ccf004; + font-weight:normal; + text-align:left; + text-decoration:none; + margin:0 5px 0 5px; + +} + + +#main_master { + width:960px; + height:auto; + margin:0 auto; + padding:0; +} + +#inside_header { + width:960px; + height:auto; + float:left; + margin:0 0 0 0; + padding:0; +} + +.header_top { + width:960px; + height:67px; + float:left; + margin:0; + padding:0; +} + +.header_bot { + width:960px; + height:352px; + float:left; + margin:0; + padding:0; +} + +.insideheader_bot { + width:960px; + height:91px; + float:left; + margin:0; + padding:0; +} + +.insideheader_botleft { + width:620px; + height:91px; + float:left; + margin:0; + padding:0; +} + +.insideheader_botleft h1 { + width:auto; + height:auto; + float:left; + color:#199cb4; + font-size:30px; + text-align:left; + font-weight:normal; + letter-spacing:1px; + margin:30px 0 0 0; + padding:0; +} + +.insideheader_botright { + width:340px; + height:91px; + float:left; + margin:0; + padding:0; +} + +.insideheader_button { + width:340px; + height:32px; + float:left; + margin:30px 0 0 0; + padding:0; +} + +a.insjoincomm_button { + width:169px; + height:32px; + float:left; + background:url(../images/insjoincomm_button.gif) no-repeat top left; + margin:0; + padding:0; +} + +a:hover.insjoincomm_button { + background:url(../images/insjoincomm_button_hover.gif) no-repeat top left; +} + +a.insdownload_button { + width:171px; + height:32px; + float:left; + background:url(../images/insdownload_button.gif) no-repeat top left; + margin:0; + padding:0; +} + +a:hover.insdownload_button { + background:url(../images/insdownload_button_hover.gif) no-repeat top left; +} + +.insheader_buttonshadow { + width:336px; + height:14px; + float:left; + background:url(../images/ins_buttonshadow.gif) no-repeat top left; + margin:0; + padding:0; +} +.header_botright { + width:550px; + height:352px; + float:left; + margin:0; + padding:0; +} + +.clear { + clear:both; +} + + +a.cloud_logo { + width:300px; + height:51px; + float:left; + background:url(../images/cloudstack.png) no-repeat top left; + margin:8px 0 0 0; + padding:0; +} + +.mainemenu_panel { + width: 801px; + height:51px; + float:left; + margin:0; + padding:0; +} + +.mainemenu_links { + width: auto; + height:auto; + float:right; + margin:30px 0 0 0; + padding:0; +} + +.mainemenu_links a:link { + width: auto; + height:auto; + font-size:18px; + text-align:left; + font-weight:normal; + text-decoration:none; + color:#FFF; + margin:0 25px 0 0; + padding:0; +} + +.mainemenu_links a:visited { + width: auto; + height:auto; + font-size:18px; + text-align:left; + font-weight:normal; + text-decoration:none; + margin:0 25px 0 0; + padding:0; + color:#FFF; +} + +.mainemenu_links a:hover { + width: auto; + height:auto; + font-size:18px; + text-align:left; + font-weight:normal; + text-decoration:none; + margin:0 25px 0 0; + padding:0; + color:#FFF; +} + +#main_content { + width:960px; + min-height:600px; + height:auto; + float:left; + margin:0; + padding:0; +} + +.main_homecontent_left { + width:600px; + height:auto; + float:left; + margin:0; + padding:0; +} + +.home_introbox { + width:600px; + height:auto; + float:left; + margin: 25px 0 0 0; + padding:0; +} + +.home_introbox h1 { + width:600px; + height:auto; + float:left; + color:#199cb4; + text-align:left; + font-weight:normal; + font-size:22px; + margin:0; + padding:0; +} + +.home_introbox p { + width:600px; + height:auto; + float:left; + text-align:justify; + font-weight:normal; + line-height:22px; + font-size:18px; + margin:10px 0 0 0; + padding:0; +} +.main_homecontent_right { + width:311px; + height:auto; + float:right; + margin:0; + padding:0; +} + +#news_panel { + width:600px; + height:auto; + float:left; + margin:30px 0 0 0; + padding:0; +} + +#news_panel h2 { + width:auto; + height:auto; + float:left; + color:#199cb4; + font-size:18px; + font-weight:normal; + text-align:left; +} + +.news_box { + width:600px; + height:auto; + float:left; + margin:15px 0 0 0; + padding:0; +} + +.news_box a:link { + width:600px; + height:auto; + float:left; + color:#105f8b; + text-align:left; + text-decoration:none; + font-weight:normal; + font-size:15px; +} + +.news_box a:visited { + width:600px; + height:auto; + float:left; + color:#105f8b; + text-align:left; + text-decoration:none; + font-weight:normal; + font-size:15px; +} + +.news_box a:hover { + width:600px; + height:auto; + float:left; + color:#666; + text-align:left; + text-decoration:none; + font-weight:normal; + font-size:15px; +} + +.news_box p { + width:600px; + height:auto; + float:left; + margin:8px 0 0 0; + text-align:left; + font-size:12px; + font-weight:normal; + padding:0; +} + +.news_box span { + width:auto; + height:auto; + float:left; + margin:0; + color:#999; + text-align:left; + font-size:11px; + font-weight:normal; + padding:0; +} + +#partners_panel { + width:311px; + height:auto; + float:left; + margin:30px 0 0 0; + padding:0; +} + +#partners_panel h2 { + width:300px; + height:auto; + float:left; + color:#199cb4; + font-size:18px; + font-weight:normal; + text-align:left; +} + +.partners_box { + width:310px; + height:auto; + float:left; + border-bottom:1px solid #CCC; + margin:15px 0 0 0; +} + +.partners_box_logo { + width:auto; + height:auto; + float:left; + display:block; + margin:0 0 10px 0; + padding:0; + border:0; +} + +.partners_box_small { + width:155px; + height:80px; + float:left; + margin:0; + padding:0; +} + +.readmore_box { + width:100%; + height:29px; + float:left; + margin:15px 0 0 0; + padding:0; +} + +.readmore_box a:link { + width:auto; + height:auto; + float:right; + color:#105f8b; + font-size:12px; + font-weight:normal; + text-decoration:none; + text-align:right; + margin:0 10px 0 0; + padding:0; +} + +.readmore_box a:visited { + width:auto; + height:auto; + float:right; + color:#105f8b; + font-size:12px; + font-weight:normal; + text-decoration:none; + text-align:right; + margin:0 10px 0 0; + padding:0; +} + +.readmore_box a:hover { + width:auto; + height:auto; + float:right; + color:#105f8b; + font-size:12px; + font-weight:normal; + text-decoration:underline; + text-align:right; + margin:0 10px 0 0; + padding:0; +} + +#footer { + width:100%; + height:auto; + background:#cdcdcd repeat top left; + margin:25px 0 0 0; + padding:0 0 10px 0; + float:left; +} + +#inside_footer { + width:100%; + height:auto; + background:#cdcdcd repeat top left; + margin:25px 0 0 0; + padding:0; + position:absolute; + bottom:0; +} + + +#footer_mainmaster { + width:960px; + height:auto; + margin:0 auto; + padding:0; +} + +#footer_mainmaster p{ + width:100%; + height:auto; + float:left; + margin:15px 0 0 0; + text-align:left; + font-size:11px; + font-weight:normal; + padding:0; +} + +.footer_linksbox { + width:180px; + height:auto; + float:left; + margin: 15px 20px 20px 0; + padding:0; +} + +.footer_linksbox li { + width:170px; + height:auto; + float:left; + margin: 0 0 5px 0; + border-bottom:1px solid #999; + list-style:none; + padding:0; +} + +.footer_linksbox a:link { + width:auto; + height:auto; + float:left; + font-size:11px; + font-weight:normal; + color:#666; + text-decoration:none; +} + +.footer_linksbox a:visited { + width:auto; + height:auto; + float:left; + font-size:11px; + font-weight:normal; + color:#666; + text-decoration:none; +} + +.footer_linksbox a:hover { + width:auto; + height:auto; + float:left; + font-size:11px; + font-weight:normal; + color:#333; + text-decoration:none; +} + +.inside_leftpanel { + width:212px; + height:auto; + float:left; + margin:0; + padding:0; +} + +.inside_rightpanel { + width:718px; + height:auto; + float:right; + margin:0; + padding:0; +} + +.inside_contentpanel { + width:700px; + height:auto; + float:left; + margin:0 0 0 0; + padding:0; +} + +.inside_contentpanel h1{ + width:700px; + height:auto; + float:left; + color:#199cb4; + font-size:20px; + font-weight:normal; + text-align:left; + margin:0; + padding:0; +} + +.inside_contentpanel h2{ + width:700px; + height:auto; + float:left; + color:#199cb4; + font-size:16px; + font-weight:normal; + text-align:left; + margin:15px 0 0 0; + padding:0; +} + + +.inside_contentpanel h3{ + width:700px; + height:auto; + float:left; + font-size:15px; + font-weight:bold; + text-align:left; + margin:15px 0 0 0; + padding:0; +} + +.inside_contentpanel h4{ + width:700px; + height:auto; + float:left; + font-size:14px; + font-weight:normal; + text-align:left; + margin:15px 0 10px 15px; + padding:0; +} + +.inside_contentpanel p { + width:100%; + height:auto; + float:left; + text-align:justify; + font-size:12px; + font-weight:normal; + margin:10px 0 0 0; + padding:0; +} + +.inside_contentpanel a:link { + width:auto; + height:auto; + color:#009fcd; + text-decoration:none; + text-align:left; + font-size:12px; + margin:0; + padding:0; +} + +.inside_contentpanel a:visited { + width:auto; + height:auto; + color:#009fcd; + text-decoration:none; + text-align:left; + font-size:12px; + margin:0; + padding:0; +} + +.inside_contentpanel a:hover { + width:auto; + height:auto; + color:#009fcd; + text-decoration:underline; + text-align:left; + font-size:12px; + margin:0; + padding:0; +} + +.download_text { + width:600px; + height:auto; + float:left; + color:#7418c2; + text-align:left; + font-weight:normal; + font-size:18px; + margin:20px 0 15px 0 +} + +.download_textbox { + width:720px; + height:auto; + float:left; + color:#333; + text-align:left; + font-weight:normal; + font-size:18px; + margin:20px 0 15px 0; + border-top:1px dashed #999; +} + +.screenshots_box { + width:454px; + height:455px; + float:left; + background:#000 repeat top left; + margin:20px 0 0 65px; + display:inline; +} + +.apiannouncement_box { + width:928px; + height:auto; + float:left; + background:#e0f4ff repeat top left; + margin:15px 0 0 0; + border:1px solid #9dd2eb; +} + +.apiannouncement_contentarea { + width:895px; + height:auto; + float:left; + margin:0 0 0 15px; + display:inline; + padding:0; +} + +.inside_apileftpanel { + width:930px; + height:left; + float:left; + margin:0; + padding:0; +} + +.api_leftsections { + width:928px; + height:auto; + float:left; + border-top:1px dashed #666; + margin:15px 0 0 0; + padding:0; +} + + + +.api_leftsections span { + width:700px; + height:auto; + float:left; + color:#666; + font-size:11px; + font-weight:normal; + text-align:left; + margin:7px 0 0 0; + padding:0; +} + +.api_legends{ + width:300px; + height:auto; + float:left; + background:#f9f9f9; + border:1px solid #e6e6e6; + margin:8px 0 0 0; + padding:0 3px 3px 0; +} + +.api_legends p{ + width:250px; + height:auto; + float:left; + color:#333; + text-align:left; + font-size:11px; + font-weight:normal; + margin:5px 0 0 5px; + padding:0; +} + +.api_legends_async{ + width:auto !important; + height:auto; + color:#2c8bbc !important; + font-size:11px; + font-weight:normal; + text-align:left; + margin:0 3px 0 0 !important; + padding:0; +} + +.api_legends_premium{ + width:auto !important; + height:auto; + color:#013150 !important;; + font-size:11px; + font-weight:normal; + text-align:left; + margin:0 3px 0 0 !important;; + padding:0; +} + +.apismallsections { + width:925px; + height:auto; + float:left; + margin:15px 0 0 0; + list-style:none; + padding:0; +} + +.apismallbullet_box { + width:231px; + height:auto; + float:left; + margin:10px 0 0 0; + list-style:none; + padding:0; +} + +.apismallbullet_box h5 { + width:120px; + height:auto; + float:left; + color:#666; + font-size:12px; + text-align:left; + font-weight:bold; + margin:0; + padding:0 0 10px 0; +} + +.apismallbullet_box h6 { + width:120px; + height:auto; + float:left; + color:#6214ab; + font-size:12px; + text-align:left; + font-weight:bold; + margin:0; + padding:0 0 10px 0; +} + +.apismallbullet_box li { + width:188px; + height:auto; + float:left; + margin:4px 0 0 0; + background:url(../images/api_bullets.gif) no-repeat top left; + padding:0 0 3px 15px; + background-position: 2px 2px; + text-align: left; + list-style:none; + border-bottom:1px dotted #999; +} + +.apismallbullet_box a{ + width:auto; + height:auto; + float:left; + color:#2c8bbc; + font-size:11px !important; + font-weight:normal; + text-align:left; + margin:0; + padding:0; + text-decoration:none; +} + +.apismallbullet_box a:link, .apismallbullet_box a:visited { + text-decoration:none; +} + +.apismallbullet_box a:hover { + text-decoration:underline; +} + +.api_tablepanel { + width:920px; + height:auto; + float:left; + margin:15px 0 0 0; + padding:0; +} + +.api_tablepanel h2{ + width:800px; + height:auto; + float:left; + color:#666; + font-size:14px; + font-weight:bold; + text-align:left; + margin:15px 0 0 0; + padding:0; +} + +.apitable { + width:100%; + height:auto; + float:left; + border:none; + border-collapse:collapse; + margin:10px 0 0 0; + padding:0; +} + +.api_usagebox { + width:700px; + height:auto; + float:left; + background:#f4f5f5; + border:1px solid #CCC; + margin:10px 0 0 30px; + padding:10px; + color:#333; + font-size:11px; + font-weight:normal; + text-align:left; +} + +.api_samplebox { + width:700px; + height:auto; + float:left; + background:#E0F4FF; + border:1px solid #9DD2EB; + margin:10px 0 0 30px; + padding:10px; + color:#333; + font-size:11px; + font-weight:normal; + text-align:left; +} + +.apitable tr { + width:100%; + height:auto; + float:left; + border-collapse:collapse; + border-bottom:1px solid #d5e8f1; + margin:0; + padding:0; +} + +.apitable tr.hed { + width:100%; + height:22px; + float:left; + background:#e7e7e7; + border-collapse:collapse; + border-top:1px solid #999; + border-bottom:1px solid #999; + margin:15px 0 0 0; + padding:0; + border-left:none; + border-right:none; +} + +.apitable td { + height:auto; + float:left; + border:none; + color:#333; + font-size:12px; + font-weight:normal; + border-collapse:collapse; + text-align:left; + padding:5px; + margin:0; +} + + +.apitable td.p{ + height:auto; + float:left; + border:none; + color:#333; + font-size:12px; + font-weight:normal; + text-align:left; + padding:5px; + margin:0; +} + + + +.api_titlebox { + width:100%; + height:auto; + float:left; + margin:0; + padding:0; +} + +.api_titlebox_left { + width:700px; + height:auto; + float:left; + margin:0; + padding:0; +} + +.api_titlebox span{ + width:600px; + height:auto; + float:left; + color:#666; + font-size:11px; + font-weight:normal; + font-style:italic; + text-align:left; + margin:10px 0 0 0; + padding:0; +} + +.api_titlebox_right { + width:200px; + height:20px; + float:right; + margin:0; + padding:0; +} + +a.api_backbutton { + width:60px !important; + height:19px !important; + float:right; + background:#F00 url(../images/back_button.gif) no-repeat top left; + margin:10px 0 0 0 !important; + padding:0; + text-decoration:none; +} + +a:hover.api_backbutton { + background:url(../images/back_button_hover.gif) no-repeat top left; +} diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 4a2624426bf..227054169f8 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -1242,7 +1242,13 @@ public class VirtualMachineMO extends BaseMO { out.close(); // tar files into OVA - if(packToOva) { + if(packToOva) { + // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature) + s_logger.info("Sync file system before we package OVA..."); + + Script commandSync = new Script(true, "sync", 0, s_logger); + commandSync.execute(); + Script command = new Script(false, "tar", 0, s_logger); command.setWorkDir(exportDir); command.add("-cf", exportName + ".ova"); @@ -1250,11 +1256,16 @@ public class VirtualMachineMO extends BaseMO { for(String name: fileNames) { command.add((new File(name).getName())); } - - String result = command.execute(); - if(result == null) { - success = true; - } + + s_logger.info("Package OVA with commmand: " + command.toString()); + command.execute(); + + // to be safe, physically test existence of the target OVA file + if((new File(exportDir + File.separator + exportName + ".ova")).exists()) { + success = true; + } else { + s_logger.error(exportDir + File.separator + exportName + ".ova is not created as expected"); + } } } } catch(Throwable e) { @@ -1268,9 +1279,8 @@ public class VirtualMachineMO extends BaseMO { } } - if(!success) { - new File(exportDir + File.separator + exportName + ".ova").delete(); - } + if(!success) + throw new Exception("Unable to finish the whole process to package as a OVA file"); } } } finally {