diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 00000000000..dfe10cfe3ac
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,60 @@
+This document describes how to set up and configure a single server CloudStack installation so that you can quickly start play around the CloudStack platform. The easiest way is to deploy CloudStack from RPM package, building CloudStack from source is for advanced user. 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
+
+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 Cloud.com 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 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.
+
+
\ No newline at end of file
diff --git a/agent-simulator/.classpath b/agent-simulator/.classpath
index 264339135e1..7ae03655472 100644
--- a/agent-simulator/.classpath
+++ b/agent-simulator/.classpath
@@ -8,17 +8,12 @@
-
-
-
-
-
diff --git a/agent-simulator/scripts/guava/setup.py b/agent-simulator/scripts/guava/setup.py
new file mode 100644
index 00000000000..e8daf82cede
--- /dev/null
+++ b/agent-simulator/scripts/guava/setup.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+
+'''
+############################################################
+# guava uses nfs storage, before setting up make sure
+# * optionally turn off stats collectors
+# * expunge.delay and expunge.interval are 60s
+############################################################
+'''
+
+from optparse import OptionParser
+from configGenerator import *
+import random
+
+
+def getGlobalSettings():
+ global_settings = {'expunge.delay': '60',
+ 'expunge.interval': '60',
+ 'expunge.workers': '3',
+ 'workers': '10',
+ 'use.user.concentrated.pod.allocation': 'true',
+ 'vm.allocation.algorithm': 'random',
+ 'vm.op.wait.interval': '5',
+ 'guest.domain.suffix': 'guava.simulator',
+ 'instance.name': 'TEST',
+ 'direct.agent.load.size': '1000',
+ 'default.page.size': '10000',
+ 'linkLocalIp.nums': '10',
+ 'check.pod.cidrs': 'false',
+ }
+ for k, v in global_settings.iteritems():
+ cfg = configuration()
+ cfg.name = k
+ cfg.value = v
+ yield cfg
+
+
+def describeGuavaResources(dbnode='localhost', mshost='localhost'):
+ zs = cloudstackConfiguration()
+ numberofpods = 1
+
+ clustersPerPod = 100
+ hostsPerCluster = 10
+
+ z = zone()
+ z.dns1 = '4.2.2.2'
+ z.dns2 = '192.168.110.254'
+ z.internaldns1 = '10.91.28.6'
+ z.internaldns2 = '192.168.110.254'
+ z.name = 'Guava'
+ z.networktype = 'Advanced'
+ z.guestcidraddress = '10.1.1.0/24'
+ z.vlan='100-3000'
+
+ p = pod()
+ p.name = 'POD1'
+ p.gateway = '172.1.2.1'
+ p.startip = '172.1.2.2'
+ p.endip = '172.1.255.252'
+ p.netmask = '255.255.0.0'
+
+ v = iprange()
+ v.vlan = 'untagged'
+ v.startip = '172.2.1.2'
+ v.endip = '172.2.255.252'
+ v.gateway = '172.2.1.1'
+ v.netmask = '255.255.0.0'
+
+ curhost = 1
+ for i in range(1, clustersPerPod + 1):
+ c = cluster()
+ c.clustername = 'POD1-CLUSTER' + str(i)
+ c.hypervisor = 'Simulator'
+ c.clustertype = 'CloudManaged'
+
+ for j in range(1, hostsPerCluster + 1):
+ h = host()
+ h.username = 'root'
+ h.password = 'password'
+ h.url = 'http://sim/test-%d'%(curhost)
+ c.hosts.append(h)
+ curhost = curhost + 1
+
+ ps = primaryStorage()
+ ps.name = 'spool'+str(i)
+ ps.url = 'nfs://172.16.24.32/export/path/'+str(i)
+ c.primaryStorages.append(ps)
+ p.clusters.append(c)
+
+
+ secondary = secondaryStorage()
+ secondary.url = 'nfs://172.16.25.32/secondary/path'
+
+ z.pods.append(p)
+ z.ipranges.append(v)
+ z.secondaryStorages.append(secondary)
+ zs.zones.append(z)
+
+ '''Add mgt server'''
+ mgt = managementServer()
+ mgt.mgtSvrIp = mshost
+ zs.mgtSvr.append(mgt)
+
+ '''Add a database'''
+ db = dbServer()
+ db.dbSvr = opts.dbnode
+ zs.dbSvr = db
+
+ '''Add some configuration'''
+ [zs.globalConfig.append(cfg) for cfg in getGlobalSettings()]
+
+ ''''add loggers'''
+ testClientLogger = logger()
+ testClientLogger.name = 'TestClient'
+ testClientLogger.file = '/var/log/testclient.log'
+
+ testCaseLogger = logger()
+ testCaseLogger.name = 'TestCase'
+ testCaseLogger.file = '/var/log/testcase.log'
+
+ zs.logger.append(testClientLogger)
+ zs.logger.append(testCaseLogger)
+ return zs
+
+
+if __name__ == '__main__':
+ parser = OptionParser()
+ parser.add_option('-o', '--output', action='store', default='./guavaCfg', dest='output', help='the path where the json config file generated')
+ parser.add_option('-d', '--dbnode', dest='dbnode', help='hostname/ip of the database node', action='store')
+ parser.add_option('-m', '--mshost', dest='mshost', help='hostname/ip of management server', action='store')
+
+ (opts, args) = parser.parse_args()
+ cfg = describeGuavaResources(opts.dbnode, opts.mshost)
+ generate_setup_config(cfg, opts.output)
diff --git a/agent-simulator/scripts/guava/tests/testProvision.py b/agent-simulator/scripts/guava/tests/testProvision.py
new file mode 100644
index 00000000000..99c39d9c18d
--- /dev/null
+++ b/agent-simulator/scripts/guava/tests/testProvision.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+import random
+import hashlib
+from cloudstackTestCase import *
+
+class Provision(cloudstackTestCase):
+ '''
+ '''
+ def setUp(self):
+ pass
+
+
+ def tearDown(self):
+ pass
+
+
+ def test_createAccounts(self, numberOfAccounts=5):
+ '''
+ 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 deployCmd(self, account):
+ deployVmCmd = deployVirtualMachine.deployVirtualMachineCmd()
+ deployVmCmd.zoneid = 1
+ deployVmCmd.hypervisor='Simulator'
+ deployVmCmd.account=account
+ deployVmCmd.domainid=1
+ deployVmCmd.templateid=10
+ deployVmCmd.serviceofferingid=7
+ 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)
+ self.debug(listVmResponse)
+ return listVmResponse
+
+
+ def destroyVmCmd(self, key):
+ api = self.testClient.getApiClient()
+ destroyVmCmd = destroyVirtualMachine.destroyVirtualMachineCmd()
+ destroyVmCmd.id = key
+ api.destroyVirtualMachine(destroyVmCmd)
+
+
+ def test_stressDeploy(self):
+ '''
+ Deploy 20 Vms in each account
+ '''
+ api = self.testClient.getApiClient()
+ for acct in range(1, 5):
+ [api.deployVirtualMachine(self.deployCmd('user'+str(acct))) for x in range(0,20)]
+
+ def test_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)):
+ self.destroyVmCmd(vm.id)
+
+ def test_combineStress(self):
+ for i in range(0, 5):
+ self.test_stressDestroy()
+ self.test_stressDeploy()
+
+ 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/agent-simulator/scripts/kumquat/setup.py b/agent-simulator/scripts/kumquat/setup.py
new file mode 100644
index 00000000000..035c70865a6
--- /dev/null
+++ b/agent-simulator/scripts/kumquat/setup.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python
+
+'''
+############################################################
+# Kumquat uses nfs storage, before setting up make sure
+# * optionally turn off stats collectors
+# * expunge.delay and expunge.interval are 60s
+############################################################
+'''
+
+from optparse import OptionParser
+from configGenerator import *
+import random
+
+
+def getGlobalSettings():
+ global_settings = {'expunge.delay': '60',
+ 'expunge.interval': '60',
+ 'capacity.skipcounting.hours': '2',
+ 'cpu.overprovisioning.factor': '1.5',
+ 'expunge.workers': '3',
+ 'workers': '10',
+ 'use.user.concentrated.pod.allocation': 'true',
+ 'vm.allocation.algorithm': 'random',
+ 'vm.op.wait.interval': '5',
+ 'guest.domain.suffix': 'kumquat.simulator',
+ 'instance.name': 'KIM',
+ 'direct.agent.load.size': '16',
+ 'default.page.size': '500',
+ 'linkLocalIp.nums': '10',
+ 'check.pod.cidrs': 'false',
+ 'max.account.public.ips': '10000',
+ 'max.account.snapshots': '10000',
+ 'max.account.templates': '10000',
+ 'max.account.user.vms': '10000',
+ 'max.account.volumes': '10000',
+ }
+ for k, v in global_settings.iteritems():
+ cfg = configuration()
+ cfg.name = k
+ cfg.value = v
+ yield cfg
+
+
+def podIpRangeGenerator():
+ x=1
+ y=2
+ while 1:
+ if y == 255:
+ x=x+1
+ if x == 255:
+ x=1
+ break
+
+ y=1
+
+ y=y+1
+ #pod mangement network
+ yield ('172.'+str(x)+'.'+str(y)+'.129', '172.'+str(x)+'.'+str(y)+'.130', '172.'+str(x)+'.'+str(y)+'.189')
+
+
+def vlanIpRangeGenerator():
+ x=1
+ y=2
+ while 1:
+ if y == 255:
+ x=x+1
+ if x==255:
+ x=1
+ break
+
+ y=1
+
+ y=y+1
+ #vlan ip range
+ yield ('172.'+str(x)+'.'+str(y)+'.129', '172.'+str(x)+'.'+str(y)+'.190', '172.'+str(x)+'.'+str(y)+'.249')
+
+
+def describeKumquatResources(dbnode='localhost', mshost='localhost'):
+ zs = cloudstackConfiguration()
+ numberofpods = 15
+
+ clustersPerPod = 2
+ hostsPerCluster = 8
+
+ curpod = 0
+ curhost = 0
+
+ z = zone()
+ z.dns1 = '4.2.2.2'
+ z.dns2 = '192.168.110.254'
+ z.internaldns1 = '10.91.28.6'
+ z.internaldns2 = '192.168.110.254'
+ z.name = 'Kumquat'
+ z.networktype = 'Advanced'
+ z.guestcidraddress = '10.1.1.0/24'
+ z.vlan='100-3000'
+
+ for podRange,vlanRange in zip(podIpRangeGenerator(), vlanIpRangeGenerator()):
+ p = pod()
+ curpod=curpod+1
+ p.name = 'POD'+str(curpod)
+ p.gateway=podRange[0]
+ p.startip=podRange[1]
+ p.endip=podRange[2]
+ p.netmask='255.255.255.128'
+
+ for i in range(1,clustersPerPod+1):
+ c = cluster()
+ c.clustername = 'POD'+str(curpod)+'-CLUSTER'+str(i)
+ c.hypervisor = 'Simulator'
+ c.clustertype = 'CloudManaged'
+
+ ps = primaryStorage()
+ ps.name = 'spool'+str(i)
+ ps.url = 'nfs://172.16.24.32/export/path/'+str(curpod)+'/'+str(i)
+ c.primaryStorages.append(ps)
+
+ for i in range(1, hostsPerCluster + 1):
+ h = host()
+ h.username = 'root'
+ h.password = 'password'
+ h.url = "http://sim/test-%d"%(curhost)
+ c.hosts.append(h)
+ curhost=curhost+1
+
+ p.clusters.append(c)
+
+ z.pods.append(p)
+ if curpod == numberofpods:
+ break
+
+ v = iprange()
+ v.vlan = 'untagged'
+ v.gateway='172.2.1.1'
+ v.startip='172.2.1.2'
+ v.endip='172.2.255.252'
+ v.netmask="255.255.0.0"
+ z.ipranges.append(v)
+
+ secondary = secondaryStorage()
+ secondary.url = 'nfs://172.16.25.32/secondary/path'
+ z.secondaryStorages.append(secondary)
+ zs.zones.append(z)
+
+ '''Add mgt server'''
+ mgt = managementServer()
+ mgt.mgtSvrIp = mshost
+ zs.mgtSvr.append(mgt)
+
+ '''Add a database'''
+ db = dbServer()
+ db.dbSvr = opts.dbnode
+ zs.dbSvr = db
+
+ '''Add some configuration'''
+ [zs.globalConfig.append(cfg) for cfg in getGlobalSettings()]
+
+ ''''add loggers'''
+ testClientLogger = logger()
+ testClientLogger.name = 'TestClient'
+ testClientLogger.file = '/var/log/testclient.log'
+
+ testCaseLogger = logger()
+ testCaseLogger.name = 'TestCase'
+ testCaseLogger.file = '/var/log/testcase.log'
+
+ zs.logger.append(testClientLogger)
+ zs.logger.append(testCaseLogger)
+ return zs
+
+
+if __name__ == '__main__':
+ parser = OptionParser()
+ parser.add_option('-o', '--output', action='store', default='./KumquatCfg', dest='output', help='the path where the json config file generated')
+ parser.add_option('-d', '--dbnode', dest='dbnode', help='hostname/ip of the database node', action='store')
+ parser.add_option('-m', '--mshost', dest='mshost', help='hostname/ip of management server', action='store')
+
+ (opts, args) = parser.parse_args()
+ cfg = describeKumquatResources(opts.dbnode, opts.mshost)
+ generate_setup_config(cfg, opts.output)
diff --git a/agent-simulator/scripts/kumquat/tests/testProvision.py b/agent-simulator/scripts/kumquat/tests/testProvision.py
new file mode 100644
index 00000000000..253ef34becd
--- /dev/null
+++ b/agent-simulator/scripts/kumquat/tests/testProvision.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+import random
+import hashlib
+from cloudstackTestCase import *
+
+class Provision(cloudstackTestCase):
+ '''
+ '''
+
+ so = '10' #default
+
+ def setUp(self):
+ pass
+
+
+ def tearDown(self):
+ pass
+
+ @unittest.skip("already done")
+ def test_createAccounts(self, numberOfAccounts=850):
+ '''
+ 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(acctResponse)
+
+
+ def test_setupServiceOffering(self):
+ socreate = createServiceOffering.createServiceOfferingCmd()
+ socreate.cpunumber = 1
+ socreate.cpuspeed = 100
+ socreate.displaytext = 'Sample SO'
+ socreate.memory = 128
+ socreate.name = 'Sample SO'
+ api = self.testClient.getApiClient()
+ soresponse = api.createServiceOffering(socreate)
+ self.so = soresponse.id
+
+ def deployCmd(self, acct):
+ deployVmCmd = deployVirtualMachine.deployVirtualMachineCmd()
+ deployVmCmd.zoneid = 1
+ deployVmCmd.hypervisor='Simulator'
+ deployVmCmd.account=acct
+ deployVmCmd.domainid=1
+ deployVmCmd.templateid=2
+ deployVmCmd.serviceofferingid=self.so
+ return deployVmCmd
+
+
+ def test_stressDeploy(self):
+ '''
+ Deploy 5 Vms in each account
+ '''
+ api = self.testClient.getApiClient()
+ for acct in range(122, 850):
+ [api.deployVirtualMachine(self.deployCmd('user'+str(acct))) for x in range(0, 5)]
+
+
+ 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/agent-simulator/scripts/zucchini/setup.py b/agent-simulator/scripts/zucchini/setup.py
index e69207f937a..65d48cec39e 100644
--- a/agent-simulator/scripts/zucchini/setup.py
+++ b/agent-simulator/scripts/zucchini/setup.py
@@ -44,18 +44,18 @@ def getGlobalSettings():
'use.user.concentrated.pod.allocation':'false',
'vm.allocation.algorithm':'firstfit',
'capacity.check.period':'0',
- 'host.stats.interval':'-1',
- 'vm.stats.interval':'-1',
- 'storage.stats.interval':'-1',
- 'router.stats.interval':'-1',
+# 'host.stats.interval':'-1',
+# 'vm.stats.interval':'-1',
+# 'storage.stats.interval':'-1',
+# 'router.stats.interval':'-1',
'vm.op.wait.interval':'5',
'xen.public.network.device':'10.10.10.10', #only a dummy for the simulator
- 'guest.domain.suffix':'zcloud.simulator',
+ 'guest.domain.suffix':'zucchini.simulator',
'instance.name':'ZIM',
'direct.agent.load.size':'1000',
'default.page.size':'10000',
'linkLocalIp.nums':'4',
- 'systemvm.use.local.storage':'true',
+ 'system.vm.use.local.storage':'true',
'use.local.storage':'true',
'check.pod.cidrs':'false',
}
@@ -201,7 +201,8 @@ if __name__=="__main__":
(opts, args) = parser.parse_args()
mandatories = ['mshost', 'dbnode', 'agents']
for m in mandatories:
- if not opts.__dict__[m]:
- print "mandatory option missing"
- cfg = describeZucchiniResources(int(opts.agents), opts.dbnode, opts.mshost, opts.randomize)
- generate_setup_config(cfg, opts.output)
+ if not opts.__dict__[m]:
+ print "mandatory option missing"
+
+ cfg = describeZucchiniResources(int(opts.agents), opts.dbnode, opts.mshost, opts.randomize)
+ generate_setup_config(cfg, opts.output)
diff --git a/agent-simulator/scripts/zucchini/tests/testListVm.py b/agent-simulator/scripts/zucchini/tests/testListVm.py
new file mode 100644
index 00000000000..12fdb869eb6
--- /dev/null
+++ b/agent-simulator/scripts/zucchini/tests/testListVm.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+'''
+List Virtual Machine tests
+'''
+try:
+ import unittest2 as unittest
+except ImportError:
+ import unittest
+
+import timeit
+import random
+from cloudstackAPI import *
+from cloudstackTestCase import *
+
+class ListVmTests(cloudstackTestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_listAllVm(self):
+ numVms = 0
+ def time_listAllVm():
+ api = self.testClient.getApiClient()
+ listVmCmd = listVirtualMachines.listVirtualMachinesCmd()
+ listVmCmd.account = 'admin'
+ listVmCmd.zoneid = 1
+ listVmCmd.domainid = 1
+ numVms = len(api.listVirtualMachines(listVmCmd))
+
+ t = timeit.Timer(time_listAllVm)
+ l = t.repeat(5, 5)
+ self.debug("Number of VMs: " + str(len(numVms)) + ", time for last 5 listVM calls : " + str(l))
diff --git a/agent/.classpath b/agent/.classpath
index a533b6c64e4..536dd38714f 100644
--- a/agent/.classpath
+++ b/agent/.classpath
@@ -3,10 +3,10 @@
+
-
diff --git a/agent/.project b/agent/.project
index 8b1ee7d35a6..166ff6cc1f3 100644
--- a/agent/.project
+++ b/agent/.project
@@ -5,6 +5,11 @@
+
+ org.python.pydev.PyDevBuilder
+
+
+
org.eclipse.jdt.core.javabuilder
@@ -13,5 +18,6 @@
org.eclipse.jdt.core.javanature
+ org.python.pydev.pythonNature
diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java
index 6229e184b0a..d4eb27762a1 100644
--- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java
+++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java
@@ -39,6 +39,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
@@ -386,6 +387,31 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected String getDefaultStorageScriptsDir() {
return "scripts/storage/qcow2";
}
+
+ private void saveProperties(Map params) throws ConfigurationException {
+ final File file = PropertiesUtil.findConfigFile("agent.properties");
+ if (file == null) {
+ throw new ConfigurationException("Unable to find agent.properties.");
+ }
+
+ s_logger.info("agent.properties found at " + file.getAbsolutePath());
+
+ try {
+ Properties _properties = new Properties();
+ _properties.load(new FileInputStream(file));
+ Set names = _properties.stringPropertyNames();
+ for (String key : params.keySet()) {
+ if (!names.contains(key)) {
+ _properties.setProperty(key, (String)params.get(key));
+ }
+ }
+ _properties.store(new FileOutputStream(file), "");
+ } catch (final FileNotFoundException ex) {
+ throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
+ } catch (final IOException ex) {
+ throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
+ }
+ }
@Override
public boolean configure(String name, Map params)
@@ -560,8 +586,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
-
-
_localStoragePath = (String)params.get("local.storage.path");
if (_localStoragePath == null) {
_localStoragePath = "/var/lib/libvirt/images/";
@@ -569,7 +593,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
_localStorageUUID = (String)params.get("local.storage.uuid");
if (_localStorageUUID == null) {
- throw new ConfigurationException("Can't find local.storage.uuid");
+ _localStorageUUID = UUID.randomUUID().toString();
+ params.put("local.storage.uuid", _localStorageUUID);
}
value = (String)params.get("scripts.timeout");
@@ -663,6 +688,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
_storageResource = new LibvirtStorageResource(this, _storage, _createvmPath, _timeout, _mountPoint, _monitor);
+ saveProperties(params);
return true;
}
@@ -903,7 +929,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
} else if (cmd instanceof CopyVolumeCommand) {
return execute((CopyVolumeCommand)cmd);
} else {
- s_logger.warn("Unsupported command ");
+ s_logger.warn("Unsupported command :"+cmd.toString());
return Answer.createUnsupportedCommandAnswer(cmd);
}
} catch (final IllegalArgumentException e) {
@@ -1596,7 +1622,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.stringifyRules(), vif, brname);
if (!result) {
- s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
+ s_logger.warn("Failed to program Ingress network rules for vm " + cmd.getVmName());
return new SecurityIngressRuleAnswer(cmd, false, "programming network rules failed");
} else {
s_logger.debug("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length);
@@ -1624,7 +1650,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.stringifyRules(), vif, brname);
if (!result) {
- s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
+ s_logger.warn("Failed to program Egress network rules for vm " + cmd.getVmName());
return new SecurityEgressRuleAnswer(cmd, false, "programming network rules failed");
} else {
s_logger.debug("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length);
@@ -3490,7 +3516,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.add("--vmid", vmId);
cmd.add("--vmip", guestIP);
/* type of the rule : ingress or egress */
- cmd.add("--type", type);
+ cmd.add("--ruletype", type);
cmd.add("--sig", sig);
cmd.add("--seq", seq);
cmd.add("--vmmac", mac);
diff --git a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java
index afff7368c70..3d3591f628c 100644
--- a/api/src/com/cloud/agent/api/BackupSnapshotCommand.java
+++ b/api/src/com/cloud/agent/api/BackupSnapshotCommand.java
@@ -64,7 +64,8 @@ public class BackupSnapshotCommand extends SnapshotCommand {
String prevSnapshotUuid,
String prevBackupUuid,
boolean isVolumeInactive,
- String vmName)
+ String vmName,
+ int wait)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, snapshotUuid, snapshotName, dcId, accountId, volumeId);
this.snapshotId = snapshotId;
@@ -74,6 +75,7 @@ public class BackupSnapshotCommand extends SnapshotCommand {
this.vmName = vmName;
this.pool = new StorageFilerTO(pool);
setVolumePath(volumePath);
+ setWait(wait);
}
public String getPrevSnapshotUuid() {
diff --git a/api/src/com/cloud/agent/api/CheckHealthCommand.java b/api/src/com/cloud/agent/api/CheckHealthCommand.java
index f78d7cb49aa..937775e603f 100644
--- a/api/src/com/cloud/agent/api/CheckHealthCommand.java
+++ b/api/src/com/cloud/agent/api/CheckHealthCommand.java
@@ -20,8 +20,11 @@ package com.cloud.agent.api;
public class CheckHealthCommand extends Command {
- public CheckHealthCommand() {}
-
+ public CheckHealthCommand() {
+ setWait(50);
+ }
+
+
@Override
public boolean executeInSequence() {
return false;
diff --git a/api/src/com/cloud/agent/api/CheckOnHostCommand.java b/api/src/com/cloud/agent/api/CheckOnHostCommand.java
index 2bbb564acd4..5bb5d2a203d 100644
--- a/api/src/com/cloud/agent/api/CheckOnHostCommand.java
+++ b/api/src/com/cloud/agent/api/CheckOnHostCommand.java
@@ -29,6 +29,7 @@ public class CheckOnHostCommand extends Command {
public CheckOnHostCommand(Host host) {
this.host = new HostTO(host);
+ setWait(20);
}
public HostTO getHost() {
diff --git a/api/src/com/cloud/agent/api/CheckVirtualMachineCommand.java b/api/src/com/cloud/agent/api/CheckVirtualMachineCommand.java
index 3eea2979b4b..346328cc69f 100644
--- a/api/src/com/cloud/agent/api/CheckVirtualMachineCommand.java
+++ b/api/src/com/cloud/agent/api/CheckVirtualMachineCommand.java
@@ -27,6 +27,7 @@ public class CheckVirtualMachineCommand extends Command {
public CheckVirtualMachineCommand(String vmName) {
this.vmName = vmName;
+ setWait(20);
}
public String getVmName() {
diff --git a/api/src/com/cloud/agent/api/Command.java b/api/src/com/cloud/agent/api/Command.java
index 120ed6c7cb6..2263d90fd39 100755
--- a/api/src/com/cloud/agent/api/Command.java
+++ b/api/src/com/cloud/agent/api/Command.java
@@ -28,13 +28,23 @@ import com.cloud.agent.api.LogLevel.Log4jLevel;
* all of the methods that needs to be implemented by the children classes.
*
*/
-public abstract class Command {
+public abstract class Command {
// allow command to carry over hypervisor or other environment related context info
@LogLevel(Log4jLevel.Trace)
protected Map contextMap = new HashMap();
+ private int wait; //in second
protected Command() {
+ this.wait = 0;
+ }
+
+ public int getWait() {
+ return wait;
+ }
+
+ public void setWait(int wait) {
+ this.wait = wait;
}
@Override
diff --git a/api/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java b/api/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
index 13581099af9..eb3cf8dcae0 100644
--- a/api/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
+++ b/api/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java
@@ -52,12 +52,14 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand {
String backedUpSnapshotName,
String origTemplateInstallPath,
Long newTemplateId,
- String templateName)
+ String templateName,
+ int wait)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
this.origTemplateInstallPath = origTemplateInstallPath;
this.newTemplateId = newTemplateId;
this.templateName = templateName;
+ setWait(wait);
}
/**
diff --git a/api/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java b/api/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
index 60f34e285b6..20e26607bbf 100644
--- a/api/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
+++ b/api/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java
@@ -31,14 +31,15 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand {
public CreatePrivateTemplateFromVolumeCommand() {}
- public CreatePrivateTemplateFromVolumeCommand(String secondaryStorageURL, long templateId, long accountId, String userSpecifiedName, String uniqueName, String volumePath, String vmName) {
+ public CreatePrivateTemplateFromVolumeCommand(String secondaryStorageURL, long templateId, long accountId, String userSpecifiedName, String uniqueName, String volumePath, String vmName, int wait) {
_secondaryStorageURL = secondaryStorageURL;
_templateId = templateId;
_accountId = accountId;
_userSpecifiedName = userSpecifiedName;
_uniqueName = uniqueName;
_volumePath = volumePath;
- _vmName = vmName;
+ _vmName = vmName;
+ setWait(wait);
}
@Override
diff --git a/api/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java b/api/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
index b6a2197d8d1..a9c81486f2a 100644
--- a/api/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
+++ b/api/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java
@@ -50,9 +50,10 @@ public class CreateVolumeFromSnapshotCommand extends SnapshotCommand {
Long accountId,
Long volumeId,
String backedUpSnapshotUuid,
- String backedUpSnapshotName)
+ String backedUpSnapshotName,
+ int wait)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId);
+ setWait(wait);
}
-
}
\ No newline at end of file
diff --git a/api/src/com/cloud/agent/api/NetworkUsageAnswer.java b/api/src/com/cloud/agent/api/NetworkUsageAnswer.java
index 6138f7a1314..973bef08946 100644
--- a/api/src/com/cloud/agent/api/NetworkUsageAnswer.java
+++ b/api/src/com/cloud/agent/api/NetworkUsageAnswer.java
@@ -19,9 +19,10 @@ package com.cloud.agent.api;
import com.cloud.agent.api.LogLevel.Log4jLevel;
-@LogLevel(Log4jLevel.Trace)
+@LogLevel(Log4jLevel.Debug)
public class NetworkUsageAnswer extends Answer {
- Long bytesSent;
+ String routerName;
+ Long bytesSent;
Long bytesReceived;
protected NetworkUsageAnswer() {
@@ -31,6 +32,7 @@ public class NetworkUsageAnswer extends Answer {
super(cmd, true, details);
this.bytesReceived = bytesReceived;
this.bytesSent = bytesSent;
+ routerName = cmd.getDomRName();
}
@@ -49,4 +51,8 @@ public class NetworkUsageAnswer extends Answer {
public Long getBytesSent() {
return bytesSent;
}
+
+ public String getRouterName() {
+ return routerName;
+ }
}
diff --git a/api/src/com/cloud/agent/api/PingTestCommand.java b/api/src/com/cloud/agent/api/PingTestCommand.java
index 98970315b07..308f47700fc 100644
--- a/api/src/com/cloud/agent/api/PingTestCommand.java
+++ b/api/src/com/cloud/agent/api/PingTestCommand.java
@@ -27,12 +27,14 @@ public class PingTestCommand extends Command {
public PingTestCommand() {}
public PingTestCommand(String computingHostIp) {
- _computingHostIp = computingHostIp;
+ _computingHostIp = computingHostIp;
+ setWait(20);
}
public PingTestCommand(String routerIp, String privateIp) {
_routerIp = routerIp;
- _privateIp = privateIp;
+ _privateIp = privateIp;
+ setWait(20);
}
public String getComputingHostIp() {
diff --git a/api/src/com/cloud/agent/api/StartupRoutingCommand.java b/api/src/com/cloud/agent/api/StartupRoutingCommand.java
index 616b5c7f10f..baecda31bef 100755
--- a/api/src/com/cloud/agent/api/StartupRoutingCommand.java
+++ b/api/src/com/cloud/agent/api/StartupRoutingCommand.java
@@ -52,6 +52,7 @@ public class StartupRoutingCommand extends StartupCommand {
String pool;
HypervisorType hypervisorType;
Map hostDetails; //stuff like host os, cpu capabilities
+ String hypervisorVersion;
public StartupRoutingCommand() {
super(Host.Type.Routing);
@@ -59,7 +60,7 @@ public class StartupRoutingCommand extends StartupCommand {
getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), RouterPrivateIpStrategy.DcGlobal.toString());
}
-
+
public StartupRoutingCommand(int cpus,
long speed,
long memory,
@@ -71,7 +72,7 @@ public class StartupRoutingCommand extends StartupCommand {
this(cpus, speed, memory, dom0MinMemory, caps, hypervisorType, vms);
getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStrategy.toString());
}
-
+
public StartupRoutingCommand(int cpus,
long speed,
long memory,
@@ -82,50 +83,55 @@ public class StartupRoutingCommand extends StartupCommand {
this(cpus, speed, memory, dom0MinMemory, caps, hypervisorType, new HashMap(), new HashMap());
getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStrategy.toString());
}
-
+
public StartupRoutingCommand(int cpus,
- long speed,
- long memory,
- long dom0MinMemory,
- final String caps,
- final HypervisorType hypervisorType,
- final Map hostDetails,
- Map vms) {
- super(Host.Type.Routing);
- this.cpus = cpus;
- this.speed = speed;
- this.memory = memory;
- this.dom0MinMemory = dom0MinMemory;
- this.vms = vms;
- this.hypervisorType = hypervisorType;
- this.hostDetails = hostDetails;
- this.caps = caps;
- this.poolSync = false;
+ long speed,
+ long memory,
+ long dom0MinMemory,
+ final String caps,
+ final HypervisorType hypervisorType,
+ final Map hostDetails,
+ Map vms) {
+ super(Host.Type.Routing);
+ this.cpus = cpus;
+ this.speed = speed;
+ this.memory = memory;
+ this.dom0MinMemory = dom0MinMemory;
+ this.vms = vms;
+ this.hypervisorType = hypervisorType;
+ this.hostDetails = hostDetails;
+ this.caps = caps;
+ this.poolSync = false;
}
-
+
public StartupRoutingCommand(int cpus2, long speed2, long memory2,
- long dom0MinMemory2, String caps2, HypervisorType hypervisorType2,
- Map vms2) {
- this(cpus2, speed2, memory2, dom0MinMemory2, caps2, hypervisorType2, new HashMap(), vms2);
- }
-
- public void setChanges(Map vms) {
+ long dom0MinMemory2, String caps2, HypervisorType hypervisorType2,
+ Map vms2) {
+ this(cpus2, speed2, memory2, dom0MinMemory2, caps2, hypervisorType2, new HashMap(), vms2);
+ }
+
+ public StartupRoutingCommand(int cpus, long speed, long memory, long dom0MinMemory, final String caps, final HypervisorType hypervisorType, final Map hostDetails, Map vms, String hypervisorVersion) {
+ this(cpus, speed, memory, dom0MinMemory, caps, hypervisorType, hostDetails, vms);
+ this.hypervisorVersion = hypervisorVersion;
+ }
+
+ public void setChanges(Map vms) {
this.vms = vms;
}
-
- public void setStateChanges(Map vms) {
- for( String vm_name : vms.keySet() ) {
- if( this.vms == null ) {
- this.vms = new HashMap();
- }
- this.vms.put(vm_name, new VmState(vms.get(vm_name), null));
- }
- }
+
+ public void setStateChanges(Map vms) {
+ for( String vm_name : vms.keySet() ) {
+ if( this.vms == null ) {
+ this.vms = new HashMap();
+ }
+ this.vms.put(vm_name, new VmState(vms.get(vm_name), null));
+ }
+ }
public int getCpus() {
return cpus;
}
-
+
public String getCapabilities() {
return caps;
}
@@ -145,36 +151,36 @@ getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStr
public Map getVmStates() {
return vms;
}
-
+
public void setSpeed(long speed) {
this.speed = speed;
}
-
+
public void setCpus(int cpus) {
this.cpus = cpus;
}
-
+
public void setMemory(long memory) {
this.memory = memory;
}
-
+
public void setDom0MinMemory(long dom0MinMemory) {
this.dom0MinMemory = dom0MinMemory;
}
-
+
public void setCaps(String caps) {
this.caps = caps;
}
-
+
public String getPool() {
- return pool;
- }
-
- public void setPool(String pool) {
- this.pool = pool;
+ return pool;
}
- public boolean isPoolSync() {
+ public void setPool(String pool) {
+ this.pool = pool;
+ }
+
+ public boolean isPoolSync() {
return poolSync;
}
@@ -183,19 +189,27 @@ getHostDetails().put(RouterPrivateIpStrategy.class.getCanonicalName(), privIpStr
}
public HypervisorType getHypervisorType() {
- return hypervisorType;
- }
+ return hypervisorType;
+ }
- public void setHypervisorType(HypervisorType hypervisorType) {
- this.hypervisorType = hypervisorType;
- }
+ public void setHypervisorType(HypervisorType hypervisorType) {
+ this.hypervisorType = hypervisorType;
+ }
- public Map getHostDetails() {
- return hostDetails;
- }
+ public Map getHostDetails() {
+ return hostDetails;
+ }
- public void setHostDetails(Map hostDetails) {
- this.hostDetails = hostDetails;
- }
+ public void setHostDetails(Map hostDetails) {
+ this.hostDetails = hostDetails;
+ }
+
+ public String getHypervisorVersion() {
+ return hypervisorVersion;
+ }
+
+ public void setHypervisorVersion(String hypervisorVersion) {
+ this.hypervisorVersion = hypervisorVersion;
+ }
}
diff --git a/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java
index 3e367230795..cbe5ff03d11 100644
--- a/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java
+++ b/api/src/com/cloud/agent/api/storage/CopyVolumeCommand.java
@@ -34,15 +34,16 @@ public class CopyVolumeCommand extends Command {
public CopyVolumeCommand() {
}
- public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage) {
+ public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait) {
this.volumeId = volumeId;
this.volumePath = volumePath;
this.pool = new StorageFilerTO(pool);
this.secondaryStorageURL = secondaryStorageURL;
this.toSecondaryStorage = toSecondaryStorage;
+ setWait(wait);
}
- @Override
+ @Override
public boolean executeInSequence() {
return true;
}
diff --git a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
index 4f514a249a6..58de20e196d 100644
--- a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
+++ b/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java
@@ -32,15 +32,16 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand {
String secondaryStorageUrl;
String primaryStorageUrl;
- protected PrimaryStorageDownloadCommand() {
+ protected PrimaryStorageDownloadCommand() {
}
- public PrimaryStorageDownloadCommand(String name, String url, ImageFormat format, long accountId, long poolId, String poolUuid) {
+ public PrimaryStorageDownloadCommand(String name, String url, ImageFormat format, long accountId, long poolId, String poolUuid, int wait) {
super(name, url, format, accountId);
this.poolId = poolId;
this.poolUuid = poolUuid;
+ setWait(wait);
}
-
+
public String getPoolUuid() {
return poolUuid;
}
diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java
index c57da2e5851..f8705536314 100755
--- a/api/src/com/cloud/api/ApiConstants.java
+++ b/api/src/com/cloud/api/ApiConstants.java
@@ -257,4 +257,7 @@ public class ApiConstants {
public static final String KEYBOARD="keyboard";
public static final String OPEN_FIREWALL="openfirewall";
public static final String TEMPLATE_TAG = "templatetag";
+ public static final String HYPERVISOR_VERSION = "hypervisorversion";
+ public static final String MAX_GUESTS_LIMIT = "maxguestslimit";
+
}
diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java
index 51ed0e9b55b..37ec55bb2c3 100755
--- a/api/src/com/cloud/api/ResponseGenerator.java
+++ b/api/src/com/cloud/api/ResponseGenerator.java
@@ -35,6 +35,7 @@ import com.cloud.api.response.ExtractResponse;
import com.cloud.api.response.FirewallResponse;
import com.cloud.api.response.FirewallRuleResponse;
import com.cloud.api.response.HostResponse;
+import com.cloud.api.response.HypervisorCapabilitiesResponse;
import com.cloud.api.response.IPAddressResponse;
import com.cloud.api.response.InstanceGroupResponse;
import com.cloud.api.response.IpForwardingRuleResponse;
@@ -72,6 +73,7 @@ import com.cloud.dc.Vlan;
import com.cloud.domain.Domain;
import com.cloud.event.Event;
import com.cloud.host.Host;
+import com.cloud.hypervisor.HypervisorCapabilities;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.RemoteAccessVpn;
@@ -81,8 +83,8 @@ import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.LoadBalancer;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.StaticNatRule;
-import com.cloud.network.security.IngressRule;
import com.cloud.network.security.EgressRule;
+import com.cloud.network.security.IngressRule;
import com.cloud.network.security.SecurityGroup;
import com.cloud.network.security.SecurityGroupRules;
import com.cloud.offering.DiskOffering;
@@ -162,20 +164,20 @@ public interface ResponseGenerator {
Account findAccountByNameDomain(String accountName, Long domainId);
VirtualMachineTemplate findTemplateById(Long templateId);
-
+
Host findHostById(Long hostId);
-
+
List createTemplateResponses(long templateId, long zoneId, boolean readyOnly);
-
+
VpnUsersResponse createVpnUserResponse(VpnUser user);
RemoteAccessVpnResponse createRemoteAccessVpnResponse(RemoteAccessVpn vpn);
List createTemplateResponses(long templateId, Long zoneId, boolean readyOnly);
List createTemplateResponses(long templateId, Long snapshotId, Long volumeId, boolean readyOnly);
-
+
ListResponse createSecurityGroupResponses(List extends SecurityGroupRules> networkGroups);
-
+
SecurityGroupResponse createSecurityGroupResponseFromIngressRule(List extends IngressRule> ingressRules);
SecurityGroupResponse createSecurityGroupResponseFromEgressRule(List extends EgressRule> egressRules);
@@ -197,25 +199,27 @@ public interface ResponseGenerator {
TemplatePermissionsResponse createTemplatePermissionsResponse(List accountNames, Long id, boolean isAdmin);
AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd);
-
+
NetworkOfferingResponse createNetworkOfferingResponse(NetworkOffering offering);
-
+
NetworkResponse createNetworkResponse(Network network);
- UserResponse createUserResponse(User user);
+ UserResponse createUserResponse(User user);
- AccountResponse createUserAccountResponse(UserAccount user);
-
- Long getSecurityGroupId(String groupName, long accountId);
+ AccountResponse createUserAccountResponse(UserAccount user);
+
+ Long getSecurityGroupId(String groupName, long accountId);
List createIsoResponses(long isoId, Long zoneId, boolean readyOnly);
ProjectResponse createProjectResponse(Project project);
-
+
List createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly);
- List createTemplateResponses(long templateId, Long vmId);
-
+ List createTemplateResponses(long templateId, Long vmId);
+
FirewallResponse createFirewallResponse(FirewallRule fwRule);
+ HypervisorCapabilitiesResponse createHypervisorCapabilitiesResponse(HypervisorCapabilities hpvCapabilities);
+
}
diff --git a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java
index 3b1e99b0c95..3352df62cf8 100644
--- a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java
+++ b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java
@@ -98,7 +98,8 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd {
if (zone.getNetworkType() == NetworkType.Advanced) {
List extends Network> networks = _networkService.getVirtualNetworksOwnedByAccountInZone(getAccountName(), getDomainId(), getZoneId());
if (networks.size() == 0) {
- throw new InvalidParameterValueException("Account name=" + getAccountName() + " domainId=" + getDomainId() + " doesn't have virtual networks in zone " + getZoneId());
+ String domain = _accountService.getDomain(getDomainId()).getName();
+ throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + " doesn't have virtual networks in zone=" + zone.getName());
}
assert (networks.size() <= 1) : "Too many virtual networks. This logic should be obsolete";
return networks.get(0).getId();
diff --git a/api/src/com/cloud/api/commands/ListHypervisorCapabilitiesCmd.java b/api/src/com/cloud/api/commands/ListHypervisorCapabilitiesCmd.java
new file mode 100644
index 00000000000..d857dd31f1b
--- /dev/null
+++ b/api/src/com/cloud/api/commands/ListHypervisorCapabilitiesCmd.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.api.BaseListCmd;
+import com.cloud.api.Implementation;
+import com.cloud.api.Parameter;
+import com.cloud.api.response.HypervisorCapabilitiesResponse;
+import com.cloud.api.response.ListResponse;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorCapabilities;
+
+@Implementation(description="Lists all hypervisor capabilities.", responseObject=HypervisorCapabilitiesResponse.class)
+public class ListHypervisorCapabilitiesCmd extends BaseListCmd {
+ public static final Logger s_logger = Logger.getLogger(ListHypervisorCapabilitiesCmd.class.getName());
+
+ private static final String s_name = "listhypervisorcapabilitiesresponse";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="ID of the hypervisor capability")
+ private Long id;
+
+ @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, description="the hypervisor for which to restrict the search")
+ private String hypervisor;
+
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getId() {
+ return id;
+ }
+
+ public HypervisorType getHypervisor() {
+ if(hypervisor != null){
+ return HypervisorType.getType(hypervisor);
+ }else{
+ return null;
+ }
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public void execute(){
+ List extends HypervisorCapabilities> hpvCapabilities = _mgr.listHypervisorCapabilities(getId(), getHypervisor(), this.getStartIndex(), this.getPageSizeVal());
+ ListResponse response = new ListResponse();
+ List hpvCapabilitiesResponses = new ArrayList();
+ for (HypervisorCapabilities capability : hpvCapabilities) {
+ HypervisorCapabilitiesResponse hpvCapabilityResponse = _responseGenerator.createHypervisorCapabilitiesResponse(capability);
+ hpvCapabilityResponse.setObjectName("hypervisorCapabilities");
+ hpvCapabilitiesResponses.add(hpvCapabilityResponse);
+ }
+
+ response.setResponses(hpvCapabilitiesResponses);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ }
+}
diff --git a/api/src/com/cloud/api/commands/UpdateHypervisorCapabilitiesCmd.java b/api/src/com/cloud/api/commands/UpdateHypervisorCapabilitiesCmd.java
new file mode 100644
index 00000000000..4497a44fc5c
--- /dev/null
+++ b/api/src/com/cloud/api/commands/UpdateHypervisorCapabilitiesCmd.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.api.commands;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.api.BaseCmd;
+import com.cloud.api.Implementation;
+import com.cloud.api.Parameter;
+import com.cloud.api.ServerApiException;
+import com.cloud.api.response.HypervisorCapabilitiesResponse;
+import com.cloud.api.response.ServiceOfferingResponse;
+import com.cloud.hypervisor.HypervisorCapabilities;
+import com.cloud.user.Account;
+
+
+@Implementation(description="Updates a hypervisor capabilities.", responseObject=ServiceOfferingResponse.class)
+public class UpdateHypervisorCapabilitiesCmd extends BaseCmd {
+ public static final Logger s_logger = Logger.getLogger(UpdateHypervisorCapabilitiesCmd.class.getName());
+ private static final String s_name = "updatehypervisorcapabilitiesresponse";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="ID of the hypervisor capability")
+ private Long id;
+
+ @Parameter(name=ApiConstants.SECURITY_GROUP_EANBLED, type=CommandType.BOOLEAN, description="set true to enable security group for this hypervisor.")
+ private Boolean securityGroupEnabled;
+
+ @Parameter(name=ApiConstants.MAX_GUESTS_LIMIT, type=CommandType.LONG, description="the max number of Guest VMs per host for this hypervisor.")
+ private Long maxGuestsLimit;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Boolean getSecurityGroupEnabled() {
+ return securityGroupEnabled;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public Long getMaxGuestsLimit() {
+ return maxGuestsLimit;
+ }
+
+
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM;
+ }
+
+ @Override
+ public void execute(){
+ HypervisorCapabilities result = _mgr.updateHypervisorCapabilities(getId(), getMaxGuestsLimit(), getSecurityGroupEnabled());
+ if (result != null){
+ HypervisorCapabilitiesResponse response = _responseGenerator.createHypervisorCapabilitiesResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update hypervisor capabilities");
+ }
+ }
+}
diff --git a/api/src/com/cloud/api/response/HostResponse.java b/api/src/com/cloud/api/response/HostResponse.java
index cd8e7fb2126..5d6b06a350d 100755
--- a/api/src/com/cloud/api/response/HostResponse.java
+++ b/api/src/com/cloud/api/response/HostResponse.java
@@ -80,7 +80,7 @@ public class HostResponse extends BaseResponse {
@SerializedName("cpuused") @Param(description="the amount of the host's CPU currently used")
private String cpuUsed;
-
+
@SerializedName("cpuwithoverprovisioning") @Param(description="the amount of the host's CPU after applying the cpu.overprovisioning.factor ")
private String cpuWithOverprovisioning;
@@ -122,7 +122,7 @@ public class HostResponse extends BaseResponse {
@SerializedName("clustername") @Param(description="the cluster name of the host")
private String clusterName;
-
+
@SerializedName("clustertype") @Param(description="the cluster type of the cluster that host belongs to")
private String clusterType;
@@ -137,28 +137,31 @@ public class HostResponse extends BaseResponse {
@SerializedName("events") @Param(description="events available for the host")
private String events;
-
+
@SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the host")
private Long jobId;
@SerializedName("jobstatus") @Param(description="shows the current pending asynchronous job status")
private Integer jobStatus;
-
+
@SerializedName("hosttags") @Param(description="comma-separated list of tags for the host")
private String hostTags;
-
+
@SerializedName("hasEnoughCapacity") @Param(description="true if this host has enough CPU and RAM capacity to migrate a VM to it, false otherwise")
private Boolean hasEnoughCapacity;
-
+
@SerializedName("allocationstate") @Param(description="the allocation state of the host")
private String allocationState;
+ @SerializedName(ApiConstants.HYPERVISOR_VERSION) @Param(description="the hypervisor version")
+ private String hypervisorVersion;
+
@Override
public Long getObjectId() {
return getId();
}
-
+
@Override
public Long getJobId() {
return jobId;
@@ -168,7 +171,7 @@ public class HostResponse extends BaseResponse {
public void setJobId(Long jobId) {
this.jobId = jobId;
}
-
+
@Override
public Integer getJobStatus() {
return jobStatus;
@@ -426,13 +429,13 @@ public class HostResponse extends BaseResponse {
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
-
+
public String getClusterType() {
- return clusterType;
+ return clusterType;
}
-
+
public void setClusterType(String clusterType) {
- this.clusterType = clusterType;
+ this.clusterType = clusterType;
}
public Boolean isLocalStorageActive() {
@@ -466,7 +469,7 @@ public class HostResponse extends BaseResponse {
public void setEvents(String events) {
this.events = events;
}
-
+
public String getHostTags() {
return hostTags;
}
@@ -474,7 +477,7 @@ public class HostResponse extends BaseResponse {
public void setHostTags(String hostTags) {
this.hostTags = hostTags;
}
-
+
public Boolean hasEnoughCapacity() {
return hasEnoughCapacity;
}
@@ -482,20 +485,29 @@ public class HostResponse extends BaseResponse {
public void setHasEnoughCapacity(Boolean hasEnoughCapacity) {
this.hasEnoughCapacity = hasEnoughCapacity;
}
-
+
public String getAllocationState() {
- return allocationState;
+ return allocationState;
}
-
+
public void setAllocationState(String allocationState) {
- this.allocationState = allocationState;
+ this.allocationState = allocationState;
}
-
+
public String getCpuWithOverprovisioning() {
return cpuWithOverprovisioning;
}
public void setCpuWithOverprovisioning(String cpuWithOverprovisioning) {
this.cpuWithOverprovisioning = cpuWithOverprovisioning;
- }
+ }
+
+ public void setHypervisorVersion(String hypervisorVersion) {
+ this.hypervisorVersion = hypervisorVersion;
+ }
+
+ public String getHypervisorVersion() {
+ return hypervisorVersion;
+ }
+
}
diff --git a/api/src/com/cloud/api/response/HypervisorCapabilitiesResponse.java b/api/src/com/cloud/api/response/HypervisorCapabilitiesResponse.java
new file mode 100644
index 00000000000..fe968369159
--- /dev/null
+++ b/api/src/com/cloud/api/response/HypervisorCapabilitiesResponse.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.api.response;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class HypervisorCapabilitiesResponse extends BaseResponse {
+ @SerializedName(ApiConstants.ID) @Param(description="the ID of the hypervisor capabilities row")
+ private Long id;
+
+ @SerializedName(ApiConstants.HYPERVISOR_VERSION) @Param(description="the hypervisor version")
+ private String hypervisorVersion;
+
+ @SerializedName(ApiConstants.HYPERVISOR) @Param(description="the hypervisor type")
+ private HypervisorType hypervisor;
+
+ @SerializedName(ApiConstants.MAX_GUESTS_LIMIT) @Param(description="the maximum number of guest vms recommended for this hypervisor")
+ private Long maxGuestsLimit;
+
+ @SerializedName(ApiConstants.SECURITY_GROUP_EANBLED) @Param(description="true if security group is supported")
+ private boolean isSecurityGroupEnabled;
+
+
+
+ @Override
+ public Long getObjectId() {
+ return getId();
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+
+ public String getHypervisorVersion() {
+ return hypervisorVersion;
+ }
+
+ public void setHypervisorVersion(String hypervisorVersion) {
+ this.hypervisorVersion = hypervisorVersion;
+ }
+
+ public HypervisorType getHypervisor() {
+ return hypervisor;
+ }
+
+ public void setHypervisor(HypervisorType hypervisor) {
+ this.hypervisor = hypervisor;
+ }
+
+ public Long getMaxGuestsLimit() {
+ return maxGuestsLimit;
+ }
+
+ public void setMaxGuestsLimit(Long maxGuestsLimit) {
+ this.maxGuestsLimit = maxGuestsLimit;
+ }
+
+ public Boolean getIsSecurityGroupEnabled() {
+ return this.isSecurityGroupEnabled;
+ }
+
+ public void setIsSecurityGroupEnabled(Boolean sgEnabled) {
+ this.isSecurityGroupEnabled = sgEnabled;
+ }
+}
diff --git a/api/src/com/cloud/host/Host.java b/api/src/com/cloud/host/Host.java
index 280ad33d72b..7cd674c0aba 100755
--- a/api/src/com/cloud/host/Host.java
+++ b/api/src/com/cloud/host/Host.java
@@ -36,7 +36,7 @@ public interface Host {
ExternalLoadBalancer(false),
PxeServer(false),
TrafficMonitor(false),
-
+
ExternalDhcp(false),
SecondaryStorageVM(true),
LocalSecondaryStorage(false);
@@ -44,11 +44,11 @@ public interface Host {
private Type(boolean virtual) {
_virtual = virtual;
}
-
+
public boolean isVirtual() {
return _virtual;
}
-
+
public static String[] toStrings(Host.Type... types) {
String[] strs = new String[types.length];
for (int i = 0; i < types.length; i++) {
@@ -57,27 +57,27 @@ public interface Host {
return strs;
}
}
-
+
public enum HostAllocationState {
Disabled,
Enabled;
}
-
+
/**
* @return id of the host.
*/
long getId();
-
+
/**
* @return name of the machine.
*/
String getName();
-
+
/**
* @return the type of host.
*/
Type getType();
-
+
/**
* @return the date the host first registered
*/
@@ -87,32 +87,32 @@ public interface Host {
* @return current state of this machine.
*/
Status getStatus();
-
+
/**
* @return the ip address of the host.
*/
String getPrivateIpAddress();
-
+
/**
* @return the ip address of the host attached to the storage network.
*/
String getStorageIpAddress();
-
+
/**
* @return the mac address of the host.
*/
String getGuid();
-
+
/**
* @return total amount of memory.
*/
Long getTotalMemory();
-
+
/**
* @return # of cores in a machine. Note two cpus with two cores each returns 4.
*/
Integer getCpus();
-
+
/**
* @return speed of each cpu in mhz.
*/
@@ -122,32 +122,32 @@ public interface Host {
* @return the proxy port that is being listened at the agent host
*/
Integer getProxyPort();
-
+
/**
* @return the pod.
*/
Long getPodId();
-
+
/**
* @return availability zone.
*/
long getDataCenterId();
-
+
/**
* @return parent path. only used for storage server.
*/
String getParent();
-
+
/**
* @return storage ip address.
*/
String getStorageIpAddressDeux();
-
+
/**
* @return type of hypervisor
*/
HypervisorType getHypervisorType();
-
+
/**
* @return disconnection date
*/
@@ -176,27 +176,29 @@ public interface Host {
*@return removal date
*/
Date getRemoved();
-
+
Long getClusterId();
-
+
String getPublicIpAddress();
-
+
String getPublicNetmask();
-
+
String getPrivateNetmask();
-
+
String getStorageNetmask();
-
+
String getStorageMacAddress();
-
+
String getPublicMacAddress();
-
+
String getPrivateMacAddress();
-
+
String getStorageNetmaskDeux();
-
+
String getStorageMacAddressDeux();
-
+
HostAllocationState getHostAllocationState();
-
+
+ String getHypervisorVersion();
+
}
diff --git a/api/src/com/cloud/host/Status.java b/api/src/com/cloud/host/Status.java
index 7b932e4762d..c915eb6a0cb 100644
--- a/api/src/com/cloud/host/Status.java
+++ b/api/src/com/cloud/host/Status.java
@@ -180,15 +180,18 @@ public enum Status {
s_fsm.addTransition(Status.Disconnected, Event.WaitedTooLong, Status.Alert);
s_fsm.addTransition(Status.Disconnected, Event.Remove, Status.Removed);
s_fsm.addTransition(Status.Disconnected, Event.HypervisorVersionChanged, Status.Disconnected);
+ s_fsm.addTransition(Status.Disconnected, Event.AgentDisconnected, Status.Disconnected);
s_fsm.addTransition(Status.Down, Event.MaintenanceRequested, Status.PrepareForMaintenance);
s_fsm.addTransition(Status.Down, Event.AgentConnected, Status.Connecting);
s_fsm.addTransition(Status.Down, Event.Remove, Status.Removed);
s_fsm.addTransition(Status.Down, Event.ManagementServerDown, Status.Down);
+ s_fsm.addTransition(Status.Down, Event.AgentDisconnected, Status.Down);
s_fsm.addTransition(Status.Alert, Event.MaintenanceRequested, Status.PrepareForMaintenance);
s_fsm.addTransition(Status.Alert, Event.AgentConnected, Status.Connecting);
s_fsm.addTransition(Status.Alert, Event.Ping, Status.Up);
s_fsm.addTransition(Status.Alert, Event.Remove, Status.Removed);
s_fsm.addTransition(Status.Alert, Event.ManagementServerDown, Status.Alert);
+ s_fsm.addTransition(Status.Alert, Event.AgentDisconnected, Status.Alert);
s_fsm.addTransition(Status.Rebalancing, Event.RebalanceFailed, Status.Disconnected);
s_fsm.addTransition(Status.Rebalancing, Event.RebalanceCompleted, Status.Connecting);
}
diff --git a/api/src/com/cloud/hypervisor/Hypervisor.java b/api/src/com/cloud/hypervisor/Hypervisor.java
index 15295727c4e..2f50e072512 100644
--- a/api/src/com/cloud/hypervisor/Hypervisor.java
+++ b/api/src/com/cloud/hypervisor/Hypervisor.java
@@ -20,50 +20,51 @@ package com.cloud.hypervisor;
public class Hypervisor {
public static enum HypervisorType {
- None, //for storage hosts
- Xen,
- XenServer,
- KVM,
- VMware,
- Hyperv,
- VirtualBox,
- Parralels,
- BareMetal,
- Simulator,
- Ovm,
-
- Any; /*If you don't care about the hypervisor type*/
+ None, //for storage hosts
+ Xen,
+ XenServer,
+ KVM,
+ VMware,
+ Hyperv,
+ VirtualBox,
+ Parralels,
+ BareMetal,
+ Simulator,
+ Ovm,
- public static HypervisorType getType(String hypervisor) {
- if (hypervisor == null) {
- return HypervisorType.None;
- }
+ Any; /*If you don't care about the hypervisor type*/
- if (hypervisor.equalsIgnoreCase("Xen")) {
- return HypervisorType.Xen;
- } else if (hypervisor.equalsIgnoreCase("XenServer")) {
- return HypervisorType.XenServer;
- } else if (hypervisor.equalsIgnoreCase("KVM")) {
- return HypervisorType.KVM;
- } else if (hypervisor.equalsIgnoreCase("VMware")) {
- return HypervisorType.VMware;
- } else if (hypervisor.equalsIgnoreCase("Hyperv")) {
- return HypervisorType.Hyperv;
- } else if (hypervisor.equalsIgnoreCase("VirtualBox")) {
- return HypervisorType.VirtualBox;
- } else if (hypervisor.equalsIgnoreCase("Parralels")) {
- return HypervisorType.Parralels;
- }else if (hypervisor.equalsIgnoreCase("BareMetal")) {
- return HypervisorType.BareMetal;
- } else if (hypervisor.equalsIgnoreCase("Simulator")) {
- return HypervisorType.Simulator;
- } else if (hypervisor.equalsIgnoreCase("Ovm")) {
- return HypervisorType.Ovm;
- } else if (hypervisor.equalsIgnoreCase("Any")) {
- return HypervisorType.Any;
- } else {
- return HypervisorType.None;
- }
- }
+ public static HypervisorType getType(String hypervisor) {
+ if (hypervisor == null) {
+ return HypervisorType.None;
+ }
+
+ if (hypervisor.equalsIgnoreCase("Xen")) {
+ return HypervisorType.Xen;
+ } else if (hypervisor.equalsIgnoreCase("XenServer")) {
+ return HypervisorType.XenServer;
+ } else if (hypervisor.equalsIgnoreCase("KVM")) {
+ return HypervisorType.KVM;
+ } else if (hypervisor.equalsIgnoreCase("VMware")) {
+ return HypervisorType.VMware;
+ } else if (hypervisor.equalsIgnoreCase("Hyperv")) {
+ return HypervisorType.Hyperv;
+ } else if (hypervisor.equalsIgnoreCase("VirtualBox")) {
+ return HypervisorType.VirtualBox;
+ } else if (hypervisor.equalsIgnoreCase("Parralels")) {
+ return HypervisorType.Parralels;
+ }else if (hypervisor.equalsIgnoreCase("BareMetal")) {
+ return HypervisorType.BareMetal;
+ } else if (hypervisor.equalsIgnoreCase("Simulator")) {
+ return HypervisorType.Simulator;
+ } else if (hypervisor.equalsIgnoreCase("Ovm")) {
+ return HypervisorType.Ovm;
+ } else if (hypervisor.equalsIgnoreCase("Any")) {
+ return HypervisorType.Any;
+ } else {
+ return HypervisorType.None;
+ }
+ }
}
+
}
diff --git a/api/src/com/cloud/hypervisor/HypervisorCapabilities.java b/api/src/com/cloud/hypervisor/HypervisorCapabilities.java
new file mode 100644
index 00000000000..6623740d2a7
--- /dev/null
+++ b/api/src/com/cloud/hypervisor/HypervisorCapabilities.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.hypervisor;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+
+
+/**
+ * HypervisorCapability represents one particular hypervisor version's capabilities.
+ */
+public interface HypervisorCapabilities {
+ /**
+ * @return id of the host.
+ */
+ long getId();
+
+ /**
+ * @return type of hypervisor
+ */
+ HypervisorType getHypervisorType();
+
+
+ String getHypervisorVersion();
+
+ boolean isSecurityGroupEnabled();
+
+ /**
+ * @return the maxGuestslimit
+ */
+ Long getMaxGuestsLimit();
+
+
+}
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index bf88bfe65f3..3495a3e5c23 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -91,6 +91,7 @@ public interface Network extends ControlledEntity {
public static final Provider DhcpServer = new Provider("DhcpServer");
public static final Provider JuniperSRX = new Provider("JuniperSRX");
public static final Provider F5BigIp = new Provider("F5BigIp");
+ public static final Provider NetscalerMPX = new Provider("NetscalerMPX");
public static final Provider ExternalDhcpServer = new Provider("ExternalDhcpServer");
public static final Provider ExternalGateWay = new Provider("ExternalGateWay");
public static final Provider ElasticLoadBalancerVm = new Provider("ElasticLoadBalancerVm");
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java
index b0ec7b3e62c..123f56597a2 100755
--- a/api/src/com/cloud/server/ManagementService.java
+++ b/api/src/com/cloud/server/ManagementService.java
@@ -89,6 +89,8 @@ import com.cloud.exception.InternalErrorException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorCapabilities;
import com.cloud.network.IpAddress;
import com.cloud.network.router.VirtualRouter;
import com.cloud.offering.DiskOffering;
@@ -307,7 +309,7 @@ public interface ManagementService {
* @return List of capacities
*/
List extends Capacity> listCapacityByType(ListCapacityByTypeCmd cmd);
-
+
/**
* List the permissions on a template. This will return a list of account names that have been granted permission to launch
* instances from the template.
@@ -508,5 +510,9 @@ public interface ManagementService {
Pair, List> listHostsForMigrationOfVM(UserVm vm, Long startIndex, Long pageSize);
String[] listEventTypes();
-
+
+ List extends HypervisorCapabilities> listHypervisorCapabilities(Long id, HypervisorType hypervisorType, Long startIndex, Long pageSizeVal);
+
+ HypervisorCapabilities updateHypervisorCapabilities(Long id, Long maxGuestsLimit, Boolean securityGroupEnabled);
+
}
diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/Snapshot.java
index 453fa57abbc..d9c190e1d75 100644
--- a/api/src/com/cloud/storage/Snapshot.java
+++ b/api/src/com/cloud/storage/Snapshot.java
@@ -20,9 +20,10 @@ package com.cloud.storage;
import java.util.Date;
+import com.cloud.acl.ControlledEntity;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
-public interface Snapshot {
+public interface Snapshot extends ControlledEntity{
public enum Type {
MANUAL,
RECURRING,
diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java
index a763acc966b..0920b0b1f7f 100755
--- a/api/src/com/cloud/vm/VirtualMachine.java
+++ b/api/src/com/cloud/vm/VirtualMachine.java
@@ -32,8 +32,6 @@ import com.cloud.utils.fsm.StateObject;
*/
public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject {
- public static final String PARAM_KEY_KEYBOARD = "keyboard";
-
public enum State {
Starting(true, "VM is being started. At this state, you should find host id filled which means it's being started on that host."),
Running(false, "VM is running. host id has the host that it is running on."),
diff --git a/build.xml b/build.xml
index f1f4b7fb1ac..c6712e42be3 100755
--- a/build.xml
+++ b/build.xml
@@ -25,4 +25,5 @@
+
diff --git a/build/build-cloud.xml b/build/build-cloud.xml
index 1e3c64f10e5..489b4c48089 100755
--- a/build/build-cloud.xml
+++ b/build/build-cloud.xml
@@ -13,6 +13,7 @@
-->
+
@@ -62,6 +63,7 @@
+
@@ -145,17 +147,27 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/build/build-tests.xml b/build/build-tests.xml
index 289394c936a..400465dde51 100755
--- a/build/build-tests.xml
+++ b/build/build-tests.xml
@@ -25,14 +25,14 @@
-
+
-
+
diff --git a/build/build-usage.xml b/build/build-usage.xml
new file mode 100644
index 00000000000..eaba1d7f057
--- /dev/null
+++ b/build/build-usage.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ Cloud Stack Usage server build
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/developer.xml b/build/developer.xml
index 2ace5c0a1c0..52c6866869c 100755
--- a/build/developer.xml
+++ b/build/developer.xml
@@ -20,6 +20,9 @@
+
+
+
@@ -143,8 +146,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/build/package.xml b/build/package.xml
index 8f735c01324..175e47b61a4 100755
--- a/build/package.xml
+++ b/build/package.xml
@@ -189,12 +189,12 @@
-
+
-
-
+
+
diff --git a/client/.project b/client/.project
index f3ae78416f1..d11f22afe31 100644
--- a/client/.project
+++ b/client/.project
@@ -5,6 +5,11 @@
+
+ org.python.pydev.PyDevBuilder
+
+
+
org.eclipse.jdt.core.javabuilder
@@ -13,5 +18,6 @@
org.eclipse.jdt.core.javanature
+ org.python.pydev.pythonNature
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index 21cd03bbb06..336c571d4c8 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -4,6 +4,8 @@
#Labels
+label.ocfs2=OCFS2
+
label.action.edit.host=Edit Host
network.rate=Network Rate
@@ -66,7 +68,6 @@ label.PING.CIFS.username=PING CIFS username
label.PING.CIFS.password=PING CIFS password
label.CPU.cap=CPU Cap
-label.network.domain=Network Domain
label.action.enable.zone=Enable Zone
label.action.enable.zone.processing=Enabling Zone....
@@ -387,7 +388,6 @@ label.full=Full
label.gateway=Gateway
label.general.alerts=General Alerts
label.generating.url=Generating URL
-label.generating.url=Generating URL
label.go.step.2=Go to Step 2
label.go.step.3=Go to Step 3
label.go.step.4=Go to Step 4
@@ -563,7 +563,6 @@ label.private.ips=Private IP Addresses
label.private.port=Private Port
label.private.zone=Private Zone
label.protocol=Protocol
-label.protocol=Protocol
label.public.interface=Public Interface
label.public.ip=Public IP Address
label.public.ips=Public IP Addresses
@@ -635,7 +634,6 @@ label.succeeded=Succeeded
label.sunday=Sunday
label.system.capacity=System Wide Capacity
label.system.vm.type=System VM Type
-label.system.vm.type=System VM Type
label.system.vm=System VM
label.system.vms=System VMs
label.tagged=Tagged
@@ -738,7 +736,6 @@ message.action.destroy.instance=Please confirm that you want to destroy this ins
message.action.destroy.systemvm=Please confirm that you want to destroy this System VM.
message.action.disable.static.NAT=Please confirm that you want to disable static NAT.
message.action.enable.maintenance=Your host has been successfully prepared for maintenance. This process can take up to several minutes or longer depending on how many VMs are currently on this host.
-message.action.force.reconnect=Please confirm that you want to force a reconnection for this host.
message.action.force.reconnect=Your host has been successfully forced to reconnect. This process can take up to several minutes.
message.action.host.enable.maintenance.mode=Enabling maintenance mode will cause a live migration of all running instances on this host to any available host.
message.action.instance.reset.password=Please confirm that you want to change the ROOT password for this virtual machine.
@@ -842,4 +839,4 @@ error.login=Your username/password does not match our records.
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.
\ No newline at end of file
+error.unresolved.internet.name=Your internet name cannot be resolved.
diff --git a/client/WEB-INF/classes/resources/messages_es.properties b/client/WEB-INF/classes/resources/messages_es.properties
index 30f0c3a88c8..de8a434065a 100644
--- a/client/WEB-INF/classes/resources/messages_es.properties
+++ b/client/WEB-INF/classes/resources/messages_es.properties
@@ -4,6 +4,8 @@
#Labels
+label.ocfs2=OCFS2
+
label.action.edit.host=edición Anfitrión
network.rate=Tasa de red
diff --git a/client/WEB-INF/classes/resources/messages_ja.properties b/client/WEB-INF/classes/resources/messages_ja.properties
index 8e2a5105806..da6f133db5b 100644
--- a/client/WEB-INF/classes/resources/messages_ja.properties
+++ b/client/WEB-INF/classes/resources/messages_ja.properties
@@ -4,6 +4,8 @@
#Labels
+label.ocfs2=OCFS2
+
label.action.edit.host=ホストを編集する
network.rate=ネットワーク速度
diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties
index 8de433f026f..c18156aa439 100644
--- a/client/WEB-INF/classes/resources/messages_zh_CN.properties
+++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties
@@ -4,6 +4,8 @@
#Labels
+label.ocfs2=OCFS2
+
label.action.edit.host=编辑主机
network.rate=网络速率
diff --git a/client/bindir/cloud-setup-management.in b/client/bindir/cloud-setup-management.in
index 29126e34df9..c82f7407318 100755
--- a/client/bindir/cloud-setup-management.in
+++ b/client/bindir/cloud-setup-management.in
@@ -4,10 +4,17 @@ from cloudutils.utilities import initLoging
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
from cloudutils.globalEnv import globalEnv
from cloudutils.serviceConfigServer import cloudManagementConfig
+from optparse import OptionParser
if __name__ == '__main__':
initLoging("/var/log/cloud/setupManagement.log")
glbEnv = globalEnv()
+ parser = OptionParser()
+ parser.add_option("--https", action="store_true", dest="https", help="Enable HTTPs connection of management server")
+ (options, args) = parser.parse_args()
+ if options.https:
+ glbEnv.svrMode = "HttpsServer"
+
glbEnv.mode = "Server"
print "Starting to configure CloudStack Management Server:"
diff --git a/client/tomcatconf/cloudmanagementserver.keystore b/client/tomcatconf/cloudmanagementserver.keystore
new file mode 100644
index 00000000000..3ee4d13565a
Binary files /dev/null and b/client/tomcatconf/cloudmanagementserver.keystore differ
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index 65295ce7558..73280121dec 100755
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -274,4 +274,7 @@ listProjects=com.cloud.api.commands.ListProjectsCmd;15
createFirewallRule=com.cloud.api.commands.CreateFirewallRuleCmd;15
deleteFirewallRule=com.cloud.api.commands.DeleteFirewallRuleCmd;15
listFirewallRules=com.cloud.api.commands.ListFirewallRulesCmd;15
-
+
+#### hypervisor capabilities commands
+updateHypervisorCapabilities=com.cloud.api.commands.UpdateHypervisorCapabilitiesCmd;1
+listHypervisorCapabilities=com.cloud.api.commands.ListHypervisorCapabilitiesCmd;1
\ No newline at end of file
diff --git a/client/tomcatconf/components-premium.xml.in b/client/tomcatconf/components-premium.xml.in
index 82a903864c4..3d73ed27c10 100755
--- a/client/tomcatconf/components-premium.xml.in
+++ b/client/tomcatconf/components-premium.xml.in
@@ -31,7 +31,8 @@
-
+
+
diff --git a/client/tomcatconf/db.properties.in b/client/tomcatconf/db.properties.in
index c944023d7b3..f3a01a9835b 100644
--- a/client/tomcatconf/db.properties.in
+++ b/client/tomcatconf/db.properties.in
@@ -26,6 +26,14 @@ db.cloud.logAbandoned=true
db.cloud.poolPreparedStatements=false
db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true
+# Cloud.com database SSL settings
+db.cloud.useSSL=false
+db.cloud.keyStore=
+db.cloud.keyStorePassword=
+db.cloud.trustStore=
+db.cloud.trustStorePassword=
+
+
# usage database settings
db.usage.username=@DBUSER@
db.usage.password=@DBPW@
diff --git a/client/tomcatconf/server.xml.in b/client/tomcatconf/server-nonssl.xml
similarity index 100%
rename from client/tomcatconf/server.xml.in
rename to client/tomcatconf/server-nonssl.xml
diff --git a/client/tomcatconf/server-ssl.xml.in b/client/tomcatconf/server-ssl.xml.in
new file mode 100755
index 00000000000..cdb9267b811
--- /dev/null
+++ b/client/tomcatconf/server-ssl.xml.in
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/tomcatconf/tomcat6.conf.in b/client/tomcatconf/tomcat6-nonssl.conf.in
similarity index 100%
rename from client/tomcatconf/tomcat6.conf.in
rename to client/tomcatconf/tomcat6-nonssl.conf.in
diff --git a/client/tomcatconf/tomcat6-ssl.conf.in b/client/tomcatconf/tomcat6-ssl.conf.in
new file mode 100644
index 00000000000..da03a7d18b3
--- /dev/null
+++ b/client/tomcatconf/tomcat6-ssl.conf.in
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+
+# System-wide configuration file for tomcat6 services
+# This will be sourced by tomcat6 and any secondary service
+# Values will be overridden by service-specific configuration
+# files in /etc/sysconfig
+#
+# Use this one to change default values for all services
+# Change the service specific ones to affect only one service
+# (see, for instance, /etc/sysconfig/tomcat6)
+#
+
+# Where your java installation lives
+#JAVA_HOME="/usr/lib/jvm/java"
+
+# Where your tomcat installation lives
+CATALINA_BASE="@MSENVIRON@"
+CATALINA_HOME="@MSENVIRON@"
+JASPER_HOME="@MSENVIRON@"
+CATALINA_TMPDIR="@MSENVIRON@/temp"
+
+# You can pass some parameters to java here if you wish to
+#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3"
+
+# Use JAVA_OPTS to set java.library.path for libtcnative.so
+#JAVA_OPTS="-Djava.library.path=/usr/lib64"
+JAVA_OPTS="-Djava.awt.headless=true -Djavax.net.ssl.trustStore=/etc/cloud/management/cloudmanagementserver.keystore -Djavax.net.ssl.trustStorePassword=vmops.com -Dcom.sun.management.jmxremote.port=45219 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=@MSLOGDIR@ -XX:PermSize=128M"
+
+# What user should run tomcat
+TOMCAT_USER="@MSUSER@"
+# Do not remove the following line
+TOMCAT6_USER="$TOMCAT_USER"
+
+TOMCAT_LOG="@MSLOGDIR@/catalina.out"
+
+# You can change your tomcat locale here
+#LANG="en_US"
+
+# Run tomcat under the Java Security Manager
+SECURITY_MANAGER="false"
+
+# Time to wait in seconds, before killing process
+SHUTDOWN_WAIT="30"
+
+# Whether to annoy the user with "attempting to shut down" messages or not
+SHUTDOWN_VERBOSE="false"
+
+# Set the TOMCAT_PID location
+CATALINA_PID="@PIDDIR@/@PACKAGE@-management.pid"
+
+# Connector port is 8080 for this tomcat6 instance
+#CONNECTOR_PORT="8080"
+
+# We pick up the classpath in the next line
+
+dummy=1 ; . @MSCONF@/classpath.conf
diff --git a/cloud.spec b/cloud.spec
index 1c45fa7a58d..c996950b04c 100644
--- a/cloud.spec
+++ b/cloud.spec
@@ -108,7 +108,6 @@ CloudStack uses.
Summary: Cloud.com library dependencies
Requires: java >= 1.6.0
Obsoletes: vmops-deps < %{version}-%{release}
-Obsoletes: cloud-premium-deps < %{version}-%{release}
Group: System Environment/Libraries
%description deps
This package contains a number of third-party dependencies
@@ -228,6 +227,7 @@ Group: System Environment/Libraries
%if 0%{?rhel} >= 6
Requires: cloud-kvm
+Requires: cloud-qemu-img
%else
Requires: kvm
%endif
@@ -237,10 +237,6 @@ Requires: cloud-qemu-kvm
Requires: cloud-qemu-img
%endif
-%if 0%{?rhel} >= 6
-Requires: cloud-qemu-img
-%endif
-
%if 0%{?rhel} >= 5
Requires: qemu-img
%endif
@@ -311,24 +307,19 @@ The Cloud.com test package contains a suite of automated tests
that the very much appreciated QA team at Cloud.com constantly
uses to help increase the quality of the Cloud.com Stack.
+%package usage
+Summary: Cloud.com usage monitor
+Obsoletes: vmops-usage < %{version}-%{release}
+Requires: java >= 1.6.0
+Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-server = %{version}, %{name}-daemonize = %{version}
+Requires: %{name}-setup = %{version}
+Requires: %{name}-client = %{version}
+License: CSL 1.1
+Group: System Environment/Libraries
+%description usage
+The Cloud.com usage monitor provides usage accounting across the entire cloud for
+cloud operators to charge based on usage parameters.
-#%if %{_premium}
-#
-#
-#%package usage
-#Summary: Cloud.com usage monitor
-#Obsoletes: vmops-usage < %{version}-%{release}
-#Requires: java >= 1.6.0
-#Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-server = %{version}, %{name}-premium = %{version}, %{name}-daemonize = %{version}
-#Requires: %{name}-setup = %{version}
-#Requires: %{name}-client = %{version}
-#License: CSL 1.1
-#Group: System Environment/Libraries
-#%description usage
-#The Cloud.com usage monitor provides usage accounting across the entire cloud for
-#cloud operators to charge based on usage parameters.
-#
-#%endif
%prep
@@ -390,36 +381,29 @@ if [ "$1" == "1" ] ; then
/sbin/chkconfig --level 345 %{name}-management on > /dev/null 2>&1 || true
fi
+%preun usage
+if [ "$1" == "0" ] ; then
+ /sbin/chkconfig --del %{name}-usage > /dev/null 2>&1 || true
+ /sbin/service %{name}-usage stop > /dev/null 2>&1 || true
+fi
+%pre usage
+id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "Cloud.com unprivileged user" \
+ -r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true
+# user harcoded here, also hardcoded on wscript
-#%if %{_premium}
-#
-#%preun usage
-#if [ "$1" == "0" ] ; then
-# /sbin/chkconfig --del %{name}-usage > /dev/null 2>&1 || true
-# /sbin/service %{name}-usage stop > /dev/null 2>&1 || true
-#fi
-#
-#%pre usage
-#id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "Cloud.com unprivileged user" \
-# -r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true
-## user harcoded here, also hardcoded on wscript
-#
-#%post usage
-#if [ "$1" == "1" ] ; then
-# /sbin/chkconfig --add %{name}-usage > /dev/null 2>&1 || true
-# /sbin/chkconfig --level 345 %{name}-usage on > /dev/null 2>&1 || true
-#else
-# /sbin/service %{name}-usage condrestart >/dev/null 2>&1 || true
-#fi
-#
-#%endif
+%post usage
+if [ "$1" == "1" ] ; then
+ /sbin/chkconfig --add %{name}-usage > /dev/null 2>&1 || true
+ /sbin/chkconfig --level 345 %{name}-usage on > /dev/null 2>&1 || true
+else
+ /sbin/service %{name}-usage condrestart >/dev/null 2>&1 || true
+fi
%pre agent-scripts
id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "Cloud.com unprivileged user" \
-r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true
-
%preun agent
if [ "$1" == "0" ] ; then
/sbin/chkconfig --del %{name}-agent > /dev/null 2>&1 || true
@@ -484,12 +468,15 @@ fi
%files deps
%defattr(0644,root,root,0755)
-%{_javadir}/%{name}-commons-codec-1.4.jar
+%{_javadir}/%{name}-commons-codec-1.5.jar
+%{_javadir}/%{name}-commons-dbcp-1.4.jar
+%{_javadir}/%{name}-commons-pool-1.5.6.jar
+%{_javadir}/%{name}-google-gson-1.7.1.jar
+%{_javadir}/%{name}-netscaler.jar
%{_javadir}/%{name}-log4j-extras.jar
%{_javadir}/%{name}-backport-util-concurrent-3.0.jar
%{_javadir}/%{name}-ehcache.jar
%{_javadir}/%{name}-email.jar
-%{_javadir}/%{name}-gson.jar
%{_javadir}/%{name}-httpcore-4.0.jar
%{_javadir}/%{name}-libvirt-0.4.5.jar
%{_javadir}/%{name}-log4j.jar
@@ -512,8 +499,6 @@ fi
%{_javadir}/vmware*.jar
%{_javadir}/%{name}-jnetpcap.jar
%{_javadir}/%{name}-junit.jar
-%{_javadir}/%{name}-selenium-java-client-driver.jar
-%{_javadir}/%{name}-selenium-server.jar
%files core
@@ -612,20 +597,15 @@ fi
%{_libdir}/%{name}/test/*
%config(noreplace) %{_sysconfdir}/%{name}/test/*
-#%if %{_premium}
-#
-#
-#%files usage
-#%defattr(0644,root,root,0775)
+%files usage
+%defattr(0644,root,root,0775)
#%{_javadir}/%{name}-usage.jar
-#%attr(0755,root,root) %{_initrddir}/%{name}-usage
-#%attr(0755,root,root) %{_libexecdir}/usage-runner
+%attr(0755,root,root) %{_initrddir}/%{name}-usage
+%attr(0755,root,root) %{_libexecdir}/usage-runner
#%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/usage
#%{_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
-#
-#%endif
%changelog
* Mon May 3 2010 Manuel Amador (Rudd-O) 1.9.12
diff --git a/console-proxy/js/ajaxviewer.js b/console-proxy/js/ajaxviewer.js
index fabd50f5e2e..458091c402f 100644
--- a/console-proxy/js/ajaxviewer.js
+++ b/console-proxy/js/ajaxviewer.js
@@ -198,12 +198,14 @@ KeyboardMapper.prototype = {
/////////////////////////////////////////////////////////////////////////////
// class AjaxViewer
//
-function AjaxViewer(panelId, imageUrl, updateUrl, tileMap, width, height, tileWidth, tileHeight, rawKeyboard) {
+function AjaxViewer(panelId, imageUrl, updateUrl, tileMap, width, height, tileWidth, tileHeight, rawKeyboard, linuxGuest) {
// logging is disabled by default so that it won't have negative impact on performance
// however, a back door key-sequence can trigger to open the logger window, it is designed to help
// trouble-shooting
g_logger = new Logger();
- g_logger.enable(false);
+ g_logger.enable(true);
+ // g_logger.open();
+ // g_logger.log(Logger.LEVEL_INFO, 'rawKeyboard: ' + rawKeyboard);
var ajaxViewer = this;
this.rawKeyboard = rawKeyboard;
@@ -226,6 +228,8 @@ function AjaxViewer(panelId, imageUrl, updateUrl, tileMap, width, height, tileWi
this.currentKeyboard = 0;
this.keyboardMappers = [];
+
+ this.linuxGuest = linuxGuest;
this.timer = 0;
this.eventQueue = [];
@@ -620,21 +624,110 @@ AjaxViewer.prototype = {
var charCodeMap = [];
var shiftedCharCodeMap = [];
- keyCodeMap[106] = { code: 222, shift : 1 }; // JP NUM *
- charCodeMap[42] = { code: 34, shift : 1 };
+ if(this.linuxGuest) {
+ // for LINUX guest OSes
+
+ shiftedKeyCodeMap[50] = { code: 222, shift: 1 } ; // JP SHIFT + 2 -> "
+ shiftedCharCodeMap[64] = { code: 34, shift: 1 };
+
+ shiftedKeyCodeMap[54] = { code: 55, shift : 1 }; // JP SHIFT + 6 -> &
+ shiftedCharCodeMap[94] = { code: 38, shift : 1 };
+
+ shiftedKeyCodeMap[55] = { code: 222, shift : 0 }; // JP SHIFT + 7 -> '
+ shiftedCharCodeMap[38] = { code: 39, shift : 1 };
+
+ shiftedKeyCodeMap[56] = { code: 57, shift : 1 }; // JP SHIFT + 8 -> (
+ shiftedCharCodeMap[42] = { code: 40, shift : 1 };
+
+ shiftedKeyCodeMap[57] = { code: 48, shift : 1 }; // JP SHIFT + 9 -> )
+ shiftedCharCodeMap[40] = { code: 41, shift : 1 };
- keyCodeMap[107] = { code: 59, shift : 1 }; // JP NUM +
- charCodeMap[43] = { code: 42, shift : 1 };
-
- keyCodeMap[110] = { code: 190, shift : 0 }; // JP NUM .
- charCodeMap[46] = { code: 46, shift : 0 };
+ shiftedKeyCodeMap[48] = { code: 192, shift : 1 }; // JP SHIFT + 0 -> ~
+ shiftedCharCodeMap[41] = { code: 126, shift : 1 };
- keyCodeMap[193] = { code: 220, shift : 0, charCode: 92 }; // JP key left to right shift on JP keyboard
- shiftedKeyCodeMap[193] = { code: 189, shift: 1, charCode: 64 };
-
- keyCodeMap[255] = { code: 220, shift : 0, charCode: 92 }; // JP Japanese Yen mark on JP keyboard
- shiftedKeyCodeMap[255] = { code: 220, shift: 1, charCode: 95 };
-
+ shiftedKeyCodeMap[109] = { code: 107, shift : 1 }; // JP SHIFT + (-=), keycode/charcode(109, 95) from Firefox
+ shiftedCharCodeMap[95] = { code: 61, shift : 0 };
+
+ shiftedKeyCodeMap[189] = { code: 107, shift : 1 }; // JP SHIFT + (-=), keycode/charcode(109, 95) from Chrome/Safari/MSIE
+ shiftedCharCodeMap[95] = { code: 61, shift : 0 };
+
+ shiftedKeyCodeMap[222] = { code: 192, shift : 1 }; // JP SHIFT + (~^)
+ shiftedCharCodeMap[126] = { code: 126, shift : 1 };
+
+ if($.browser.mozilla) {
+ keyCodeMap[107] = { code: 107, shift : 1, defer : true }; // JP NUM +, keycode/charcode (107, 43) from Firefox
+ charCodeMap[43] = { code: 43, shift : 1, keyCode: 43 };
+ charCodeMap[61] = { code: 94, shift : 0, keyCode: 94 }; // JP (~^), keycode/charcode (107, 61) from Firefox
+
+ shiftedKeyCodeMap[107] = { code: 192, shift : 1 }; // JP SHIFT + (!^)
+ shiftedCharCodeMap[43] = { code: 126, shift : 1 };
+ } else {
+ keyCodeMap[187] = { code: 54, shift: 1, defer: true }; // JP ~^
+ charCodeMap[61] = { code: 94, shift: 0, keyCode: 94 };
+
+ shiftedKeyCodeMap[187] = { code: 192, shift : 1 }; // JP SHIFT + (~^)
+ shiftedCharCodeMap[43] = { code: 126, shift : 1 };
+
+ keyCodeMap[107] = { code: 107, shift : 0, defer: true }; // JP NUM +, keycode/charcode(107, 43)
+ charCodeMap[43] = { code: 43, shift : 1, keyCode: 43 };
+ }
+
+ shiftedKeyCodeMap[255] = { code: 220, shift : 1, charCode: 124 }; // JP (|-, key before backspace), Japanese Yen mark
+
+ keyCodeMap[219] = { code: 192, shift : 0 }; // JP @`
+ charCodeMap[91] = { code: 96, shift : 0 };
+ shiftedKeyCodeMap[219] = { code: 50, shift : 1 }; // JP SHIFT + (@`)
+ shiftedCharCodeMap[123] = { code: 64, shift : 1 };
+
+ keyCodeMap[221] = { code: 219, shift : 0 }; // JP [{
+ charCodeMap[93] = { code: 91, shift : 0 };
+ shiftedKeyCodeMap[221] = { code: 219, shift : 1 };
+ shiftedCharCodeMap[125] = { code: 123, shift : 1 };
+
+ if($.browser.mozilla) {
+ shiftedKeyCodeMap[59] = { code: 107, shift : 1, defer: true }; // JP ;+
+ shiftedCharCodeMap[58] = { code: 43, shift : 1, keyCode: 43 };
+ } else {
+ shiftedKeyCodeMap[186] = { code: 107, shift : 1, defer: true }; // JP ;+
+ shiftedCharCodeMap[58] = { code: 43, shift : 1, keyCode: 43 };
+ }
+
+ keyCodeMap[222] = { code: 59, shift : 0, defer : true }; // JP :*
+ charCodeMap[39] = { code: 59, shift : 0, keyCode: 58 };
+ shiftedKeyCodeMap[222] = { code: 56, shift : 1 };
+ shiftedCharCodeMap[34] = { code: 42, shift : 1 };
+
+ keyCodeMap[220] = { code: 221, shift : 0 }; // JP ]}
+ charCodeMap[92] = { code: 93, shift : 0 };
+ shiftedKeyCodeMap[220] = { code: 221, shift : 1 };
+ shiftedCharCodeMap[124] = { code: 125, shift : 1 };
+
+ keyCodeMap[106] = { code: 222, shift : 1, defer: true }; // JP NUM *
+ charCodeMap[42] = { code: 42, shift : 1, keyCode: 42 };
+
+ keyCodeMap[110] = { code: 190, shift : 0 }; // JP NUM .
+ charCodeMap[46] = { code: 46, shift : 0 };
+
+ keyCodeMap[193] = { code: 220, shift : 0, charCode: 92 }; // JP key left to right shift on JP keyboard
+ shiftedKeyCodeMap[193] = { code: 189, shift: 1, charCode: 64 };
+
+ keyCodeMap[255] = { code: 220, shift : 0, charCode: 92 }; // JP Japanese Yen mark on JP keyboard
+ shiftedKeyCodeMap[255] = { code: 220, shift: 1, charCode: 95 };
+
+ } else {
+ // for windows guest OSes
+ keyCodeMap[106] = { code: 222, shift : 1 }; // JP NUM *
+ charCodeMap[42] = { code: 34, shift : 1 };
+
+ keyCodeMap[110] = { code: 190, shift : 0 }; // JP NUM .
+ charCodeMap[46] = { code: 46, shift : 0 };
+
+ keyCodeMap[193] = { code: 220, shift : 0, charCode: 92 }; // JP key left to right shift on JP keyboard
+ shiftedKeyCodeMap[193] = { code: 189, shift: 1, charCode: 64 };
+
+ keyCodeMap[255] = { code: 220, shift : 0, charCode: 92 }; // JP Japanese Yen mark on JP keyboard
+ shiftedKeyCodeMap[255] = { code: 220, shift: 1, charCode: 95 };
+ }
this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_JAPAN_EN_OS_TO_JP_VM] = new KeyboardMapper(false, keyCodeMap, shiftedKeyCodeMap,
charCodeMap, shiftedCharCodeMap);
},
@@ -645,76 +738,136 @@ AjaxViewer.prototype = {
var charCodeMap = [];
var shiftedCharCodeMap = [];
- shiftedKeyCodeMap[50] = { code: 50, shift: 1, defer: true }; // JP SHIFT + 2 -> "
- shiftedCharCodeMap[34] = { code: 0, shift : 1, keyCode: 50 };
-
- shiftedKeyCodeMap[55] = { code: 222, shift : 0, defer:true }; // JP SHIFT + 7 -> '
- shiftedCharCodeMap[39] = { code: 0, shift : 1, keyCode: 55 };
-
- keyCodeMap[222] = { code: 107, shift: 0 }; // JP ~^
- charCodeMap[94] = { code: 59, shift: 0 };
-
- shiftedKeyCodeMap[222] = { code: 107, shift : 1 }; // JP SHIFT + (~^)
- shiftedCharCodeMap[126] = { code: 43, shift : 1 };
-
- keyCodeMap[192] = { code: 219, shift : 0 }; // JP @`
- charCodeMap[64] = { code: 91, shift : 0 };
- shiftedKeyCodeMap[192] = { code: 219, shift : 1 }; // JP SHIFT + (@`)
- shiftedCharCodeMap[96] = { code: 123, shift : 1 };
-
- keyCodeMap[219] = { code: 221, shift : 0 }; // JP [{
- charCodeMap[91] = { code: 93, shift : 0 };
- shiftedKeyCodeMap[219] = { code: 221, shift : 1 };
- shiftedCharCodeMap[123] = { code: 125, shift : 1 };
-
- if($.browser.mozilla) {
- // Note, keycode 107 is duplicated with "+" key at NUM pad
- keyCodeMap[107] = { code: 59, shift : 0, defer: true }; // JP ;+
- charCodeMap[59] = { code: 58, shift : 0, keyCode: 59 };
- shiftedKeyCodeMap[107] = { code: 59, shift : 1 };
- shiftedCharCodeMap[43] = { code: 42, shift : 1 };
-
- // keyCodeMap[107] = { code: 59, shift : 1 }; // JP NUM +
- charCodeMap[43] = { code: 42, shift : 1, keyCode: 59 };
- } else {
- keyCodeMap[187] = { code: 59, shift : 0, defer: true }; // JP ;+
- charCodeMap[59] = { code: 58, shift : 0, keyCode: 59 };
- shiftedKeyCodeMap[187] = { code: 59, shift : 1 };
- shiftedCharCodeMap[43] = { code: 42, shift : 1 };
-
- keyCodeMap[107] = { code: 59, shift : 1 }; // JP NUM +
- charCodeMap[43] = { code: 42, shift : 1 };
- }
-
- if($.browser.mozilla) {
- keyCodeMap[59] = { code: 222, shift : 0 }; // JP :*
- charCodeMap[58] = { code: 39, shift : 0 };
- shiftedKeyCodeMap[59] = { code: 222, shift : 1 };
- shiftedCharCodeMap[42] = { code: 34, shift : 1 };
- } else {
- keyCodeMap[186] = { code: 222, shift : 0 }; // JP :*
- charCodeMap[58] = { code: 39, shift : 0 };
- shiftedKeyCodeMap[186] = { code: 222, shift : 1 };
- shiftedCharCodeMap[42] = { code: 34, shift : 1 };
- }
-
- keyCodeMap[221] = { code: 220, shift : 0 }; // JP ]}
- charCodeMap[93] = { code: 92, shift : 0 };
- shiftedKeyCodeMap[221] = { code: 220, shift : 1 };
- shiftedCharCodeMap[125] = { code: 124, shift : 1 };
-
- keyCodeMap[106] = { code: 222, shift : 1 }; // JP NUM *
- charCodeMap[42] = { code: 34, shift : 1 };
-
- keyCodeMap[110] = { code: 190, shift : 0 }; // JP NUM .
- charCodeMap[46] = { code: 46, shift : 0 };
+ if(this.linuxGuest) {
+ shiftedKeyCodeMap[50] = { code: 50, shift: 1, defer: true }; // JP SHIFT + 2 -> "
+ shiftedCharCodeMap[34] = { code: 34, shift : 1, keyCode: 34 };
- keyCodeMap[193] = { code: 220, shift : 0, charCode: 92 }; // JP key left to right shift on JP keyboard
- shiftedKeyCodeMap[193] = { code: 189, shift: 1, charCode: 64 };
-
- keyCodeMap[255] = { code: 220, shift : 0, charCode: 92 }; // JP Japanese Yen mark on JP keyboard
- shiftedKeyCodeMap[255] = { code: 220, shift: 1, charCode: 95 };
+ shiftedKeyCodeMap[54] = { code: 55, shift : 1 }; // JP SHIFT + 6 -> &
+ shiftedCharCodeMap[94] = { code: 38, shift : 1 };
+
+ shiftedKeyCodeMap[55] = { code: 222, shift : 0, defer:true }; // JP SHIFT + 7 -> '
+ shiftedCharCodeMap[39] = { code: 39, shift : 1, keyCode: 39 };
+
+ shiftedKeyCodeMap[56] = { code: 57, shift : 1 }; // JP SHIFT + 8 -> (
+ shiftedCharCodeMap[42] = { code: 40, shift : 1 };
+
+ shiftedKeyCodeMap[57] = { code: 48, shift : 1 }; // JP SHIFT + 9 -> )
+ shiftedCharCodeMap[40] = { code: 41, shift : 1 };
+
+ shiftedKeyCodeMap[48] = { code: 192, shift : 1 }; // JP SHIFT + 0 -> ~
+ shiftedCharCodeMap[41] = { code: 126, shift : 1 };
+
+ keyCodeMap[222] = { code: 107, shift: 0, defer: true }; // JP ~^
+ charCodeMap[94] = { code: 94, shift: 0, keyCode: 94 };
+ shiftedKeyCodeMap[222] = { code: 192, shift : 1, defer: true }; // JP SHIFT + (~^)
+ shiftedCharCodeMap[126] = { code: 126, shift : 1 };
+
+ shiftedKeyCodeMap[192] = { code: 50, shift : 1 }; // JP SHIFT + (@`)
+ shiftedCharCodeMap[96] = { code: 64, shift : 1 };
+
+ if($.browser.mozilla) {
+ shiftedKeyCodeMap[109] = { code: 107, shift : 1 }; // JP SHIFT + (-=), keycode/charcode(109, 95) from Firefox
+
+ // Note, keycode 107 is duplicated with "+" key at NUM pad
+ keyCodeMap[107] = { code: 59, shift : 0, defer: true }; // JP ;+
+ charCodeMap[59] = { code: 58, shift : 0, keyCode: 59 };
+ charCodeMap[43] = { code: 43, shift : 1, keyCode: 43 }; // JP NUM +
+
+ shiftedKeyCodeMap[107] = { code: 59, shift : 0, defer: true }; // JP ;+
+ shiftedCharCodeMap[43] = { code: 43, shift : 1, keyCode: 43 };
+
+ keyCodeMap[59] = { code: 59, shift : 0, defer : true }; // JP :*
+ charCodeMap[58] = { code: 58, shift : 0, keyCode: 58 };
+ } else {
+ shiftedKeyCodeMap[189] = { code: 107, shift : 1 }; // JP SHIFT + (-=), keycode/charcode(109, 95) from Chrome/Safari/MSIE
+ shiftedCharCodeMap[95] = { code: 61, shift : 0 };
+
+ keyCodeMap[187] = { code: 59, shift : 0, defer: true }; // JP ;+
+ charCodeMap[59] = { code: 58, shift : 0, keyCode: 59 };
+ shiftedKeyCodeMap[187] = { code: 59, shift : 1, defer: true };
+ shiftedCharCodeMap[43] = { code: 43, shift : 1, keyCode: 43 };
+
+ keyCodeMap[107] = { code: 59, shift : 0, defer: true }; // JP NUM +
+ charCodeMap[43] = { code: 43, shift : 1, keyCode: 43};
+
+ keyCodeMap[186] = { code: 59, shift : 0, defer: true }; // JP :*
+ charCodeMap[58] = { code: 58, shift : 0, keyCode: 58 };
+ }
+
+ keyCodeMap[226] = { code: 220, shift : 0, charCode: 92 }; // JP key left to right shift on JP keyboard
+ shiftedKeyCodeMap[226] = { code: 189, shift: 1 };
+
+ } else {
+ // windows guest
+ shiftedKeyCodeMap[50] = { code: 50, shift: 1, defer: true }; // JP SHIFT + 2 -> "
+ shiftedCharCodeMap[34] = { code: 0, shift : 1, keyCode: 50 };
+
+ shiftedKeyCodeMap[55] = { code: 222, shift : 0, defer:true }; // JP SHIFT + 7 -> '
+ shiftedCharCodeMap[39] = { code: 0, shift : 1, keyCode: 55 };
+
+ keyCodeMap[222] = { code: 107, shift: 0 }; // JP ~^
+ charCodeMap[94] = { code: 59, shift: 0 };
+
+ shiftedKeyCodeMap[222] = { code: 107, shift : 1 }; // JP SHIFT + (~^)
+ shiftedCharCodeMap[126] = { code: 43, shift : 1 };
+
+ keyCodeMap[192] = { code: 219, shift : 0 }; // JP @`
+ charCodeMap[64] = { code: 91, shift : 0 };
+ shiftedKeyCodeMap[192] = { code: 219, shift : 1 }; // JP SHIFT + (@`)
+ shiftedCharCodeMap[96] = { code: 123, shift : 1 };
+
+ keyCodeMap[219] = { code: 221, shift : 0 }; // JP [{
+ charCodeMap[91] = { code: 93, shift : 0 };
+ shiftedKeyCodeMap[219] = { code: 221, shift : 1 };
+ shiftedCharCodeMap[123] = { code: 125, shift : 1 };
+
+ if($.browser.mozilla) {
+ // Note, keycode 107 is duplicated with "+" key at NUM pad
+ keyCodeMap[107] = { code: 59, shift : 0, defer: true }; // JP ;+
+ charCodeMap[59] = { code: 58, shift : 0, keyCode: 59 };
+ shiftedKeyCodeMap[107] = { code: 59, shift : 0 };
+ shiftedCharCodeMap[43] = { code: 42, shift : 0 };
+ charCodeMap[43] = { code: 42, shift : 1, keyCode: 59 };
+ } else {
+ keyCodeMap[187] = { code: 59, shift : 0, defer: true }; // JP ;+
+ charCodeMap[59] = { code: 58, shift : 0, keyCode: 59 };
+ shiftedKeyCodeMap[187] = { code: 59, shift : 1 };
+ shiftedCharCodeMap[43] = { code: 42, shift : 1 };
+
+ keyCodeMap[107] = { code: 59, shift : 1 }; // JP NUM +
+ charCodeMap[43] = { code: 42, shift : 1 };
+ }
+
+ if($.browser.mozilla) {
+ keyCodeMap[59] = { code: 222, shift : 0 }; // JP :*
+ charCodeMap[58] = { code: 39, shift : 0 };
+ shiftedKeyCodeMap[59] = { code: 222, shift : 1 };
+ shiftedCharCodeMap[42] = { code: 34, shift : 1 };
+ } else {
+ keyCodeMap[186] = { code: 222, shift : 0 }; // JP :*
+ charCodeMap[58] = { code: 39, shift : 0 };
+ shiftedKeyCodeMap[186] = { code: 222, shift : 1 };
+ shiftedCharCodeMap[42] = { code: 34, shift : 1 };
+ }
+
+ keyCodeMap[221] = { code: 220, shift : 0 }; // JP ]}
+ charCodeMap[93] = { code: 92, shift : 0 };
+ shiftedKeyCodeMap[221] = { code: 220, shift : 1 };
+ shiftedCharCodeMap[125] = { code: 124, shift : 1 };
+
+ keyCodeMap[106] = { code: 222, shift : 1 }; // JP NUM *
+ charCodeMap[42] = { code: 34, shift : 1 };
+
+ keyCodeMap[110] = { code: 190, shift : 0 }; // JP NUM .
+ charCodeMap[46] = { code: 46, shift : 0 };
+
+ keyCodeMap[193] = { code: 220, shift : 0, charCode: 92 }; // JP key left to right shift on JP keyboard
+ shiftedKeyCodeMap[193] = { code: 189, shift: 1, charCode: 64 };
+
+ keyCodeMap[255] = { code: 220, shift : 0, charCode: 92 }; // JP Japanese Yen mark on JP keyboard
+ shiftedKeyCodeMap[255] = { code: 220, shift: 1, charCode: 95 };
+ }
this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_JAPAN_JP_OS_TO_JP_VM] = new KeyboardMapper(false, keyCodeMap, shiftedKeyCodeMap,
charCodeMap, shiftedCharCodeMap);
},
diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java
index bb1f1e21682..6bd73786701 100644
--- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java
+++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java
@@ -76,7 +76,8 @@ public class ConsoleProxyAjaxHandler implements HttpHandler {
String tag = queryMap.get("tag");
String ticket = queryMap.get("ticket");
String ajaxSessionIdStr = queryMap.get("sess");
- String eventStr = queryMap.get("event");
+ String eventStr = queryMap.get("event");
+
if(tag == null)
tag = "";
@@ -171,8 +172,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler {
if(s_logger.isDebugEnabled())
s_logger.debug("Ajax request indicates a fresh client start");
- String title = queryMap.get("t");
- handleClientStart(t, viewer, title != null ? title : "");
+ String title = queryMap.get("t");
+ String guest = queryMap.get("guest");
+ handleClientStart(t, viewer, title != null ? title : "", guest);
} else {
if(s_logger.isTraceEnabled())
@@ -392,9 +394,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler {
}
}
- private void handleClientStart(HttpExchange t, ConsoleProxyViewer viewer, String title) throws IOException {
+ private void handleClientStart(HttpExchange t, ConsoleProxyViewer viewer, String title, String guest) throws IOException {
List languages = t.getRequestHeaders().get("Accept-Language");
- String response = viewer.onAjaxClientStart(title, languages);
+ String response = viewer.onAjaxClientStart(title, languages, guest);
Headers hds = t.getResponseHeaders();
hds.set("Content-Type", "text/html");
diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxKeyMapper.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxKeyMapper.java
index 2f0b1a2a3c8..9911cc1a500 100644
--- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxKeyMapper.java
+++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxKeyMapper.java
@@ -178,7 +178,7 @@ public class ConsoleProxyAjaxKeyMapper {
js2javaCodeMap.put(new Integer(18), new Integer(0xffe9));
// for SHIFT transaction at proxy side
- shiftedKeyCharMap = new HashMap();
+ shiftedKeyCharMap = new HashMap();
shiftedKeyCharMap.put(new Integer('1'), new Integer('!'));
shiftedKeyCharMap.put(new Integer('2'), new Integer('@'));
shiftedKeyCharMap.put(new Integer('3'), new Integer('#'));
@@ -190,7 +190,7 @@ public class ConsoleProxyAjaxKeyMapper {
shiftedKeyCharMap.put(new Integer('9'), new Integer('('));
shiftedKeyCharMap.put(new Integer('0'), new Integer(')'));
shiftedKeyCharMap.put(new Integer('-'), new Integer('_'));
- shiftedKeyCharMap.put(new Integer('='), new Integer('+'));
+ //shiftedKeyCharMap.put(new Integer('='), new Integer('+'));
shiftedKeyCharMap.put(new Integer('`'), new Integer('~'));
shiftedKeyCharMap.put(new Integer('['), new Integer('{'));
shiftedKeyCharMap.put(new Integer(']'), new Integer('}'));
@@ -239,7 +239,7 @@ public class ConsoleProxyAjaxKeyMapper {
return vkCode.intValue();
}
- public int getJvmKeyCode(int jsKeyCode) {
+ public int getJvmKeyCode(int jsKeyCode) {
Integer code = js2javaCodeMap.get(jsKeyCode);
if(code != null)
return code.intValue();
diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyViewer.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyViewer.java
index d3d0153f365..c1c2211c06c 100644
--- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyViewer.java
+++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyViewer.java
@@ -924,7 +924,7 @@ public class ConsoleProxyViewer implements java.lang.Runnable, RfbViewer, RfbPro
"