diff --git a/.gitignore b/.gitignore index b465d22a73f..df8c2ae5163 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,8 @@ artifacts waf-* target override -premium .metadata dist *~ *.bak +cloud-*.tar.bz2 diff --git a/agent/bindir/cloud-setup-agent.in b/agent/bindir/cloud-setup-agent.in index 4fabf7a3b22..9c5913b6926 100755 --- a/agent/bindir/cloud-setup-agent.in +++ b/agent/bindir/cloud-setup-agent.in @@ -37,16 +37,14 @@ backupdir = "@SHAREDSTATEDIR@/@AGENTPATH@/etcbackup" #=================== the magic happens here ==================== -stderr("Welcome to the Cloud Agent setup") -stderr("") try: # parse cmd line - opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod=", "no-kvm"]) + opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod=", "no-kvm", "guid="]) host=None zone=None pod=None - stderr(str(opts)) + guid=None autoMode=False do_check_kvm = True for opt, arg in opts: @@ -59,11 +57,19 @@ try: elif opt == "--pod": if arg != "": pod = arg + elif opt == "--guid": + if arg != "": + guid = arg elif opt == "--no-kvm": do_check_kvm = False elif opt == "-a": autoMode=True + if autoMode: + cloud_utils.setLogFile("/var/log/cloud/setupAgent.log") + + stderr("Welcome to the Cloud Agent setup") + stderr("") # pre-flight checks for things that the administrator must fix try: for f,n in cloud_utils.preflight_checks( @@ -106,7 +112,7 @@ try: stderr(str(e)) bail(cloud_utils.E_SETUPFAILED,"Cloud Agent setup failed") - setup_agent_config(configfile, host, zone, pod) + setup_agent_config(configfile, host, zone, pod, guid) stderr("Enabling and starting the Cloud Agent") stop_service(servicename) enable_service(servicename) diff --git a/agent/src/com/cloud/agent/resource/DummyResource.java b/agent/src/com/cloud/agent/resource/DummyResource.java index c269c64284d..9ff60e1220d 100755 --- a/agent/src/com/cloud/agent/resource/DummyResource.java +++ b/agent/src/com/cloud/agent/resource/DummyResource.java @@ -32,6 +32,7 @@ import com.cloud.resource.ServerResource; @Local(value={ServerResource.class}) public class DummyResource implements ServerResource { + private boolean _isRemoteAgent = false; String _name; Host.Type _type; boolean _negative; @@ -101,4 +102,12 @@ public class DummyResource implements ServerResource { public void setAgentControl(IAgentControl agentControl) { _agentControl = agentControl; } + + public boolean IsRemoteAgent() { + return _isRemoteAgent; + } + + public void setRemoteAgent(boolean remote) { + _isRemoteAgent = remote; + } } diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index a10c9c2e9cd..986ac065f6d 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -149,7 +149,7 @@ - + diff --git a/console-proxy/bindir/cloud-setup-console-proxy.in b/console-proxy/bindir/cloud-setup-console-proxy.in index b550407d593..9bf55bc2f09 100755 --- a/console-proxy/bindir/cloud-setup-console-proxy.in +++ b/console-proxy/bindir/cloud-setup-console-proxy.in @@ -14,6 +14,7 @@ for pythonpath in ( if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath) # ---- End snippet of code ---- import cloud_utils +from cloud_utils import stderr E_GENERIC= 1 E_NOKVM = 2 @@ -27,13 +28,6 @@ E_CPRECONFIGFAILED = 9 E_CPFAILEDTOSTART = 10 E_NOFQDN = 11 - -def stderr(msgfmt,*args): - msgfmt += "\n" - if args: sys.stderr.write(msgfmt%args) - else: sys.stderr.write(msgfmt) - sys.stderr.flush() - def bail(errno=E_GENERIC,message=None,*args): if message: stderr(message,*args) stderr("Cloud Console Proxy setup aborted") @@ -133,10 +127,11 @@ CentOS = os.path.exists("/etc/centos-release") or ( os.path.exists("/etc/redhat- def main(): # parse cmd line - opts, args = getopt.getopt(sys.argv[1:], "", ["host=", "zone=", "pod="]) + opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod="]) host=None zone=None pod=None + autoMode=False do_check_kvm = True for opt, arg in opts: if opt == "--host": @@ -148,8 +143,13 @@ def main(): elif opt == "--pod": if arg != "": pod = arg + elif opt == "-a": + autoMode=True servicename = "@PACKAGE@-console-proxy" + if autoMode: + cloud_utils.setLogFile("/var/log/cloud/setupConsoleProxy.log") + stderr("Welcome to the Cloud Console Proxy setup") stderr("") diff --git a/core/src/com/cloud/hypervisor/kvm/resource/KvmDummyResourceBase.java b/core/src/com/cloud/hypervisor/kvm/resource/KvmDummyResourceBase.java new file mode 100644 index 00000000000..78451bced48 --- /dev/null +++ b/core/src/com/cloud/hypervisor/kvm/resource/KvmDummyResourceBase.java @@ -0,0 +1,70 @@ +package com.cloud.hypervisor.kvm.resource; + +import java.util.HashMap; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.PingCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.host.Host.Type; +import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.xen.resource.CitrixResourceBase; +import com.cloud.resource.ServerResource; +import com.cloud.resource.ServerResourceBase; +import com.cloud.vm.State; + +public class KvmDummyResourceBase extends ServerResourceBase implements ServerResource { + private String _zoneId; + private String _podId; + private String _guid; + private String _agentIp; + @Override + public Type getType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public StartupCommand[] initialize() { + StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.Type.KVM, new HashMap(), new HashMap()); + cmd.setDataCenter(_zoneId); + cmd.setPod(_podId); + cmd.setGuid(_guid); + cmd.setName(_agentIp); + cmd.setPrivateIpAddress(_agentIp); + cmd.setStorageIpAddress(_agentIp); + cmd.setVersion(KvmDummyResourceBase.class.getPackage().getImplementationVersion()); + return new StartupCommand[] { cmd }; + } + + @Override + public PingCommand getCurrentStatus(long id) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Answer executeRequest(Command cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + protected String getDefaultScriptsDir() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean configure(final String name, final Map params) throws ConfigurationException { + _zoneId = (String)params.get("zone"); + _podId = (String)params.get("pod"); + _guid = (String)params.get("guid"); + _agentIp = (String)params.get("agentIp"); + return true; + } +} diff --git a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 0df9c7df36c..ea44e249591 100644 --- a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -23,7 +23,7 @@ import com.cloud.resource.ServerResource; import com.cloud.storage.resource.StoragePoolResource; public class VmwareResource implements StoragePoolResource, ServerResource { - + private boolean _isRemoteAgent = false; @Override public DownloadAnswer execute(PrimaryStorageDownloadCommand cmd) { // TODO Auto-generated method stub @@ -119,4 +119,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource { // TODO Auto-generated method stub return false; } + + public boolean IsRemoteAgent() { + return _isRemoteAgent; + } + + public void setRemoteAgent(boolean remote) { + _isRemoteAgent = remote; + } } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 6503da76def..cf0a7932969 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -224,6 +224,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected String _guestNetworkName; protected int _wait; protected IAgentControl _agentControl; + protected boolean _isRemoteAgent = false; protected final XenServerHost _host = new XenServerHost(); @@ -764,7 +765,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR Map hostMap = Host.getAllRecords(conn); if (hostMap.size() == 1) { s_logger.debug("There's no one to take over as master"); - return new MaintainAnswer(cmd, "Only master in the pool"); + return new MaintainAnswer(cmd,false, "Only master in the pool"); } Host newMaster = null; Host.Record newMasterRecord = null; @@ -1324,7 +1325,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR if (param.contains("cpu")) { vmStatsAnswer.setNumCPUs(vmStatsAnswer.getNumCPUs() + 1); - vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows)); + vmStatsAnswer.setCPUUtilization((vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows))*100); } else if (param.equals("vif_0_rx")) { vmStatsAnswer.setNetworkReadKBs(getDataAverage(dataNode, col, numRows)); } else if (param.equals("vif_0_tx")) { @@ -5797,15 +5798,17 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR if (checkSR(sr)) { return sr; } + throw new CloudRuntimeException("Check this SR failed"); + } else { + + if (pool.getPoolType() == StoragePoolType.NetworkFilesystem) + return getNfsSR(pool); + else if (pool.getPoolType() == StoragePoolType.IscsiLUN) + return getIscsiSR(conn, pool); + else + throw new CloudRuntimeException("The pool type: " + pool.getPoolType().name() + " is not supported."); } - if (pool.getPoolType() == StoragePoolType.NetworkFilesystem) - return getNfsSR(pool); - else if (pool.getPoolType() == StoragePoolType.IscsiLUN) - return getIscsiSR(conn, pool); - else - throw new CloudRuntimeException("The pool type: " + pool.getPoolType().name() + " is not supported."); - } protected Answer execute(final CheckConsoleProxyLoadCommand cmd) { @@ -6073,6 +6076,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR _agentControl = agentControl; } + public boolean IsRemoteAgent() { + return _isRemoteAgent; + } + + public void setRemoteAgent(boolean remote) { + _isRemoteAgent = remote; + } protected Answer execute(PoolEjectCommand cmd) { diff --git a/core/src/com/cloud/resource/ServerResource.java b/core/src/com/cloud/resource/ServerResource.java index b056a478016..75a37155361 100755 --- a/core/src/com/cloud/resource/ServerResource.java +++ b/core/src/com/cloud/resource/ServerResource.java @@ -71,4 +71,8 @@ public interface ServerResource extends Manager { public IAgentControl getAgentControl(); public void setAgentControl(IAgentControl agentControl); + + public boolean IsRemoteAgent(); + + public void setRemoteAgent(boolean remote); } diff --git a/core/src/com/cloud/resource/ServerResourceBase.java b/core/src/com/cloud/resource/ServerResourceBase.java index c10da164984..a60849c0772 100755 --- a/core/src/com/cloud/resource/ServerResourceBase.java +++ b/core/src/com/cloud/resource/ServerResourceBase.java @@ -48,6 +48,7 @@ public abstract class ServerResourceBase implements ServerResource { protected NetworkInterface _storageNic; protected NetworkInterface _storageNic2; protected IAgentControl _agentControl; + protected boolean _isRemoteAgent = false; @Override public String getName() { @@ -301,4 +302,12 @@ public abstract class ServerResourceBase implements ServerResource { public boolean stop() { return true; } + + public boolean IsRemoteAgent() { + return _isRemoteAgent; + } + + public void setRemoteAgent(boolean remote) { + _isRemoteAgent = remote; + } } diff --git a/core/src/com/cloud/server/ManagementServer.java b/core/src/com/cloud/server/ManagementServer.java index a78e68ef140..be62fb62109 100644 --- a/core/src/com/cloud/server/ManagementServer.java +++ b/core/src/com/cloud/server/ManagementServer.java @@ -72,6 +72,7 @@ import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotScheduleVO; import com.cloud.storage.SnapshotVO; +import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.StorageStats; import com.cloud.storage.VMTemplateHostVO; @@ -2184,4 +2185,7 @@ public interface ManagementServer { boolean addConfig(String instance, String component, String category, String name, String value, String description); boolean validateCustomVolumeSizeRange(long size) throws InvalidParameterValueException; + + boolean checkIfMaintenable(long hostId); + } diff --git a/core/src/com/cloud/storage/template/VhdProcessor.java b/core/src/com/cloud/storage/template/VhdProcessor.java index 36ec0bf6ef8..6ed4752903a 100644 --- a/core/src/com/cloud/storage/template/VhdProcessor.java +++ b/core/src/com/cloud/storage/template/VhdProcessor.java @@ -47,7 +47,7 @@ public class VhdProcessor implements Processor { private int vhd_footer_creator_app_offset = 28; private int vhd_footer_creator_ver_offset = 32; private int vhd_footer_current_size_offset = 48; - private byte[] citrix_creator_app = {0x74, 0x61, 0x70, 0x00}; /*"tap "*/ + private byte[][] citrix_creator_app = {{0x74, 0x61, 0x70, 0x00},{0x43, 0x54, 0x58, 0x53}}; /*"tap ", and "CTXS"*/ @Override public FormatInfo process(String templatePath, ImageFormat format, String templateName) throws InternalErrorException { @@ -91,10 +91,7 @@ public class VhdProcessor implements Processor { } } - if (!Arrays.equals(creatorApp, citrix_creator_app)) { - /*Only support VHD image created by citrix xenserver*/ - throw new InternalErrorException("Image creator is:" + creatorApp.toString() +", is not supported"); - } + //imageSignatureCheck(creatorApp); long templateSize = NumbersUtil.bytesToLong(currentSize); info.virtualSize = templateSize; @@ -127,4 +124,22 @@ public class VhdProcessor implements Processor { public boolean stop() { return true; } + + private void imageSignatureCheck(byte[] creatorApp) throws InternalErrorException { + boolean findKnownCreator = false; + for (int i = 0; i < citrix_creator_app.length; i++) { + if (Arrays.equals(creatorApp, citrix_creator_app[i])) { + findKnownCreator = true; + break; + } + } + if (!findKnownCreator) { + /*Only support VHD image created by citrix xenserver, and xenconverter*/ + String readableCreator = ""; + for (int j = 0; j < creatorApp.length; j++) { + readableCreator += (char)creatorApp[j]; + } + throw new InternalErrorException("Image creator is:" + readableCreator +", is not supported"); + } + } } diff --git a/core/test/com/cloud/vmware/TestVMWare.java b/core/test/com/cloud/vmware/TestVMWare.java index 1c7f4aa633b..3ac7c5e06de 100644 --- a/core/test/com/cloud/vmware/TestVMWare.java +++ b/core/test/com/cloud/vmware/TestVMWare.java @@ -10,22 +10,34 @@ import java.util.Map; import org.apache.log4j.xml.DOMConfigurator; import com.cloud.utils.PropertiesUtil; -import com.vmware.apputils.AppUtil; -import com.vmware.vim.ArrayOfManagedObjectReference; -import com.vmware.vim.DatastoreInfo; -import com.vmware.vim.DynamicProperty; -import com.vmware.vim.InvalidProperty; -import com.vmware.vim.ManagedObjectReference; -import com.vmware.vim.ObjectContent; -import com.vmware.vim.ObjectSpec; -import com.vmware.vim.PropertyFilterSpec; -import com.vmware.vim.PropertySpec; -import com.vmware.vim.RuntimeFault; -import com.vmware.vim.SelectionSpec; -import com.vmware.vim.TraversalSpec; +import com.vmware.apputils.version.ExtendedAppUtil; +import com.vmware.vim25.HostIpConfig; +import com.vmware.vim25.HostVirtualNicSpec; +import com.vmware.vim25.HostConfigManager; +import com.vmware.vim25.HostPortGroupSpec; +import com.vmware.vim25.VirtualMachineConfigSpec; +import com.vmware.vim25.VirtualDeviceConfigSpecOperation; +import com.vmware.vim25.VirtualEthernetCard; +import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo; +import com.vmware.vim25.VirtualPCNet32; +import com.vmware.vim25.VirtualDeviceConfigSpec; +import com.vmware.vim25.VirtualMachineCloneSpec; +import com.vmware.vim25.VirtualMachineRelocateSpec; +import com.vmware.vim25.ArrayOfManagedObjectReference; +import com.vmware.vim25.DatastoreInfo; +import com.vmware.vim25.DynamicProperty; +import com.vmware.vim25.InvalidProperty; +import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.ObjectContent; +import com.vmware.vim25.ObjectSpec; +import com.vmware.vim25.PropertyFilterSpec; +import com.vmware.vim25.PropertySpec; +import com.vmware.vim25.RuntimeFault; +import com.vmware.vim25.SelectionSpec; +import com.vmware.vim25.TraversalSpec; public class TestVMWare { - private static AppUtil cb; + private static ExtendedAppUtil cb; private static void setupLog4j() { File file = PropertiesUtil.findConfigFile("log4j-cloud.xml"); @@ -98,7 +110,7 @@ public class TestVMWare { PropertyFilterSpec spec = new PropertyFilterSpec(); spec.setPropSet(propspecary); spec.setObjectSet(new ObjectSpec[] { new ObjectSpec() }); - spec.getObjectSet(0).setObj(cb.getConnection().getRootFolder()); + spec.getObjectSet(0).setObj(cb.getServiceConnection3().getRootFolder()); spec.getObjectSet(0).setSkip(new Boolean(false)); spec.getObjectSet(0).setSelectSet( new SelectionSpec[] { folderTraversalSpec }); @@ -106,8 +118,8 @@ public class TestVMWare { // Recursively get all ManagedEntity ManagedObjectReferences // and the "name" property for all ManagedEntities retrieved ObjectContent[] ocary = - cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { spec } ); @@ -253,15 +265,15 @@ public class TestVMWare { PropertyFilterSpec filterSpec = new PropertyFilterSpec(); filterSpec.setPropSet(propSpecs); filterSpec.setObjectSet(new ObjectSpec[] { new ObjectSpec() }); - filterSpec.getObjectSet(0).setObj(cb.getConnection().getRootFolder()); + filterSpec.getObjectSet(0).setObj(cb.getServiceConnection3().getRootFolder()); filterSpec.getObjectSet(0).setSkip(new Boolean(false)); filterSpec.getObjectSet(0).setSelectSet( new SelectionSpec[] { folderTraversalSpec } ); try { - ObjectContent[] objContent = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] objContent = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { filterSpec } ); printContent(objContent); @@ -293,7 +305,7 @@ public class TestVMWare { pSpec.setPathSet(new String[] { "name"} ); ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(cb.getConnection().getRootFolder()); + oSpec.setObj(cb.getServiceConnection3().getRootFolder()); oSpec.setSkip(Boolean.TRUE); oSpec.setSelectSet(new SelectionSpec[] { getFolderRecursiveTraversalSpec() }); @@ -301,8 +313,8 @@ public class TestVMWare { pfSpec.setPropSet(new PropertySpec[] { pSpec }); pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - ObjectContent[] ocs = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { pfSpec }); if(ocs != null) { @@ -336,8 +348,8 @@ public class TestVMWare { pfSpec.setPropSet(new PropertySpec[] { pSpec }); pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - ObjectContent[] ocs = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { pfSpec }); if(ocs != null) { @@ -380,8 +392,8 @@ public class TestVMWare { pfSpec.setPropSet(new PropertySpec[] { pSpec }); pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - ObjectContent[] ocs = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { pfSpec }); if(ocs != null) { @@ -416,8 +428,8 @@ public class TestVMWare { pfSpec.setPropSet(new PropertySpec[] { pSpec }); pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - ObjectContent[] ocs = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { pfSpec }); if(ocs != null) { @@ -461,8 +473,8 @@ public class TestVMWare { pfSpec.setPropSet(new PropertySpec[] { pSpec }); pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - ObjectContent[] ocs = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { pfSpec }); if(ocs != null) { @@ -495,7 +507,7 @@ public class TestVMWare { folder2childEntity.setSelectSet(new SelectionSpec[] { recurseFolders }); ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(cb.getConnection().getRootFolder()); + oSpec.setObj(cb.getServiceConnection3().getRootFolder()); oSpec.setSkip(Boolean.TRUE); oSpec.setSelectSet(new SelectionSpec[] { folder2childEntity }); @@ -503,8 +515,8 @@ public class TestVMWare { pfSpec.setPropSet(new PropertySpec[] { pSpec }); pfSpec.setObjectSet(new ObjectSpec[] { oSpec }); - return cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + return cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] { pfSpec }); } @@ -556,8 +568,8 @@ public class TestVMWare { pfSpec.setPropSet(new PropertySpec[] {pSpec} ); pfSpec.setObjectSet(new ObjectSpec[] {oSpec} ); - ObjectContent[] ocs = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] {pfSpec} ); if(ocs != null) { @@ -584,8 +596,8 @@ public class TestVMWare { PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.setPropSet(new PropertySpec[] {pSpec} ); pfSpec.setObjectSet(new ObjectSpec[] {oSpec} ); - ObjectContent[] ocs = cb.getConnection().getService().retrieveProperties( - cb.getConnection().getServiceContent().getPropertyCollector(), + ObjectContent[] ocs = cb.getServiceConnection3().getService().retrieveProperties( + cb.getServiceConnection3().getServiceContent().getPropertyCollector(), new PropertyFilterSpec[] {pfSpec} ); Object[] ret = new Object[properties.length]; @@ -613,7 +625,7 @@ public class TestVMWare { morVm.setType("VirtualMachine"); morVm.set_value("vm-66"); - cb.getConnection().getService().powerOnVM_Task(morVm, null); + cb.getServiceConnection3().getService().powerOnVM_Task(morVm, null); } private void powerOffVm() throws Exception { @@ -621,7 +633,149 @@ public class TestVMWare { morVm.setType("VirtualMachine"); morVm.set_value("vm-66"); - cb.getConnection().getService().powerOffVM_Task(morVm); + cb.getServiceConnection3().getService().powerOffVM_Task(morVm); + } + + private void createSnapshot() throws Exception { + ManagedObjectReference morVm = new ManagedObjectReference(); + morVm.setType("VirtualMachine"); + morVm.set_value("vm-66"); + cb.getServiceConnection3().getService().createSnapshot_Task(morVm, "RunningSnapshotProg", "", false, false); + } + + private void registerTemplate() throws Exception { + ManagedObjectReference morFolder = new ManagedObjectReference(); + morFolder.setType("Folder"); + morFolder.set_value("group-v3"); + + ManagedObjectReference morHost = new ManagedObjectReference(); + morHost.setType("HostSystem"); + morHost.set_value("host-48"); + + System.out.println("Begin registerVM_Task"); + ManagedObjectReference taskmor = cb.getServiceConnection3().getService().registerVM_Task( + morFolder, "[NFS datastore] Template-Fedora/Template-Fedora.vmtx", "Template-Fedora", true, + null, morHost); + System.out.println("End registerVM_Task"); + + String result = cb.getServiceUtil3().waitForTask(taskmor); + if (result.equalsIgnoreCase("Sucess")) { + System.out.println("Registering The Virtual Machine ..........Done"); + } else { + System.out.println("Some Exception While Registering The VM"); + } + } + + private void createVmFromTemplate() throws Exception { + VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec(); + + ManagedObjectReference morDatastore = new ManagedObjectReference(); + morDatastore.setType("Datastore"); + morDatastore.set_value("datastore-30"); + + ManagedObjectReference morHost = new ManagedObjectReference(); + morHost.setType("HostSystem"); + morHost.set_value("host-48"); + + ManagedObjectReference morPool = new ManagedObjectReference(); + morPool.setType("ResourcePool"); + morPool.set_value("resgroup-41"); + + VirtualMachineRelocateSpec relocSpec = new VirtualMachineRelocateSpec(); + cloneSpec.setLocation(relocSpec); + cloneSpec.setPowerOn(false); + cloneSpec.setTemplate(false); + + relocSpec.setDatastore(morDatastore); + relocSpec.setHost(morHost); + relocSpec.setPool(morPool); + + ManagedObjectReference morTemplate = new ManagedObjectReference(); + morTemplate.setType("VirtualMachine"); + morTemplate.set_value("vm-76"); + + ManagedObjectReference morFolder = new ManagedObjectReference(); + morFolder.setType("Folder"); + morFolder.set_value("group-v3"); + + ManagedObjectReference cloneTask + = cb.getServiceConnection3().getService().cloneVM_Task(morTemplate, morFolder, + "Fedora-clone-test", cloneSpec); + + String status = cb.getServiceUtil3().waitForTask(cloneTask); + if(status.equalsIgnoreCase("failure")) { + System.out.println("Failure -: Virtual Machine cannot be cloned"); + } + + if(status.equalsIgnoreCase("sucess")) { + System.out.println("Virtual Machine Cloned successfully."); + } + } + + private void addNic() throws Exception { + ManagedObjectReference morVm = new ManagedObjectReference(); + morVm.setType("VirtualMachine"); + morVm.set_value("vm-77"); + + ManagedObjectReference morNetwork = new ManagedObjectReference(); + morNetwork.setType("DistributedVirtualPortgroup"); + morNetwork.set_value("dvportgroup-56"); + + VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec(); + nicSpec.setOperation(VirtualDeviceConfigSpecOperation.add); + VirtualEthernetCard nic = new VirtualPCNet32(); + VirtualEthernetCardNetworkBackingInfo nicBacking + = new VirtualEthernetCardNetworkBackingInfo(); + nicBacking.setDeviceName("Adapter to dSwitch-vlan26"); + nicBacking.setNetwork(morNetwork); + + nic.setAddressType("generated"); + nic.setBacking(nicBacking); + nic.setKey(4); + nicSpec.setDevice(nic); + + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); + VirtualDeviceConfigSpec [] nicSpecArray = {nicSpec}; + vmConfigSpec.setDeviceChange(nicSpecArray); + + ManagedObjectReference tmor + = cb.getServiceConnection3().getService().reconfigVM_Task( + morVm, vmConfigSpec); + + String status = cb.getServiceUtil3().waitForTask(tmor); + if(status.equalsIgnoreCase("failure")) { + System.out.println("Failure -: Virtual Machine cannot be cloned"); + } + + if(status.equalsIgnoreCase("sucess")) { + System.out.println("Virtual Machine Cloned successfully."); + } + } + + // add virtual NIC to vmkernel + private void addNicToNetwork() throws Exception { + ManagedObjectReference morHost = new ManagedObjectReference(); + morHost.setType("HostSystem"); + morHost.set_value("host-48"); + + HostPortGroupSpec portgrp = new HostPortGroupSpec(); + portgrp.setName("VM Network vlan26"); + + Object cmobj = cb.getServiceUtil3().getDynamicProperty(morHost, "configManager"); + HostConfigManager configMgr = (HostConfigManager)cmobj; + ManagedObjectReference nwSystem = configMgr.getNetworkSystem(); + + HostVirtualNicSpec vNicSpec = new HostVirtualNicSpec(); + HostIpConfig ipConfig = new HostIpConfig(); + ipConfig.setDhcp(false); + ipConfig.setIpAddress("192.168.26.177"); + ipConfig.setSubnetMask("255.255.255.0"); + + vNicSpec.setIp(ipConfig); + vNicSpec.setPortgroup("VM Network vlan26"); + + cb.getServiceConnection3().getService().addVirtualNic(nwSystem, + "dvPortGroup-vlan26", vNicSpec); } public static void main(String[] args) throws Exception { @@ -631,21 +785,26 @@ public class TestVMWare { // skip certificate check System.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory"); - String serviceUrl = "https://vsphere-1.lab.vmops.com/sdk/vimService"; + String serviceUrl = "https://" + args[0] + "/sdk/vimService"; + try { - String[] params = new String[] {"--url", serviceUrl, "--username", "Administrator", "--password", "Suite219" }; + String[] params = new String[] {"--url", serviceUrl, "--username", args[1], "--password", args[2] }; - cb = AppUtil.initialize("Connect", params); + cb = ExtendedAppUtil.initialize("Connect", params); cb.connect(); System.out.println("Connection Succesful."); // client.listInventoryFolders(); // client.listDataCenters(); - client.powerOnVm(); - + // client.powerOnVm(); + // client.createSnapshot(); + // client.registerTemplate(); + // client.createVmFromTemplate(); + client.addNic(); + // client.addNicToNetwork(); cb.disConnect(); } catch (Exception e) { - System.out.println("Failed to connect to " + serviceUrl); + e.printStackTrace(); } } } diff --git a/python/lib/cloud_utils.py b/python/lib/cloud_utils.py index f638c55f6f8..1434372d548 100644 --- a/python/lib/cloud_utils.py +++ b/python/lib/cloud_utils.py @@ -45,9 +45,11 @@ elif os.path.exists("/etc/redhat-release") and not os.path.exists("/etc/fedora-r elif os.path.exists("/etc/legal") and "Ubuntu" in file("/etc/legal").read(-1): distro = Ubuntu else: distro = Unknown - +logFileName=None # ================== LIBRARY UTILITY CODE============= - +def setLogFile(logFile): + global logFileName + logFileName=logFile def read_properties(propfile): if not hasattr(propfile,"read"): propfile = file(propfile) properties = propfile.read().splitlines() @@ -63,9 +65,10 @@ def read_properties(propfile): def stderr(msgfmt,*args): """Print a message to stderr, optionally interpolating the arguments into it""" msgfmt += "\n" + if logFileName != None: + sys.stderr = open(logFileName, 'a+') if args: sys.stderr.write(msgfmt%args) else: sys.stderr.write(msgfmt) - sys.stderr.flush() def exit(errno=E_GENERIC,message=None,*args): """Exit with an error status code, printing a message to stderr if specified""" @@ -907,7 +910,7 @@ def prompt_for_hostpods(zonespods): # this configures the agent -def setup_agent_config(configfile, host, zone, pod): +def setup_agent_config(configfile, host, zone, pod, guid): stderr("Examining Agent configuration") fn = configfile text = file(fn).read(-1) @@ -915,9 +918,12 @@ def setup_agent_config(configfile, host, zone, pod): confopts = dict([ m.split("=",1) for m in lines if "=" in m and not m.startswith("#") ]) confposes = dict([ (m.split("=",1)[0],n) for n,m in enumerate(lines) if "=" in m and not m.startswith("#") ]) - if not "guid" in confopts: - stderr("Generating GUID for this Agent") - confopts['guid'] = uuidgen().stdout.strip() + if guid != None: + confopts['guid'] = guid + else: + if not "guid" in confopts: + stderr("Generating GUID for this Agent") + confopts['guid'] = uuidgen().stdout.strip() if host == None: try: host = confopts["host"] @@ -939,11 +945,11 @@ def setup_agent_config(configfile, host, zone, pod): stderr("You selected zone %s pod %s",confopts["zone"],confopts["pod"]) else: stderr("Skipped -- using the previous zone %s pod %s",confopts["zone"],confopts["pod"]) - else: + else: confopts["zone"] = zone confopts["pod"] = pod except (urllib2.URLError,urllib2.HTTPError),e: - stderr("Query failed: %s. Defaulting to zone %s pod %s",confopts["zone"],confopts["pod"]) + stderr("Query failed: %s. Defaulting to zone %s pod %s",str(e),confopts["zone"],confopts["pod"]) for opt,val in confopts.items(): line = "=".join([opt,val]) @@ -988,7 +994,7 @@ def setup_consoleproxy_config(configfile, host, zone, pod): confopts["zone"] = zone confopts["pod"] = pod except (urllib2.URLError,urllib2.HTTPError),e: - stderr("Query failed: %s. Defaulting to zone %s pod %s",e,confopts["zone"],confopts["pod"]) + stderr("Query failed: %s. Defaulting to zone %s pod %s",str(e),confopts["zone"],confopts["pod"]) for opt,val in confopts.items(): line = "=".join([opt,val]) diff --git a/scripts/vm/hypervisor/kvm/setup_agent.sh b/scripts/vm/hypervisor/kvm/setup_agent.sh index 5302e8f71f8..7697aaa0d0b 100755 --- a/scripts/vm/hypervisor/kvm/setup_agent.sh +++ b/scripts/vm/hypervisor/kvm/setup_agent.sh @@ -1,6 +1,6 @@ #! /bin/bash # Did cloud-agent installed -set -x +#set -x install_cloud_agent() { local dev=$1 local retry=10 @@ -126,6 +126,7 @@ cloud_agent_setup() { local host=$1 local zone=$2 local pod=$3 + local guid=$4 # disable selinux selenabled=`cat /selinux/enforce` if [ "$selenabled" == "1" ] @@ -133,21 +134,22 @@ cloud_agent_setup() { sed -i 's/\(SELINUX\)\(.*\)/\1=permissive/' /etc/selinux/config setenforce 0 fi - cloud-setup-agent --host=$host --zone=$zone --pod=$pod -a + cloud-setup-agent --host=$host --zone=$zone --pod=$pod --guid=$guid -a > /dev/null } cloud_consoleP_setup() { local host=$1 local zone=$2 local pod=$3 - cloud-setup-console-proxy --host=$host --zone=$zone --pod=$pod + cloud-setup-console-proxy --host=$host --zone=$zone --pod=$pod -a > /dev/null } host= zone= pod= +guid= dflag= -while getopts 'h:z:p:d' OPTION +while getopts 'h:z:p:u:d' OPTION do case $OPTION in h) @@ -159,6 +161,9 @@ do p) pod="$OPTARG" ;; + u) + guid="$OPTARG" + ;; d) dflag=1 ;; @@ -166,7 +171,7 @@ do esac done -install_cloud_agent $dflag -install_cloud_consoleP $dflag -cloud_agent_setup $host $zone $pod +#install_cloud_agent $dflag +#install_cloud_consoleP $dflag +cloud_agent_setup $host $zone $pod $guid cloud_consoleP_setup $host $zone $pod diff --git a/server/.classpath b/server/.classpath index 52f2d3852ad..cefa0653a40 100644 --- a/server/.classpath +++ b/server/.classpath @@ -20,5 +20,6 @@ + diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index d360d1ec242..509aef1a3c1 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -100,6 +100,7 @@ import com.cloud.host.Status.Event; import com.cloud.host.dao.DetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase; import com.cloud.maid.StackMaid; import com.cloud.maint.UpgradeManager; import com.cloud.network.IPAddressVO; @@ -461,11 +462,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { if (server == null) { return null; } - + long id = server.getId(); AgentAttache attache = createAttache(id, server, resource); - notifyMonitorsOfConnection(attache, startup); + if (!resource.IsRemoteAgent()) + notifyMonitorsOfConnection(attache, startup); return attache; } @@ -1551,7 +1553,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { protected AgentAttache createAttache(long id, HostVO server, ServerResource resource) { s_logger.debug("Adding directly connect host for " + id); - if (resource instanceof DummySecondaryStorageResource) { + if (resource instanceof DummySecondaryStorageResource || resource instanceof KvmDummyResourceBase) { return new DummyAttache(id, false); } final DirectAgentAttache attache = new DirectAgentAttache(id, resource, server.getStatus() == Status.Maintenance diff --git a/server/src/com/cloud/api/commands/AddConfigCmd.java b/server/src/com/cloud/api/commands/AddConfigCmd.java index 00ce03536ae..528333def1b 100644 --- a/server/src/com/cloud/api/commands/AddConfigCmd.java +++ b/server/src/com/cloud/api/commands/AddConfigCmd.java @@ -17,7 +17,6 @@ */ package com.cloud.api.commands; - import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/server/src/com/cloud/api/commands/ListAlertsCmd.java b/server/src/com/cloud/api/commands/ListAlertsCmd.java index fb72fa06012..cf95167b0d7 100644 --- a/server/src/com/cloud/api/commands/ListAlertsCmd.java +++ b/server/src/com/cloud/api/commands/ListAlertsCmd.java @@ -91,7 +91,7 @@ public class ListAlertsCmd extends BaseCmd{ List> alertData = new ArrayList>(); alertData.add(new Pair(BaseCmd.Properties.TYPE.getName(), alert.getType())); alertData.add(new Pair(BaseCmd.Properties.DESCRIPTION.getName(), alert.getSubject())); - alertData.add(new Pair(BaseCmd.Properties.SENT.getName(), alert.getLastSent())); + alertData.add(new Pair(BaseCmd.Properties.SENT.getName(), getDateString(alert.getLastSent()))); aTag[i++] = alertData; } diff --git a/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java b/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java index 951997b54a1..02bee1543de 100644 --- a/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java +++ b/server/src/com/cloud/api/commands/PrepareForMaintenanceCmd.java @@ -28,6 +28,7 @@ import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.HostVO; +import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.Pair; public class PrepareForMaintenanceCmd extends BaseCmd { @@ -62,6 +63,15 @@ public class PrepareForMaintenanceCmd extends BaseCmd { throw new ServerApiException(BaseCmd.PARAM_ERROR, "Host with id " + hostId.toString() + " doesn't exist"); } + //if this is the only host in the pool, you cannot enable maintenance on this host + boolean maintenable = getManagementServer().checkIfMaintenable(host.getId()); + + if(!maintenable) + { + s_logger.warn("Unable to schedule host maintenance -- there is no host to take over as master in the pool"); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Unable to schedule host maintenance -- there is no host to take over as master in the pool"); + } + long jobId = 0; try { jobId = getManagementServer().prepareForMaintenanceAsync(hostId); @@ -70,7 +80,7 @@ public class PrepareForMaintenanceCmd extends BaseCmd { } if(jobId == 0) { - s_logger.warn("Unable to schedule async-job for PrepareForMaintenance comamnd"); + s_logger.warn("Unable to schedule async-job for PrepareForMaintenance command"); } else { if(s_logger.isDebugEnabled()) s_logger.debug("PrepareForMaintenance command has been accepted, job id: " + jobId); diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java index b16b57a85b4..19c1aea8bee 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java @@ -1,8 +1,16 @@ package com.cloud.hypervisor.kvm.discoverer; +import java.net.InetAddress; import java.net.URI; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -10,16 +18,32 @@ import com.cloud.agent.api.AgentControlCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.DiscoveryException; import com.cloud.host.HostVO; import com.cloud.host.Status; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase; +import com.cloud.hypervisor.xen.resource.CitrixResourceBase; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; import com.cloud.resource.ServerResource; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.component.Inject; +import com.cloud.utils.script.Script; +import com.trilead.ssh2.SCPClient; +import com.trilead.ssh2.Session; +@Local(value=Discoverer.class) public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, Listener { - + private static final Logger s_logger = Logger.getLogger(KvmServerDiscoverer.class); + private String _setupAgentPath; + private ConfigurationDao _configDao; + private String _hostIp; + private int _waitTime = 10; + @Inject HostDao _hostDao = null; + @Override public boolean processAnswer(long agentId, long seq, Answer[] answers) { // TODO Auto-generated method stub @@ -73,14 +97,101 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, public Map> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password) throws DiscoveryException { - // TODO Auto-generated method stub + Map> resources = new HashMap>(); + Map details = new HashMap(); + if (!uri.getScheme().equals("http")) { + String msg = "urlString is not http so we're not taking care of the discovery for this: " + uri; + s_logger.debug(msg); + return null; + } + com.trilead.ssh2.Connection sshConnection = null; + Session sshSession = null; + String agentIp = null; + try { + + String hostname = uri.getHost(); + InetAddress ia = InetAddress.getByName(hostname); + agentIp = ia.getHostAddress(); + String guid = UUID.nameUUIDFromBytes(agentIp.getBytes()).toString(); + sshConnection = new com.trilead.ssh2.Connection(agentIp, 22); + + sshConnection.connect(null, 60000, 60000); + if (!sshConnection.authenticateWithPassword(username, password)) { + throw new Exception("Unable to authenticate"); + } + SCPClient scp = new SCPClient(sshConnection); + scp.put(_setupAgentPath, "/usr/bin", "0755"); + sshSession = sshConnection.openSession(); + /*running setup script in background, because we will restart agent network, that may cause connection lost*/ + s_logger.debug("/usr/bin/setup_agent.sh " + " -h " + _hostIp + " -z " + dcId + " -p " + podId + " -u " + guid); + sshSession.execCommand("/usr/bin/setup_agent.sh " + " -h " + _hostIp + " -z " + dcId + " -p " + podId + " -u " + guid + " 1>&2" ); + + KvmDummyResourceBase kvmResource = new KvmDummyResourceBase(); + Map params = new HashMap(); + + params.put("zone", Long.toString(dcId)); + params.put("pod", Long.toString(podId)); + params.put("guid", guid); + params.put("agentIp", agentIp); + kvmResource.configure("kvm agent", params); + kvmResource.setRemoteAgent(true); + resources.put(kvmResource, details); + return resources; + } catch (Exception e) { + String msg = " can't setup agent, due to " + e.toString() + " - " + e.getMessage(); + s_logger.warn(msg); + } finally { + if (sshSession != null) + sshSession.close(); + + if (sshConnection != null) + sshConnection.close(); + } + return null; } @Override - public void postDiscovery(List hosts, long msId) { - // TODO Auto-generated method stub + public void postDiscovery(List hosts, long msId) throws DiscoveryException { + /*Wait for agent coming back*/ + if (hosts.isEmpty()) { + return; + } + HostVO host = hosts.get(0); + for (int i = 0 ; i < _waitTime; i++) { + + if (host.getStatus() != Status.Up) { + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + s_logger.debug("Failed to sleep: " + e.toString()); + } + } else { + return; + } + } + /*Timeout, throw warning msg to user*/ + throw new DiscoveryException("Agent " + host.getId() + ":" + host.getPublicIpAddress() + " does not come back, It may connect to server later, if not, please check the agent log"); } - + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + _configDao = locator.getDao(ConfigurationDao.class); + _setupAgentPath = Script.findScript(getPatchPath(), "setup_agent.sh"); + + if (_setupAgentPath == null) { + throw new ConfigurationException("Can't find setup_agent.sh"); + } + _hostIp = _configDao.getValue("host"); + if (_hostIp == null) { + throw new ConfigurationException("Can't get host IP"); + } + return true; + } + + protected String getPatchPath() { + return "scripts/vm/hypervisor/kvm/"; + } } diff --git a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index ecdf216f5df..8b0e7bd280f 100644 --- a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -450,7 +450,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } @Override - public void postDiscovery(List hosts, long msId) { + public void postDiscovery(List hosts, long msId) throws DiscoveryException{ //do nothing } diff --git a/server/src/com/cloud/resource/Discoverer.java b/server/src/com/cloud/resource/Discoverer.java index 1d82d9701f9..a162a417afd 100644 --- a/server/src/com/cloud/resource/Discoverer.java +++ b/server/src/com/cloud/resource/Discoverer.java @@ -40,5 +40,5 @@ public interface Discoverer extends Adapter { */ Map> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password) throws DiscoveryException; - void postDiscovery(List hosts, long msId); + void postDiscovery(List hosts, long msId) throws DiscoveryException; } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java old mode 100755 new mode 100644 index 6f8312c6534..25c49f3ba68 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -191,6 +191,7 @@ import com.cloud.storage.SnapshotScheduleVO; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.StorageStats; import com.cloud.storage.VMTemplateHostVO; @@ -210,6 +211,7 @@ import com.cloud.storage.dao.LaunchPermissionDao; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolDao; +import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; @@ -319,6 +321,7 @@ public class ManagementServerImpl implements ManagementServer { private final GuestOSDao _guestOSDao; private final GuestOSCategoryDao _guestOSCategoryDao; private final StoragePoolDao _poolDao; + private final StoragePoolHostDao _poolHostDao; private final StorageManager _storageMgr; private final UserVmDao _vmDao; @@ -415,6 +418,7 @@ public class ManagementServerImpl implements ManagementServer { _guestOSDao = locator.getDao(GuestOSDao.class); _guestOSCategoryDao = locator.getDao(GuestOSCategoryDao.class); _poolDao = locator.getDao(StoragePoolDao.class); + _poolHostDao = locator.getDao(StoragePoolHostDao.class); _vmDao = locator.getDao(UserVmDao.class); _configs = _configDao.getConfiguration(); @@ -8544,5 +8548,29 @@ public class ManagementServerImpl implements ManagementServer { return true; } + + @Override + public boolean checkIfMaintenable(long hostId) { + + //get the poolhostref record + List poolHostRecordSet = _poolHostDao.listByHostId(hostId); + + if(poolHostRecordSet!=null) + { + //the above list has only 1 record + StoragePoolHostVO poolHostRecord = poolHostRecordSet.get(0); + + //get the poolId and get hosts associated in that pool + List hostsInPool = _poolHostDao.listByPoolId(poolHostRecord.getPoolId()); + + if(hostsInPool!=null && hostsInPool.size()>1) + { + return true; //since there are other hosts to take over as master in this pool + } + } + return false; + } + + } diff --git a/setup/db/deploy-db-dev.sh b/setup/db/deploy-db-dev.sh index 3e20af62042..fb1b53b6de5 100755 --- a/setup/db/deploy-db-dev.sh +++ b/setup/db/deploy-db-dev.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # deploy-db.sh -- deploys the database configuration. - +# # set -x if [ "$1" == "" ]; then diff --git a/ui/content/tab_hosts.html b/ui/content/tab_hosts.html index f807a8b4e2e..6d4cf09ab66 100644 --- a/ui/content/tab_hosts.html +++ b/ui/content/tab_hosts.html @@ -277,10 +277,10 @@ -
  • +
  • Cluster Options
  • -
  • +
  • diff --git a/ui/index.html b/ui/index.html index 3e318cdf753..cd1ae182aa8 100644 --- a/ui/index.html +++ b/ui/index.html @@ -9,6 +9,7 @@ cloud.com - User Console + diff --git a/ui/jsp/tab_domains.jsp b/ui/jsp/tab_domains.jsp index cf11054c9da..1d258ca1b48 100644 --- a/ui/jsp/tab_domains.jsp +++ b/ui/jsp/tab_domains.jsp @@ -1,9 +1,3 @@ -<%@ page import="java.util.*" %> - -<% - Locale browserLocale = request.getLocale(); - ResourceBundle t = ResourceBundle.getBundle("resources/resource", browserLocale); -%> @@ -75,14 +69,7 @@
    -
    -

    browser locale: <%=browserLocale%>


    - <%=t.getString("computer")%> - <%=t.getString("computer_disk_hahaha")%> - <%=t.getString("disk")%> - <%=t.getString("monitor")%> - <%=t.getString("keyboard")%> -
    + diff --git a/ui/scripts/cloud.core.hosts.js b/ui/scripts/cloud.core.hosts.js index 65423fa6f67..9d32c417c07 100644 --- a/ui/scripts/cloud.core.hosts.js +++ b/ui/scripts/cloud.core.hosts.js @@ -23,73 +23,76 @@ function showHostsTab() { var sIndex = 0; var pIndex = 0; - // Dialog Setup - if (getHypervisorType() != "kvm") { //"xenserver" - $("#host_action_new_routing").show(); - activateDialog($("#dialog_add_routing").dialog({ - autoOpen: false, - modal: true, - zIndex: 2000 - })); - - var dialogAddRouting = $("#dialog_add_routing"); - + // Dialog Setup + $("#host_action_new_routing").show(); + activateDialog($("#dialog_add_routing").dialog({ + autoOpen: false, + modal: true, + zIndex: 2000 + })); + + var dialogAddRouting = $("#dialog_add_routing"); + + //xenserver supports cluster. kvm doesn't support cluster. + if (getHypervisorType() == "kvm") + dialogAddRouting.find("#cluster_options_container, #new_cluster_radio_container, #existing_cluster_radio_container, #no_cluster_radio_container").hide(); + + $.ajax({ + data: createURL("command=listZones&available=true&response=json"+maxPageSize), + dataType: "json", + success: function(json) { + var zones = json.listzonesresponse.zone; + var zoneSelect = dialogAddRouting.find("#host_zone").empty(); + if (zones != null && zones.length > 0) { + for (var i = 0; i < zones.length; i++) + zoneSelect.append(""); + } + //dialogAddRouting.find("#host_zone").change(); + } + }); + + dialogAddRouting.find("#host_zone").bind("change", function(event) { + var zoneId = $(this).val(); $.ajax({ - data: createURL("command=listZones&available=true&response=json"+maxPageSize), + data: createURL("command=listPods&zoneId="+zoneId+"&response=json"+maxPageSize), dataType: "json", + async: false, success: function(json) { - var zones = json.listzonesresponse.zone; - var zoneSelect = dialogAddRouting.find("#host_zone").empty(); - if (zones != null && zones.length > 0) { - for (var i = 0; i < zones.length; i++) - zoneSelect.append(""); + var pods = json.listpodsresponse.pod; + var podSelect = dialogAddRouting.find("#host_pod").empty(); + if (pods != null && pods.length > 0) { + for (var i = 0; i < pods.length; i++) { + podSelect.append(""); + } } - //dialogAddRouting.find("#host_zone").change(); + dialogAddRouting.find("#host_pod").change(); } }); - - dialogAddRouting.find("#host_zone").bind("change", function(event) { - var zoneId = $(this).val(); - $.ajax({ - data: createURL("command=listPods&zoneId="+zoneId+"&response=json"+maxPageSize), - dataType: "json", - async: false, - success: function(json) { - var pods = json.listpodsresponse.pod; - var podSelect = dialogAddRouting.find("#host_pod").empty(); - if (pods != null && pods.length > 0) { - for (var i = 0; i < pods.length; i++) { - podSelect.append(""); - } - } - dialogAddRouting.find("#host_pod").change(); - } - }); - }); - - dialogAddRouting.find("#host_pod").bind("change", function(event) { - var podId = $(this).val(); - if(podId == null || podId.length == 0) - return; - var clusterSelect = dialogAddRouting.find("#cluster_select").empty(); - $.ajax({ - data: createURL("command=listClusters&response=json&podid=" + podId+maxPageSize), - dataType: "json", - success: function(json) { - var items = json.listclustersresponse.cluster; - if(items != null && items.length > 0) { - for(var i=0; i" + items[i].name + ""); - dialogAddRouting.find("input[value=existing_cluster_radio]").attr("checked", true); - } - else { - clusterSelect.append(""); - dialogAddRouting.find("input[value=new_cluster_radio]").attr("checked", true); - } - } - }); - }); - } + }); + + dialogAddRouting.find("#host_pod").bind("change", function(event) { + var podId = $(this).val(); + if(podId == null || podId.length == 0) + return; + var clusterSelect = dialogAddRouting.find("#cluster_select").empty(); + $.ajax({ + data: createURL("command=listClusters&response=json&podid=" + podId+maxPageSize), + dataType: "json", + success: function(json) { + var items = json.listclustersresponse.cluster; + if(items != null && items.length > 0) { + for(var i=0; i" + items[i].name + ""); + dialogAddRouting.find("input[value=existing_cluster_radio]").attr("checked", true); + } + else { + clusterSelect.append(""); + dialogAddRouting.find("input[value=new_cluster_radio]").attr("checked", true); + } + } + }); + }); + activateDialog($("#dialog_update_os").dialog({ autoOpen: false, modal: true, @@ -575,105 +578,106 @@ function showHostsTab() { var submenuContent = $("#submenu_content_routing"); - // Add New Routing Host - if (getHypervisorType() != "kvm") { - $("#host_action_new_routing").bind("click", function(event) { - dialogAddRouting.find("#new_cluster_name").val(""); - dialogAddRouting.find("#host_zone").change(); //refresh cluster dropdown - - dialogAddRouting - .dialog('option', 'buttons', { - "Add": function() { - var dialogBox = $(this); - var clusterRadio = dialogBox.find("input[name=cluster]:checked").val(); + // Add New Routing Host + $("#host_action_new_routing").bind("click", function(event) { + dialogAddRouting.find("#new_cluster_name").val(""); + dialogAddRouting.find("#host_zone").change(); //refresh cluster dropdown + + dialogAddRouting + .dialog('option', 'buttons', { + "Add": function() { + var dialogBox = $(this); + var clusterRadio = dialogBox.find("input[name=cluster]:checked").val(); + + // validate values + var isValid = true; + isValid &= validateString("Host name", dialogBox.find("#host_hostname"), dialogBox.find("#host_hostname_errormsg")); + isValid &= validateString("User name", dialogBox.find("#host_username"), dialogBox.find("#host_username_errormsg")); + isValid &= validateString("Password", dialogBox.find("#host_password"), dialogBox.find("#host_password_errormsg")); + if(clusterRadio == "new_cluster_radio") + isValid &= validateString("Cluster name", dialogBox.find("#new_cluster_name"), dialogBox.find("#new_cluster_name_errormsg")); + if (!isValid) return; - // validate values - var isValid = true; - isValid &= validateString("Host name", dialogBox.find("#host_hostname"), dialogBox.find("#host_hostname_errormsg")); - isValid &= validateString("User name", dialogBox.find("#host_username"), dialogBox.find("#host_username_errormsg")); - isValid &= validateString("Password", dialogBox.find("#host_password"), dialogBox.find("#host_password_errormsg")); - if(clusterRadio == "new_cluster_radio") - isValid &= validateString("Cluster name", dialogBox.find("#new_cluster_name"), dialogBox.find("#new_cluster_name_errormsg")); - if (!isValid) return; - - var array1 = []; - - var zoneId = dialogBox.find("#host_zone").val(); - array1.push("&zoneId="+zoneId); - - var podId = dialogBox.find("#host_pod").val(); - array1.push("&podId="+podId); - - var username = trim(dialogBox.find("#host_username").val()); - array1.push("&username="+encodeURIComponent(username)); - - var password = trim(dialogBox.find("#host_password").val()); - array1.push("&password="+encodeURIComponent(password)); - - if(clusterRadio == "new_cluster_radio") { - var newClusterName = trim(dialogBox.find("#new_cluster_name").val()); - array1.push("&clustername="+encodeURIComponent(newClusterName)); - } - else if(clusterRadio == "existing_cluster_radio") { - var clusterId = dialogBox.find("#cluster_select").val(); - // We will default to no cluster if someone selects Join Cluster with no cluster available. - if (clusterId != '-1') { - array1.push("&clusterid="+clusterId); - } - } - - var hostname = trim(dialogBox.find("#host_hostname").val()); - var url; - if(hostname.indexOf("http://")==-1) - url = "http://" + hostname; - else - url = hostname; - array1.push("&url="+encodeURIComponent(url)); - - var template = $("#routing_template").clone(true); - var loadingImg = template.find(".adding_loading"); - var rowContainer = template.find("#row_container"); - loadingImg.find(".adding_text").text("Adding...."); - loadingImg.show(); - rowContainer.hide(); - submenuContent.find("#grid_content").append(template.fadeIn("slow")); - - dialogBox.dialog("close"); - $.ajax({ - data: createURL("command=addHost&response=json" + array1.join("")), - dataType: "json", - success: function(json) { - var items = json.addhostresponse.host; - routingJSONToTemplate(items[0], template); - loadingImg.hide(); - rowContainer.show(); - changeGridRowsTotal(submenuContent.find("#grid_rows_total"), 1); - - if(items.length > 1) { - for(var i=1; i 1) { + for(var i=1; i