Package com.cloud.hypervisor.hyperv.resource

Source Code of com.cloud.hypervisor.hyperv.resource.HypervResource

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.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.utils.ssh.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;
    }
}
TOP

Related Classes of com.cloud.hypervisor.hyperv.resource.HypervResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.