// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.hypervisor.hyperv.resource; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.rmi.RemoteException; import java.util.ArrayList; 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.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortCommand; import com.cloud.agent.api.HostStatsEntry; import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PoolEjectCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.ValidateSnapshotCommand; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.vmware.resource.SshHelper; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; import com.cloud.serializer.GsonHelper; import com.cloud.storage.Volume; import com.cloud.storage.template.TemplateInfo; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine.State; import com.google.gson.Gson; /** * Implementation of resource base class for Hyper-V hypervisor **/ @Local(value={ServerResource.class}) public class HypervResource extends ServerResourceBase implements ServerResource{ private String _dcId; private String _podId; private String _clusterId; private String _guid; private String _name; private static final Logger s_logger = Logger.getLogger(HypervResource.class); private IAgentControl agentControl; private volatile Boolean _wakeUp = false; protected Gson _gson; protected HashMap<String, State> _vms = new HashMap<String, State>(512); protected final int DEFAULT_DOMR_SSHPORT = 3922; public HypervResource() { _gson = GsonHelper.getGsonLogger(); } @Override public Answer executeRequest(Command cmd) { if (cmd instanceof CreateCommand) { return execute((CreateCommand) cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { s_logger.info("SCVMM agent recived command SetPortForwardingRulesCommand"); //return execute((SetPortForwardingRulesCommand) cmd); } else if (cmd instanceof SetStaticNatRulesCommand) { s_logger.info("SCVMM agent recived command SetStaticNatRulesCommand"); //return execute((SetStaticNatRulesCommand) cmd); }else if (cmd instanceof LoadBalancerConfigCommand) { s_logger.info("SCVMM agent recived command SetStaticNatRulesCommand"); //return execute((LoadBalancerConfigCommand) cmd); } else if (cmd instanceof IpAssocCommand) { s_logger.info("SCVMM agent recived command IPAssocCommand"); //return execute((IPAssocCommand) cmd); } else if (cmd instanceof SavePasswordCommand) { s_logger.info("SCVMM agent recived command SavePasswordCommand"); //return execute((SavePasswordCommand) cmd); } else if (cmd instanceof DhcpEntryCommand) { return execute((DhcpEntryCommand) cmd); } else if (cmd instanceof VmDataCommand) { //return execute((VmDataCommand) cmd); } else if (cmd instanceof ReadyCommand) { s_logger.info("SCVMM agent recived ReadyCommand: " + _gson.toJson(cmd)); return new ReadyAnswer((ReadyCommand) cmd); } else if (cmd instanceof GetHostStatsCommand) { return execute((GetHostStatsCommand) cmd); } else if (cmd instanceof GetVmStatsCommand) { s_logger.info("SCVMM agent recived command GetVmStatsCommand"); //return execute((GetVmStatsCommand) cmd); } else if (cmd instanceof CheckHealthCommand) { //return execute((CheckHealthCommand) cmd); } else if (cmd instanceof StopCommand) { //return execute((StopCommand) cmd); } else if (cmd instanceof RebootRouterCommand) { //return execute((RebootRouterCommand) cmd); } else if (cmd instanceof RebootCommand) { //return execute((RebootCommand) cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { s_logger.info("SCVMM agent recived command CheckVirtualMachineCommand"); //return execute((CheckVirtualMachineCommand) cmd); } else if (cmd instanceof PrepareForMigrationCommand) { //return execute((PrepareForMigrationCommand) cmd); } else if (cmd instanceof MigrateCommand) { //return execute((MigrateCommand) cmd); } else if (cmd instanceof DestroyCommand) { //return execute((DestroyCommand) cmd); } else if (cmd instanceof ModifyStoragePoolCommand) { return execute((ModifyStoragePoolCommand) cmd); } else if (cmd instanceof DeleteStoragePoolCommand) { s_logger.info("SCVMM agent recived command DeleteStoragePoolCommand"); Answer answer = new Answer(cmd, true, "success"); return answer; //return execute((DeleteStoragePoolCommand) cmd); } else if (cmd instanceof CopyVolumeCommand) { s_logger.info("SCVMM agent recived command CopyVolumeCommand"); //return execute((CopyVolumeCommand) cmd); } else if (cmd instanceof AttachVolumeCommand) { s_logger.info("SCVMM agent recived command AttachVolumeCommand"); //return execute((AttachVolumeCommand) cmd); } else if (cmd instanceof AttachIsoCommand) { //return execute((AttachIsoCommand) cmd); } else if (cmd instanceof ValidateSnapshotCommand) { //return execute((ValidateSnapshotCommand) cmd); } else if (cmd instanceof ManageSnapshotCommand) { //return execute((ManageSnapshotCommand) cmd); } else if (cmd instanceof BackupSnapshotCommand) { //return execute((BackupSnapshotCommand) cmd); } else if (cmd instanceof CreateVolumeFromSnapshotCommand) { //return execute((CreateVolumeFromSnapshotCommand) cmd); } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { //return execute((CreatePrivateTemplateFromVolumeCommand) cmd); } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { //return execute((CreatePrivateTemplateFromSnapshotCommand) cmd); } else if (cmd instanceof GetStorageStatsCommand) { return execute((GetStorageStatsCommand) cmd); } else if (cmd instanceof PrimaryStorageDownloadCommand) { s_logger.info("SCVMM agent recived command PrimaryStorageDownloadCommand"); return execute((PrimaryStorageDownloadCommand) cmd); } else if (cmd instanceof GetVncPortCommand) { //return execute((GetVncPortCommand) cmd); } else if (cmd instanceof SetupCommand) { //return execute((SetupCommand) cmd); } else if (cmd instanceof MaintainCommand) { //return execute((MaintainCommand) cmd); } else if (cmd instanceof PingTestCommand) { s_logger.info("SCVMM agent recived command PingTestCommand"); //return execute((PingTestCommand) cmd); } else if (cmd instanceof CheckOnHostCommand) { s_logger.info("SCVMM agent recived command CheckOnHostCommand"); //return execute((CheckOnHostCommand) cmd); } else if (cmd instanceof ModifySshKeysCommand) { //return execute((ModifySshKeysCommand) cmd); } else if (cmd instanceof PoolEjectCommand) { //return execute((PoolEjectCommand) cmd); } else if (cmd instanceof NetworkUsageCommand) { //return execute((NetworkUsageCommand) cmd); } else if (cmd instanceof StartCommand) { return execute((StartCommand) cmd); } else if (cmd instanceof RemoteAccessVpnCfgCommand) { //return execute((RemoteAccessVpnCfgCommand) cmd); } else if (cmd instanceof VpnUsersCfgCommand) { //return execute((VpnUsersCfgCommand) cmd); } else if (cmd instanceof CheckSshCommand) { return execute((CheckSshCommand)cmd); } else if (cmd instanceof CheckNetworkCommand) { //return execute((CheckNetworkCommand) cmd); } else { s_logger.info("SCVMM agent recived unimplemented command: " + _gson.toJson(cmd)); return Answer.createUnsupportedCommandAnswer(cmd); } return Answer.createUnsupportedCommandAnswer(cmd); } public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd)); } try { String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); String primaryStroageUrl = cmd.getPrimaryStorageUrl(); String templateUuidName =null; assert ((primaryStroageUrl != null) && (secondaryStorageUrl != null)); // FIXME: paths and system vm name are hard coded String templateUrl = cmd.getUrl(); String templatePath = templateUrl.replace('/', '\\'); templatePath = templatePath.substring(4); if (!templatePath.endsWith(".vhd")) { String templateName = cmd.getName(); templateUuidName = UUID.nameUUIDFromBytes((templateName + "@" + cmd.getPoolUuid()).getBytes()).toString(); if (!templatePath.endsWith("\\")) { templatePath = templatePath + "\\"; } //templatePath = templatePath + templateUuidName + ".vhd"; templatePath = templatePath + "systemvm.vhd"; } s_logger.info("template URL: "+ templateUrl + "template name: "+ cmd.getName() + " sec storage " + secondaryStorageUrl+ " pri storage" + primaryStroageUrl); StringBuilder cmdStr = new StringBuilder("cmd /c powershell.exe "); cmdStr.append("copy-item '"); cmdStr.append(templatePath.toCharArray()); cmdStr.append("' 'C:\\programdata\\Virtual Machine Manager Library Files\\VHDs\\';"); s_logger.info("Running command: " + cmdStr); Process p = Runtime.getRuntime().exec(cmdStr.toString()); p.getOutputStream().close(); InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream())); BufferedReader errreader = new BufferedReader(temperrReader); if (errreader.ready()) { String errorOutput = new String(""); s_logger.info("errors found while running cmdlet: " + cmdStr.toString()); while (true){ String errline = errreader.readLine(); if (errline == null) { break; } errorOutput = errorOutput + errline; } s_logger.info(errorOutput); } p.getErrorStream().close(); InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream())); BufferedReader reader = new BufferedReader(tempReader); String output = new String(""); while (true){ String line = reader.readLine(); if (line == null) { break; } output = output + line; } p.getInputStream().close(); s_logger.info("Command output: "+ output); if (output.contains("FullyQualifiedErrorId") || output.contains("Error") || output.contains("Exception")) { return new PrimaryStorageDownloadAnswer("Failed to copy template to SCVMM library share from secondary storage."); } return new PrimaryStorageDownloadAnswer(templateUuidName, 0); } catch (Exception e) { s_logger.info("Exception caught: "+e.getMessage()); return new PrimaryStorageDownloadAnswer("Failed to copy template to SCVMM library share from secondary storage."); } } protected Answer execute(CreateCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource CreateCommand: " + _gson.toJson(cmd)); } try { long volId = cmd.getVolumeId(); String templateUrl = cmd.getTemplateUrl();; StorageFilerTO pool = cmd.getPool(); DiskProfile diskchar = cmd.getDiskCharacteristics(); if (diskchar.getType() == Volume.Type.ROOT) { if (cmd.getTemplateUrl() == null) { //create root volume VolumeTO vol = new VolumeTO(cmd.getVolumeId(), diskchar.getType(), pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(), pool.getPath(), cmd.getDiskCharacteristics().getName(), cmd.getDiskCharacteristics().getSize(), null); return new CreateAnswer(cmd, vol); } else { VolumeTO vol = new VolumeTO(cmd.getVolumeId(), diskchar.getType(), pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(), pool.getPath(), cmd.getDiskCharacteristics().getName(), cmd.getDiskCharacteristics().getSize(), null); return new CreateAnswer(cmd, vol); } } else { //create data volume String volumeUuid = "cloud.worker." + UUID.randomUUID().toString(); VolumeTO vol = new VolumeTO(cmd.getVolumeId(), diskchar.getType(), pool.getType(), pool.getUuid(), cmd.getDiskCharacteristics().getName(), pool.getPath(), volumeUuid, cmd.getDiskCharacteristics().getSize(), null); return new CreateAnswer(cmd, vol); } } catch (Exception ex) { return null; } } protected StartAnswer execute(StartCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource StartCommand: " + _gson.toJson(cmd)); } VirtualMachineTO vmSpec = cmd.getVirtualMachine(); String vmName = vmSpec.getName(); State state = State.Stopped; String scriptFileName = vmName+ ".ps1"; String newLine = System.getProperty("line.separator"); String bootArgsDiskName = vmName+"-bootparams.vhd"; String bootArgsDiskPath = "C:\\ProgramData\\Virtual Machine Manager Library Files\\VHDs\\"+bootArgsDiskName; try { // mark VM as starting state so that sync() can know not to report stopped too early synchronized (_vms) { _vms.put(vmName, State.Starting); { // create and attach boot parameter disk String diskpartScriptName = vmName+"-Diskpart.txt"; StringBuilder cmdDiskpart = new StringBuilder("create vdisk file=\"");cmdDiskpart.append(bootArgsDiskPath.toCharArray());cmdDiskpart.append("\" maximum=10 type=expandable" + newLine); cmdDiskpart.append("select vdisk file=\"");cmdDiskpart.append(bootArgsDiskPath.toCharArray());cmdDiskpart.append("\"" + newLine); cmdDiskpart.append("attach vdisk" + newLine); cmdDiskpart.append("create partition primary" + newLine); cmdDiskpart.append("format fs=ntfs label=\"test vhd\" quick" + newLine); cmdDiskpart.append("assign letter="+vmName.toCharArray()[0]+ newLine); cmdDiskpart.append("attach vdisk" + newLine); File f=new File(diskpartScriptName); FileOutputStream fop=new FileOutputStream(f); fop.write(cmdDiskpart.toString().getBytes()); fop.flush(); fop.close(); s_logger.info("Running diskpart attach command"); Process p = Runtime.getRuntime().exec("cmd.exe /c diskpart.exe /s "+diskpartScriptName); p.getOutputStream().close(); InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream())); BufferedReader errreader = new BufferedReader(temperrReader); if (errreader.ready()) { String errorOutput = new String(""); while (true){ String errline = errreader.readLine(); if (errline == null) { break; } errorOutput = errorOutput + errline; } s_logger.info("errors found while running diskpart command: " + errorOutput); } p.getErrorStream().close(); InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream())); BufferedReader reader = new BufferedReader(tempReader); String output = new String(""); while (true){ String line = reader.readLine(); if (line == null) { break; } output = output + line; } p.getInputStream().close(); s_logger.info("diskpart detahc command output: "+ output); } // wait for a while so that disk formatting is done Thread.sleep(60000); //create boot args on the disk String bootArgs = vmSpec.getBootArgs(); String Drive = vmName.substring(0,1); File fBootargs =new File(Drive+":\\cmdline"); FileOutputStream fopBoot=new FileOutputStream(fBootargs); fopBoot.write(bootArgs.toString().getBytes()); fopBoot.flush(); fopBoot.close(); //detach the boot parameter disk { String diskpartDetachScriptName = vmName+"-Detach-Diskpart.txt"; StringBuilder cmdDetachDiskpart = new StringBuilder("select vdisk file=\""); cmdDetachDiskpart.append(bootArgsDiskPath.toCharArray());cmdDetachDiskpart.append("\"" + newLine); cmdDetachDiskpart.append("detach vdisk" + newLine); File fd=new File(diskpartDetachScriptName); FileOutputStream fdop=new FileOutputStream(fd); fdop.write(cmdDetachDiskpart.toString().getBytes()); fdop.flush(); fdop.close(); s_logger.info("Running diskpart detach command"); Process pd = Runtime.getRuntime().exec("cmd.exe /c diskpart.exe /s "+diskpartDetachScriptName); pd.getOutputStream().close(); InputStreamReader temperrReader1 = new InputStreamReader(new BufferedInputStream(pd.getErrorStream())); BufferedReader errreader1 = new BufferedReader(temperrReader1); if (errreader1.ready()) { String errorOutput = new String(""); while (true){ String errline = errreader1.readLine(); if (errline == null) { break; } errorOutput = errorOutput + errline; } s_logger.info("errors found while running diskpart detach command: " + errorOutput); } pd.getErrorStream().close(); InputStreamReader tempReader1 = new InputStreamReader(new BufferedInputStream(pd.getInputStream())); BufferedReader reader1 = new BufferedReader(tempReader1); String output1 = new String(""); while (true){ String line = reader1.readLine(); if (line == null) { break; } output1 = output1 + line; } pd.getInputStream().close(); s_logger.info("diskpart detach command output: "+ output1); } } UUID id = UUID.randomUUID(); String hwProfileId = id.toString(); StringBuilder cmdStr = new StringBuilder("Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager;" + newLine); cmdStr.append("Get-VMMServer -ComputerName localhost;" + newLine); cmdStr.append("$JobGroupId = [Guid]::NewGuid().ToString();" + newLine); cmdStr.append("$hwProfileId = [Guid]::NewGuid().ToString(); " + newLine); cmdStr.append("$CPUType = Get-CPUType -VMMServer localhost | where {$_.Name -eq " + "'1.20 GHz Athlon MP'}; " + newLine); cmdStr.append("$ISO = Get-ISO -VMMServer localhost | where { $_.Name -match \"systemvm\" }; " + newLine); cmdStr.append("$VMHost = Get-VMHost -VMMServer localhost | where {$_.Name -eq \"HYPERVHOST.hypervdc.intranet.lab.vmops.com\"}; " + newLine); cmdStr.append("$VNetwork = Get-VirtualNetwork -VMHost $VMHost -Name \"public\"; " + newLine); cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine); cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine); cmdStr.append("New-VirtualNetworkAdapter -VMMServer localhost -JobGroup $JobGroupID -PhysicalAddressType Dynamic -VirtualNetwork $vnetwork; " + newLine); cmdStr.append("New-VirtualDVDDrive -VMMServer localhost -JobGroup $JobGroupID -Bus 1 -LUN 0 -ISO $ISO ; " + newLine); cmdStr.append("New-HardwareProfile -VMMServer localhost -JobGroup $JobGroupID -Owner \"HYPERVDC\\Administrator\" -CPUType $CPUType -Name $hwProfileId"); cmdStr.append(" -Description \"Profile used to create a VM/Template\"" + " -CPUCount 1 -MemoryMB 512 -RelativeWeight 100 -HighlyAvailable $true -NumLock $false -BootOrder \"CD\", " + "\"IdeHardDrive\", \"PxeBoot\", \"Floppy\" -LimitCPUFunctionality $false -LimitCPUForMigration $false; " + newLine); cmdStr.append("$JobGroupId = [Guid]::NewGuid().ToString(); " + newLine); //refresh library share cmdStr.append("$share = Get-LibraryShare;"+newLine); cmdStr.append("Refresh-LibraryShare -LibraryShare $share;"+newLine); // create root disk cmdStr.append("$VirtualHardDisk1 = Get-VirtualHardDisk -VMMServer localhost | where {$_.Location -eq \"\\\\scvmm.hypervdc.intranet.lab.vmops.com\\MSSCVMMLibrary\\VHDs\\systemvm.vhd\"} | where {$_.HostName -eq \"scvmm.hypervdc.intranet.lab.vmops.com\"}" + newLine); cmdStr.append("New-VirtualDiskDrive -VMMServer localhost -JobGroup $JobGroupID -IDE -Bus 0 -LUN 0 -VirtualHardDisk $VirtualHardDisk1 -Filename \""); cmdStr.append(vmName.toCharArray()); cmdStr.append("-systemvm.vhd\"; " + newLine); // create boot param data disk cmdStr.append("$VirtualHardDisk2 = Get-VirtualHardDisk -VMMServer localhost " + " | where {$_.Location -eq \"\\\\scvmm.hypervdc.intranet.lab.vmops.com\\MSSCVMMLibrary\\VHDs\\"); cmdStr.append(bootArgsDiskName.toCharArray()); cmdStr.append("\" } | where {$_.HostName -eq \"scvmm.hypervdc.intranet.lab.vmops.com\"}" + newLine); cmdStr.append("New-VirtualDiskDrive -VMMServer localhost -JobGroup $JobGroupID -IDE -Bus 0 -LUN 1 -VirtualHardDisk $VirtualHardDisk2 -Filename \""); cmdStr.append(bootArgsDiskName.toCharArray()); cmdStr.append("\";"+newLine); cmdStr.append("$HardwareProfile = Get-HardwareProfile -VMMServer localhost | where {$_.Name -eq $hwProfileId};" + newLine); cmdStr.append("$OperatingSystem = Get-OperatingSystem -VMMServer localhost | where {$_.Name -eq 'Other Linux (32 bit)'};" + newLine); cmdStr.append("New-VM -VMMServer localhost -Name \""); cmdStr.append(vmName.toCharArray()); cmdStr.append("\" -Description \"\" -Owner \"HYPERVDC\\Administrator\" -VMHost $VMHost -Path \"C:\\ClusterStorage\\Volume1\" -HardwareProfile $HardwareProfile " + " -JobGroup $JobGroupID" + " -OperatingSystem $OperatingSystem -RunAsSystem -StartVM -StartAction NeverAutoTurnOnVM -StopAction SaveVM;" + newLine); File f=new File(scriptFileName); FileOutputStream fop=new FileOutputStream(f); fop.write(cmdStr.toString().getBytes()); fop.flush(); fop.close(); s_logger.info("Running command: " + cmdStr); Process p = Runtime.getRuntime().exec("cmd.exe /c Powershell -Command \" & '.\\" + scriptFileName +"'\""); p.getOutputStream().close(); InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream())); BufferedReader errreader = new BufferedReader(temperrReader); if (errreader.ready()) { String errorOutput = new String(""); while (true){ String errline = errreader.readLine(); if (errline == null) { break; } errorOutput = errorOutput + errline; } s_logger.info("errors found while running cmdlet to create VM: " + errorOutput); } p.getErrorStream().close(); InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream())); BufferedReader reader = new BufferedReader(tempReader); String output = new String(""); while (true){ String line = reader.readLine(); if (line == null) { break; } output = output + line; } p.getInputStream().close(); s_logger.info("vm create cmmdlet output: "+ output); if (output.contains("FullyQualifiedErrorId") || output.contains("Error") || output.contains("Exception")) { s_logger.info("No errors found in running cmdlet "+ cmdStr.toString()); return new StartAnswer(cmd, "Failed to start VM"); } state = State.Running; return new StartAnswer(cmd); } catch (Exception e){ return new StartAnswer(cmd, "Failed to start VM"); } finally { //delete the PS script file //File f=new File(".\\"+scriptFileName); //f.delete(); synchronized (_vms) { if (state != State.Stopped) { _vms.put(vmName, state); } else { _vms.remove(vmName); } } } } protected Answer execute(DhcpEntryCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource DhcpEntryCommand: " + _gson.toJson(cmd)); } String args = " " + cmd.getVmMac(); args += " " + cmd.getVmIpAddress(); args += " " + cmd.getVmName(); if (s_logger.isDebugEnabled()) { s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args); } try { Pair<Boolean, String> result = SshHelper.sshExecute(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), DEFAULT_DOMR_SSHPORT, "root", new File("id_rsa.cloud"), null, "/root/edithosts.sh " + args); if (!result.first()) { s_logger.error("dhcp_entry command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); return new Answer(cmd, false, "DhcpEntry failed due to " + result.second()); } if (s_logger.isInfoEnabled()) { s_logger.info("dhcp_entry command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); } } catch (Throwable e) { s_logger.error("Unexpected exception ", e); return new Answer(cmd, false, "DhcpEntry failed due to exception"); } return new Answer(cmd); } protected CheckSshAnswer execute(CheckSshCommand cmd) { String vmName = cmd.getName(); String privateIp = cmd.getIp(); int cmdPort = cmd.getPort(); if (s_logger.isInfoEnabled()) { s_logger.info("Ping VM:" + cmd.getName() + " IP:" + privateIp + " port:" + cmdPort); } return new CheckSshAnswer(cmd); } @Override public void setAgentControl(IAgentControl agentControl) { this.agentControl = agentControl; } @Override public Type getType() { // TODO Auto-generated method stub return null; } @Override public StartupCommand[] initialize() { s_logger.info("recieved initialize request for cluster:" + _clusterId); List<String> vmHostList = getHostsInCluster(_clusterId); if (vmHostList.size() == 0) { s_logger.info("cluster is not recognized or zero instances in the cluster"); } StartupCommand[] answerCmds = new StartupCommand[vmHostList.size()]; int index =0; for (String hostName: vmHostList) { s_logger.info("Node :" + hostName); StartupRoutingCommand cmd = new StartupRoutingCommand(); answerCmds[index] = cmd; fillHostInfo(cmd,hostName); index++; } s_logger.info("response sent to initialize request for cluster:" + _clusterId); return answerCmds; } protected void fillHostInfo(StartupRoutingCommand cmd, String hostName) { Map<String, String> details = cmd.getHostDetails(); if (details == null) { details = new HashMap<String, String>(); } try { fillHostHardwareInfo(cmd); fillHostNetworkInfo(cmd); fillHostDetailsInfo(details); } catch (Exception e) { s_logger.error("Exception while retrieving host info ", e); throw new CloudRuntimeException("Exception while retrieving host info"); } cmd.setName(hostName); cmd.setHostDetails(details); cmd.setGuid(_guid); cmd.setDataCenter(_dcId); cmd.setPod(_podId); cmd.setCluster(_clusterId); cmd.setHypervisorType(HypervisorType.Hyperv); } private void fillHostDetailsInfo(Map<String, String> details) throws Exception { } private Answer execute(GetHostStatsCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource GetHostStatsCommand: " + _gson.toJson(cmd)); } try { // FIXME: get the actual host stats by running powershell cmdlet. This is just for prototype. HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 10000, 10000, "host", 2*1024*1024, 1*1024*1024, 1*1024*1024, 0); s_logger.info("returning stats :" + 2*1024*1024 + " " + 1*1024*1024 + " " + 1*1024*1024); return new GetHostStatsAnswer(cmd, hostStats); } catch (Exception e) { HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), 0, 0, 0, "host", 0, 0, 0, 0); String msg = "Unable to execute GetHostStatsCommand due to exception " + e.getMessage(); s_logger.error(msg, e); return new GetHostStatsAnswer(cmd, hostStats); } } protected Answer execute(ModifyStoragePoolCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource ModifyStoragePoolCommand: " + _gson.toJson(cmd)); } try { StorageFilerTO pool = cmd.getPool(); s_logger.info("Primary storage pool details: " + pool.getHost() + " " + pool.getPath()); Map<String, TemplateInfo> tInfo = new HashMap<String, TemplateInfo>(); // FIXME: get the actual storage capacity and storage stats of CSV volume // by running powershell cmdlet. This hardcoding just for prototype. ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, 1024*1024*1024*1024L, 512*1024*1024*1024L, tInfo); return answer; } catch (Throwable e) { return new Answer(cmd, false, "Unable to execute ModifyStoragePoolCommand due to exception " + e.getMessage()); } } protected Answer execute(GetStorageStatsCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing GetStorageStatsCommand command: " + _gson.toJson(cmd)); } // FIXME: get the actual storage capacity and storage stats of CSV volume return new GetStorageStatsAnswer(cmd, 1024*1024*1024*1024L, 512*1024*1024*1024L); } private void fillHostHardwareInfo(StartupRoutingCommand cmd) throws RemoteException { try { // FIXME: get the actual host capacity by running cmdlet.This hardcoding just for prototype cmd.setCaps("hvm"); cmd.setDom0MinMemory(0); cmd.setSpeed(100000); cmd.setCpus(6); long ram = new Long("211642163904"); cmd.setMemory(ram); } catch (Throwable e) { s_logger.error("Unable to query host network info due to exception ", e); throw new CloudRuntimeException("Unable to query host network info due to exception"); } } private void fillHostNetworkInfo(StartupRoutingCommand cmd) throws RemoteException { try { // FIXME: get the actual host and storage IP by running cmdlet.This hardcoding just for prototype cmd.setPrivateIpAddress("192.168.154.236"); cmd.setPrivateNetmask("255.255.255.0"); cmd.setPrivateMacAddress("00:16:3e:77:e2:a0"); cmd.setStorageIpAddress("192.168.154.36"); cmd.setStorageNetmask("255.255.255.0"); cmd.setStorageMacAddress("00:16:3e:77:e2:a0"); } catch (Throwable e) { s_logger.error("Unable to query host network info due to exception ", e); throw new CloudRuntimeException("Unable to query host network info due to exception"); } } private List <String> getHostsInCluster(String clusterName) { List<String> hypervHosts = new ArrayList<String>(); try { //StringBuilder cmd = new StringBuilder("cmd /c powershell.exe -OutputFormat XML "); StringBuilder cmd = new StringBuilder("cmd /c powershell.exe "); cmd.append("-Command Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager; "); cmd.append("Get-VMMServer -ComputerName localhost; "); cmd.append("Get-VMHostCluster "); cmd.append(clusterName.toCharArray()); Process p = Runtime.getRuntime().exec(cmd.toString()); p.getOutputStream().close(); InputStreamReader temperrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream())); BufferedReader errreader = new BufferedReader(temperrReader); if (errreader.ready()) { String errorOutput = new String(""); s_logger.info("errors found while running cmdlet Get-VMHostCluster"); while (true){ String errline = errreader.readLine(); if (errline == null) { break; } errorOutput = errorOutput + errline; } s_logger.info(errorOutput); } else { s_logger.info("No errors found in running cmdlet:" + cmd); } p.getErrorStream().close(); /* InputStream in = (InputStream) p.getInputStream(); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader parser = factory.createXMLStreamReader(in); while(parser.hasNext()) { int eventType = parser.next(); switch (eventType) { case START_ELEMENT: // Do something break; case END_ELEMENT: // Do something break; // And so on ... } } parser.close(); */ InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream())); BufferedReader reader = new BufferedReader(tempReader); String output = new String(""); while (true){ String line = reader.readLine(); if (line == null) { break; } output = output + line; } String nodesListStr = output.substring(output.indexOf("Nodes")); nodesListStr = nodesListStr.substring(nodesListStr.indexOf('{', 0)+1, nodesListStr.indexOf('}', 0)); String[] nodesList = nodesListStr.split(","); for (String node : nodesList) { hypervHosts.add(node); } p.getInputStream().close(); } catch (Exception e) { s_logger.info("Exception caught: "+e.getMessage()); } return hypervHosts; } protected HashMap<String, State> sync() { HashMap<String, State> changes = new HashMap<String, State>(); try { synchronized (_vms) { } } catch (Throwable e) { s_logger.error("Unable to perform sync information collection process at this point due to exception ", e); return null; } return changes; } @Override public PingCommand getCurrentStatus(long id) { HashMap<String, State> newStates = sync(); if (newStates == null) { newStates = new HashMap<String, State>(); } PingRoutingCommand cmd = new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, newStates); return cmd; } @Override public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { _dcId = params.get("zone").toString(); _podId= params.get("pod").toString(); _clusterId = params.get("cluster").toString(); _guid = params.get("guid").toString(); boolean success = super.configure(name, params); if (! success) { return false; } return true; } @Override protected String getDefaultScriptsDir() { // TODO Auto-generated method stub return null; } }