This commit is contained in:
Subrahmanyam Mandavilli 2016-02-23 13:07:38 +05:30
Родитель d5be81fc2d
Коммит 4e2de9c1d3
10 изменённых файлов: 151 добавлений и 45 удалений

Просмотреть файл

@ -43,6 +43,7 @@
"Revert Snapshot of Virtual Machines": "Revert Snapshot of Virtual Machines",
"Delete Snapshot of Virtual Machines": "Delete Snapshot of Virtual Machines",
"Power On Virtual Machines": "Power on Virtual Machines",
"Shutdown Virtual Machines": "Shutdown Virtual Machines",
"Delete Virtual Machines": "Delete Virtual Machines"
}
},

Просмотреть файл

@ -75,6 +75,9 @@ export class VmOperations {
case "Power On Virtual Machines":
cmdArgs += " -powerops start";
break;
case "Shutdown Virtual Machines":
cmdArgs += " -powerops stop";
break;
default:
tl.error("Invalid action name : " + actionName);
tl.exit(1);

Просмотреть файл

@ -25,6 +25,7 @@ public class Constants {
public static final String DELETE_SNAPSHOT_ACTION = "delete";
public static final String DELETE_VM_ACTION = "delete";
public static final String START_VM_ACTION = "start";
public static final String STOP_VM_ACTION = "stop";
public static final String TASK_ID = "735d144e-55fe-44d6-b687-db9031b6e70b";

Просмотреть файл

@ -95,4 +95,11 @@ public interface IVMWare {
* @throws Exception
*/
void startVM(String vmName, ConnectionData connData) throws Exception;
/**
* @param vmName name of the virtual machine
* @param connData vCenter connection information
* @throws Exception
*/
void stopVM(String vmName, ConnectionData connData) throws Exception;
}

Просмотреть файл

@ -21,20 +21,18 @@ public class VMWareImpl implements IVMWare {
private final String SNAPSHOT = "snapshot";
private final String CONFIG = "config";
private final String NAME = "name";
private final String GUEST_IP = "guest.ipAddress";
private final String GUEST_TOOLS_STATUS = "guest.toolsStatus";
private VimService vimService;
private VimPortType vimPort;
private ServiceContent serviceContent;
private UserSession userSession;
private ManagedObjectReference rootFolder;
private ManagedObjectReference targetDCMor;
public void connect(ConnectionData connData) throws Exception {
try {
if (!isSessionActive()) {
System.out.println("No active session found.. establishing new session.");
vimService = new VimService();
VimService vimService = new VimService();
vimPort = vimService.getVimPort();
Map<String, Object> reqContext = ((BindingProvider) vimPort).getRequestContext();
@ -48,15 +46,15 @@ public class VMWareImpl implements IVMWare {
if (connData.isSkipCACheck()) {
SkipCACheck.AllowUntrustedConnections();
}
}
serviceContent = vimPort.retrieveServiceContent(serviceInstance);
rootFolder = serviceContent.getRootFolder();
ManagedObjectReference rootFolder = serviceContent.getRootFolder();
userSession = vimPort.login(serviceContent.getSessionManager(), connData.getUserName(), connData.getPassword(),
null);
System.out.printf("Searching for datacenter with name [%s].\n", connData.getTargetDC());
targetDCMor = getMorByName(rootFolder, connData.getTargetDC(), DATA_CENTER, false);
}
}
} catch (Exception exp) {
System.out.printf("##vso[task.logissue type=error;code=USERINPUT_ConnectionFailed;TaskId=%s;]\n",
Constants.TASK_ID);
@ -142,13 +140,25 @@ public class VMWareImpl implements IVMWare {
String.format("Failed to power on virtual machine [%s].\n", vmName));
}
System.out.printf("Waiting for virtual machine [%s] to start.\n", vmName);
waitForVmToBoot(vmMor);
waitForPowerOperation(vmMor, VirtualMachineToolsStatus.TOOLS_OK);
System.out.printf("Successfully powered on virtual machine [%s].\n", vmName);
return;
}
System.out.printf("Virtual machine [%s] is already running.\n", vmName);
}
public void stopVM(String vmName, ConnectionData connData) throws Exception {
connect(connData);
if (isVmPoweredOn(vmName, connData)) {
ManagedObjectReference vmMor = getMorByName(targetDCMor, vmName, VIRTUAL_MACHINE, false);
vimPort.shutdownGuest(vmMor);
System.out.printf("Waiting for virtual machine [%s] to shutdown.\n", vmName);
waitForPowerOperation(vmMor, VirtualMachineToolsStatus.TOOLS_NOT_RUNNING);
System.out.printf("Successfully shutdowned the virtual machine [%s].\n", vmName);
}
System.out.printf("Virtual machine [%s] is already shutdowned.\n", vmName);
}
public void deleteVM(String vmName, ConnectionData connData) throws Exception {
connect(connData);
ManagedObjectReference vmMor = getMorByName(targetDCMor, vmName, VIRTUAL_MACHINE, false);
@ -198,8 +208,8 @@ public class VMWareImpl implements IVMWare {
connect(connData);
System.out.println("Checking virtual machine [ " + vmName + " ] power status.");
ManagedObjectReference vmMor = getMorByName(targetDCMor, vmName, VIRTUAL_MACHINE, false);
String vmIpAddress = (String) getMorProperties(vmMor, new String[]{GUEST_IP}).get(GUEST_IP);
return (vmIpAddress != null) && !vmIpAddress.isEmpty();
VirtualMachineToolsStatus vmToolsStatus = (VirtualMachineToolsStatus) getMorProperties(vmMor, new String[]{GUEST_TOOLS_STATUS}).get(GUEST_TOOLS_STATUS);
return (vmToolsStatus != null) && (vmToolsStatus == VirtualMachineToolsStatus.TOOLS_OK);
}
private ManagedObjectReference getMorByName(ManagedObjectReference rootContainer, String mobName, String morefType,
@ -229,16 +239,16 @@ public class VMWareImpl implements IVMWare {
return retVal;
}
private void waitForVmToBoot(ManagedObjectReference vmMor) throws Exception {
private void waitForPowerOperation(ManagedObjectReference vmMor, VirtualMachineToolsStatus desiredVmToolsStatus) throws Exception {
String version = "";
String ipAddress = "";
PropertyFilterSpec filterSpec = createPropFilterSpecForObject(vmMor, new String[]{GUEST_IP});
VirtualMachineToolsStatus vmToolsStatus = VirtualMachineToolsStatus.TOOLS_NOT_INSTALLED;
PropertyFilterSpec filterSpec = createPropFilterSpecForObject(vmMor, new String[]{GUEST_TOOLS_STATUS});
ManagedObjectReference propertyFilter = vimPort.createFilter(serviceContent.getPropertyCollector(), filterSpec, true);
WaitOptions waitOptions = new WaitOptions();
waitOptions.setMaxWaitSeconds(5 * 60); // Wait in number of seconds
long startTime = System.currentTimeMillis();
while (((new Date()).getTime() - startTime < 5 * 60 * 1000) && ipAddress.isEmpty()) {
while (((new Date()).getTime() - startTime < 5 * 60 * 1000) && vmToolsStatus != desiredVmToolsStatus) {
UpdateSet updateSet = vimPort.waitForUpdatesEx(serviceContent.getPropertyCollector(), version, waitOptions);
if (updateSet == null || updateSet.getFilterSet() == null) {
@ -259,7 +269,7 @@ public class VMWareImpl implements IVMWare {
List<PropertyChange> propChangeList = objectUpdate.getChangeSet();
for (PropertyChange propChange : propChangeList) {
if (propChange.getVal() != null) {
ipAddress = (String) propChange.getVal();
vmToolsStatus = (VirtualMachineToolsStatus) propChange.getVal();
}
}
}

Просмотреть файл

@ -110,8 +110,9 @@ public class VmOpsTool {
actionResult.setErrorMessage("delete vm operation failed for virtual machines ");
actionResult.setFailedVm(executeDeleteVmAction(vmName, connData));
} else if (argsMap.containsKey(Constants.POWER_OPS)) {
actionResult.setErrorMessage("start vm operation failed for virtual machines ");
actionResult.setFailedVm(executeStartVmAction(vmName, connData));
String actionName = argsMap.get(Constants.POWER_OPS);
actionResult.setErrorMessage(String.format("Failed to [%s] virtual machines ", actionName));
actionResult.setFailedVm(executePowerOpsAction(vmName, actionName, connData));
} else {
System.out.printf("##vso[task.logissue type=error;code=INFRA_InvalidOperation;TaskId=%s;]\n",
Constants.TASK_ID);
@ -126,10 +127,23 @@ public class VmOpsTool {
* @param connData vCenter connection information
* @return vmName if operation fails
*/
private String executeStartVmAction(String vmName, ConnectionData connData) {
private String executePowerOpsAction(String vmName, String actionName, ConnectionData connData) {
String failedVm = "";
try {
vmwareFactory.call().startVM(vmName, connData);
switch (actionName) {
case Constants.START_VM_ACTION:
vmwareFactory.call().startVM(vmName, connData);
break;
case Constants.STOP_VM_ACTION:
vmwareFactory.call().stopVM(vmName, connData);
break;
default:
System.out.printf(
"##vso[task.logissue type=error;code=INFRA_InvalidPowerOperation;TaskId=%s;]\n",
Constants.TASK_ID);
throw new Exception("Invalid action name ( " + actionName + " ) for power operation");
}
} catch (Exception exp) {
System.out.println(exp.getMessage() != null ? exp.getMessage() : "Unknown error occurred.");
failedVm = vmName + " ";

Просмотреть файл

@ -231,6 +231,12 @@ describe("getCmdArgsForAction", (): void => {
cmdArgs.should.contain("-powerops start");
});
it("Should construct command action for shutdown vm operation", (): void => {
var cmdArgs = vmOperations.VmOperations.getCmdArgsForAction("Shutdown Virtual Machines");
cmdArgs.should.contain("-powerops stop");
});
it("Should throw on failure to read snapshot name for restore/create/delete snapshot action", (): void => {
getInputStub.withArgs("snapshotName", true).throws();

Просмотреть файл

@ -7,6 +7,8 @@ public class InMemoryVMWareImpl implements IVMWare {
private Map<String, List<String>> vmSnapshotInfo = new HashMap<>();
private Map<String, String> vmActiveSnapshot = new HashMap<>();
private Map<String, String> vmStateInformation = new HashMap<>();
private String started = "Started";
public InMemoryVMWareImpl() {
List<String> snapshotList = new ArrayList<>();
@ -21,6 +23,8 @@ public class InMemoryVMWareImpl implements IVMWare {
vmSnapshotInfo.put("win7", snapshotList);
vmSnapshotInfo.put("vm1", snapshotList);
vmSnapshotInfo.put("vm2", snapshotList);
vmSnapshotInfo.put("startandstopubuntu", snapshotList);
vmSnapshotInfo.put("startandstopwindows", snapshotList);
String activeSnapshot = "Snapshot2";
vmActiveSnapshot.put("win2012r2", activeSnapshot);
@ -31,6 +35,20 @@ public class InMemoryVMWareImpl implements IVMWare {
vmActiveSnapshot.put("win7", activeSnapshot);
vmActiveSnapshot.put("vm1", activeSnapshot);
vmActiveSnapshot.put("vm2", activeSnapshot);
vmActiveSnapshot.put("startandstopubuntu", activeSnapshot);
vmActiveSnapshot.put("startandstopwindows", activeSnapshot);
String vmState = "Paused";
vmStateInformation.put("win2012r2", vmState);
vmStateInformation.put("poweredoffvm", vmState);
vmStateInformation.put("win10", vmState);
vmStateInformation.put("ubuntuvm", vmState);
vmStateInformation.put("win8", vmState);
vmStateInformation.put("win7", vmState);
vmStateInformation.put("vm1", vmState);
vmStateInformation.put("vm2", vmState);
vmStateInformation.put("startandstopubuntu", vmState);
vmStateInformation.put("startandstopwindows", vmState);
}
public synchronized void createSnapshot(String vmName, String snapshotName, boolean saveVMMemory, boolean quiesceFs,
@ -85,9 +103,21 @@ public class InMemoryVMWareImpl implements IVMWare {
}
}
public void startVM(String vmName, ConnectionData connData) throws Exception {
if (vmName.equals("VmThatFailsInStart")) {
throw new Exception("start vm operation failed for VmThatFailsInStart");
public synchronized void startVM(String vmName, ConnectionData connData) throws Exception {
vmName = vmName.toLowerCase();
if (vmStateInformation.containsKey(vmName)) {
vmStateInformation.put(vmName, started);
} else {
throw new Exception("VM not found.");
}
}
public synchronized void stopVM(String vmName, ConnectionData connData) throws Exception {
vmName = vmName.toLowerCase();
if (vmStateInformation.containsKey(vmName)) {
vmStateInformation.put(vmName, "Stopped");
} else {
throw new Exception("VM not found.");
}
}
@ -106,7 +136,6 @@ public class InMemoryVMWareImpl implements IVMWare {
}
public boolean isSnapshotExists(String vmName, String snapshotName, ConnectionData connData) throws Exception {
vmName = vmName.toLowerCase();
if (vmSnapshotInfo.containsKey(vmName)) {
return vmSnapshotInfo.get(vmName).contains(snapshotName);
@ -120,7 +149,12 @@ public class InMemoryVMWareImpl implements IVMWare {
}
public boolean isVmPoweredOn(String vmName, ConnectionData connData) throws Exception {
return true;
vmName = vmName.toLowerCase();
if (vmStateInformation.containsKey(vmName)) {
return vmStateInformation.get(vmName).equals(started);
} else {
throw new Exception("VM not found.");
}
}
public synchronized void cloneVMFromTemplate(String templateName, String vmName, String computeType, String computeName,

Просмотреть файл

@ -246,8 +246,8 @@ public abstract class VMWarePlatformTests {
}
@Test
public void startOnRunningVmShouldNotThrow() throws Exception {
String vmName = "Win2012R2";
public void startAndStopTwiceOnAVmShouldNotThrow() throws Exception {
String vmName = "startAndStopWindows";
String targetDC = "redmonddc";
connData.setTargetDC(targetDC);
@ -255,26 +255,24 @@ public abstract class VMWarePlatformTests {
assertThat(vmWareImpl.isVmPoweredOn(vmName, connData)).isEqualTo(true);
vmWareImpl.startVM(vmName, connData);
assertThat(vmWareImpl.isVmPoweredOn(vmName, connData)).isEqualTo(true);
vmWareImpl.stopVM(vmName, connData);
assertThat(vmWareImpl.isVmPoweredOn(vmName, connData)).isEqualTo(false);
vmWareImpl.stopVM(vmName, connData);
assertThat(vmWareImpl.isVmPoweredOn(vmName, connData)).isEqualTo(false);
}
@Test
public void startVmShouldSucceedForPoweredOffWindowsVM() throws Exception {
String vmName = "Win7";
String targetDC = "redmonddc";
connData.setTargetDC(targetDC);
vmWareImpl.startVM(vmName, connData);
assertThat(vmWareImpl.isVmPoweredOn(vmName, connData)).isEqualTo(true);
}
@Test
public void startVmShouldSucceedForPoweredOffLinuxVM() throws Exception {
String vmName = "UbuntuVM";
public void startAndStopVmShouldSucceedForLinuxVM() throws Exception {
String vmName = "startAndStopUbuntu";
String targetDC = "fareastdc";
connData.setTargetDC(targetDC);
vmWareImpl.startVM(vmName, connData);
assertThat(vmWareImpl.isVmPoweredOn(vmName, connData)).isEqualTo(true);
vmWareImpl.stopVM(vmName, connData);
assertThat(vmWareImpl.isVmPoweredOn(vmName, connData)).isEqualTo(false);
}
// Common for restore/delete snapshot operations

Просмотреть файл

@ -63,18 +63,25 @@ public class VmOpsToolUnitTests {
}
@Test
public void executeActionInParallelShouldSucceedForStartVMActionWithValidInputs() throws Exception {
String[] cmdArgs = getCmdArgs("newVM1, newVM2", Constants.POWER_OPS, Constants.START_VM_ACTION);
public void executeActionInParallelShouldSucceedForStartAndStopVMActionWithValidInputs() throws Exception {
String[] cmdArgs = getCmdArgs("vm1, vm2", Constants.POWER_OPS, Constants.START_VM_ACTION);
vmOpsTool.executeActionOnVmsInParallel(cmdArgs);
assertThat(vmWareImpl.isVmPoweredOn("newVM1", connData)).isEqualTo(true);
assertThat(vmWareImpl.isVmPoweredOn("newVM2", connData)).isEqualTo(true);
assertThat(vmWareImpl.isVmPoweredOn("vm1", connData)).isEqualTo(true);
assertThat(vmWareImpl.isVmPoweredOn("vm2", connData)).isEqualTo(true);
cmdArgs = getCmdArgs("vm1, vm2", Constants.POWER_OPS, Constants.STOP_VM_ACTION);
vmOpsTool.executeActionOnVmsInParallel(cmdArgs);
assertThat(vmWareImpl.isVmPoweredOn("vm1", connData)).isEqualTo(false);
assertThat(vmWareImpl.isVmPoweredOn("vm2", connData)).isEqualTo(false);
}
@Test
public void executeActionInParallelShouldThrowForStartVMActionFailureOnAVM() throws Exception {
String[] cmdArgs = getCmdArgs("newVM1, VmThatFailsInStart", Constants.POWER_OPS, Constants.START_VM_ACTION);
public void executeActionInParallelShouldThrowForStartAndStopVMActionFailureOnAVM() throws Exception {
String[] cmdArgs = getCmdArgs("vm1, VmThatFailsInStart", Constants.POWER_OPS, Constants.START_VM_ACTION);
Exception exp = null;
@ -85,7 +92,32 @@ public class VmOpsToolUnitTests {
}
assertThat(exp).isNotNull();
assertThat(vmWareImpl.isVmPoweredOn("newVM1", connData)).isEqualTo(true);
assertThat(vmWareImpl.isVmPoweredOn("vm1", connData)).isEqualTo(true);
cmdArgs = getCmdArgs("vm1, VmThatFailsInStop", Constants.POWER_OPS, Constants.STOP_VM_ACTION);
exp = null;
try {
vmOpsTool.executeActionOnVmsInParallel(cmdArgs);
} catch (Exception e) {
exp = e;
}
assertThat(exp).isNotNull();
assertThat(vmWareImpl.isVmPoweredOn("vm1", connData)).isEqualTo(false);
}
@Test
public void executeActionInParallelInvalidPowerOperationShouldFail() {
String[] cmdArgs = getCmdArgs("vm1, vm2", Constants.POWER_OPS, "pause");
Exception exp = null;
try {
vmOpsTool.executeActionOnVmsInParallel(cmdArgs);
} catch (Exception e) {
exp = e;
}
assertThat(exp).isNotNull();
}
@Test