public hypervisorCollection <hypSpec_iLo> requestAsManyHypervisorsAsPossible(string snapshotName) { initialiseIfNeeded(); using (BladeDirectorServices director = new BladeDirectorServices(machinePools.bladeDirectorURL)) { int nodeCount = director.svc.getAllBladeIP().Length; hypervisorCollection <hypSpec_iLo> toRet = new hypervisorCollection <hypSpec_iLo>(); DateTime deadline = DateTime.Now + TimeSpan.FromMinutes(60); try { for (int i = 0; i < nodeCount; i++) { resultAndBladeName res = director.svc.RequestAnySingleNode(); resultAndBladeName progress = director.waitForSuccess(res, deadline - DateTime.Now); bladeSpec bladeConfig = director.svc.getBladeByIP_withoutLocking(progress.bladeName); resultAndWaitToken snapRes = director.svc.selectSnapshotForBladeOrVM(progress.bladeName, snapshotName); director.waitForSuccess(snapRes, TimeSpan.FromMinutes(3)); snapshotDetails snapshot = director.svc.getCurrentSnapshotDetails(progress.bladeName); userDesc cred = bladeConfig.credentials.First(); NASParams nas = director.svc.getNASParams(); hypSpec_iLo spec = new hypSpec_iLo( bladeConfig.bladeIP, cred.username, cred.password, bladeConfig.iLOIP, bladeConfig.iLoUsername, bladeConfig.iLoPassword, nas.IP, nas.username, nas.password, snapshot.friendlyName, snapshot.path, bladeConfig.kernelDebugPort, bladeConfig.kernelDebugKey ); ipUtils.ensurePortIsFree(bladeConfig.kernelDebugPort); bladeDirectedHypervisor_iLo newHyp = new bladeDirectedHypervisor_iLo(spec); newHyp.setDisposalCallback(onDestruction); if (!toRet.TryAdd(bladeConfig.bladeIP, newHyp)) { throw new Exception(); } } return(toRet); } catch (Exception) { toRet.Dispose(); throw; } } }
public hypervisorCollection <hypSpec_vmware> createVMs(int VMsToAlloc, string snapshotName = "clean", clientExecutionMethod execType = clientExecutionMethod.smbWithWMI, VMSource src = VMSource.configuredServer, string bladeID = null) { hypervisorCollection <hypSpec_vmware> hyps = new hypervisorCollection <hypSpec_vmware>(); for (int i = 0; i < VMsToAlloc; i++) { hypervisor_vmware thisHyp = machinePools.vmware.createHypervisorForNextFreeVMOrNull(snapshotName, execType, src, bladeID); if (thisHyp == null) { break; } hyps.TryAdd(thisHyp.getConnectionSpec().kernelDebugIPOrHostname, thisHyp); } return(hyps); }
public void willProvisionManyVM() { using (bladeDirectorDebugServices svc = new bladeDirectorDebugServices(basicBladeTests.WCFPath, basicBladeTests.WebURI)) { machinePools.bladeDirectorURL = svc.servicesURL; // Create four blades, and request a load of VMs from them. List <bladeSpec> specs = new List <bladeSpec>(); for (int bladeID = 28; bladeID < 32; bladeID++) { specs.Add(svc.svcDebug.createBladeSpecForXDLNode(bladeID, "xdl.hacks.the.planet", bladeLockType.lockAll, bladeLockType.lockAll)); } svc.svcDebug.initWithBladesFromBladeSpec(specs.ToArray(), false, NASFaultInjectionPolicy.retunSuccessful); // Ask for lots of VMs. We will get back only those that 'fit' on the cluster. List <VMSpec> requestedVMSpecs = new List <VMSpec>(); foreach (bladeSpec thisBlade in specs) { string debuggerHost = ipUtils.getBestRouteTo(IPAddress.Parse(thisBlade.bladeIP)).ToString(); // Add fifty VMs for each blade. Don't forget, we will only get those that // 'fit' on the cluster. for (int vmCount = 0; vmCount < 50; vmCount++) { requestedVMSpecs.Add(new VMSpec() { hw = new VMHardwareSpec() { cpuCount = 1, memoryMB = 2048 }, sw = new VMSoftwareSpec() { debuggerHost = debuggerHost, debuggerKey = "a.b.c.d", debuggerPort = 0 // auto } }); } } using (hypervisorCollection <hypSpec_vmware> vms = machinePools.ilo.requestVMs(requestedVMSpecs.ToArray(), true)) { // Okay, we have our new VMs allocated now. Lets verify them all. // Make a list of the created computer names and debug ports, since they are different for each request, and // make sure that they are all different and in the expected range. List <int> debugPorts = new List <int>(); List <string> displayNames = new List <string>(); // We test each VM in parallel, otherwise things are reaaaally slow. List <Thread> VMTestThreads = new List <Thread>(); foreach (hypervisorWithSpec <hypSpec_vmware> hyp in vms.Values) { Thread vmTest = new Thread(() => { hyp.powerOn(new cancellableDateTime(TimeSpan.FromMinutes(10))); // Check that debugging has been provisioned correctly executionResult bcdEditRes = hyp.startExecutable("bcdedit", "/dbgsettings"); try { Assert.AreEqual(0, bcdEditRes.resultCode); Assert.IsTrue(Regex.IsMatch(bcdEditRes.stdout, "key\\s*a.b.c.d")); Assert.IsTrue(Regex.IsMatch(bcdEditRes.stdout, "debugtype\\s*NET")); Assert.IsTrue(Regex.IsMatch(bcdEditRes.stdout, "hostip\\s*127.0.0.1")); // verify port assignment and extract the port Match m = Regex.Match(bcdEditRes.stdout, "port\\s*([0-9]+)", RegexOptions.IgnoreCase); Assert.IsTrue(m.Success); int port = Int32.Parse(m.Groups[1].Value); debugPorts.Add(port); } catch (AssertFailedException) { Debug.WriteLine("bcdedit stdout " + bcdEditRes.stdout); Debug.WriteLine("bcdedit stderr " + bcdEditRes.stderr); throw; } executionResult wmicRes = hyp.startExecutable("wmic", "computersystem get totalPhysicalMemory,name,numberOfLogicalProcessors /format:value"); try { // We expect an response similar to: // // Name=ALIZANALYSIS // NumberOfLogicalProcessors=8 // TotalPhysicalMemory=17119825920 // Assert.AreEqual(0, wmicRes.resultCode); string[] lines = wmicRes.stdout.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { if (line.Trim().Length == 0) { continue; } string[] parts = line.Split('='); string name = parts[0].ToLower().Trim(); string value = parts[1].ToLower().Trim(); switch (name) { case "name": displayNames.Add(value); break; case "numberoflogicalprocessors": Assert.AreEqual("1", value, "CPU count is incorrect"); break; case "totalphysicalmemory": Assert.AreEqual("2144903168", value, "RAM size is incorrect"); break; default: break; } } } catch (AssertFailedException) { Debug.WriteLine("WMIC reported stdout '" + wmicRes.stdout + "'"); Debug.WriteLine("WMIC reported stderr '" + wmicRes.stderr + "'"); } }); VMTestThreads.Add(vmTest); vmTest.Start(); } // Wait for them all to run foreach (Thread vmtask in VMTestThreads) { vmtask.Join(); } // Now we can verify the contents of the name/port arrays we made. try { // All computers should have unique names Assert.AreEqual(displayNames.Count, displayNames.Distinct().Count()); // And should follow this pattern Assert.IsTrue(displayNames.All(x => x.StartsWith("vm_"))); } catch (AssertFailedException) { foreach (string displayName in displayNames) { Debug.WriteLine("Machine name: '" + displayName + "'"); } throw; } try { // All computers should have unique debug ports Assert.AreEqual(debugPorts.Count, debugPorts.Distinct().Count()); // And should follow this pattern Assert.IsTrue(debugPorts.All(x => x > 52800)); Assert.IsTrue(debugPorts.All(x => x < 63200)); } catch (AssertFailedException) { Debug.WriteLine("Machine debug ports:"); foreach (string debugPort in displayNames) { Debug.WriteLine(debugPort); } throw; } } } }
public hypervisorCollection <hypSpec_vmware> requestVMs(VMSpec[] specs, bool allowPartialAllocation = false) { initialiseIfNeeded(); Stopwatch allocWatch = new Stopwatch(); using (BladeDirectorServices director = new BladeDirectorServices(machinePools.bladeDirectorURL)) { DateTime deadline = DateTime.Now + TimeSpan.FromMinutes(30); resultAndBladeName[] results = new resultAndBladeName[specs.Length]; for (int n = 0; n < specs.Length; n++) { results[n] = director.svc.RequestAnySingleVM(specs[n].hw, specs[n].sw); if (results[n].result.code == resultCode.bladeQueueFull) { if (allowPartialAllocation) { results[n] = null; break; } } if (results[n].result.code != resultCode.success && results[n].result.code != resultCode.pending) { throw new bladeAllocationException(results[n].result.code); } } hypervisorCollection <hypSpec_vmware> toRet = new hypervisorCollection <hypSpec_vmware>(); try { foreach (resultAndBladeName res in results) { if (res == null) { continue; } resultAndBladeName progress = director.waitForSuccessWithoutThrowing(res, deadline - DateTime.Now); if (progress == null) { throw new TimeoutException(); } if (progress.result.code == resultCode.bladeQueueFull) { if (allowPartialAllocation) { continue; } throw new Exception("Not enough blades available to accomodate new VMs"); } if (progress.result.code != resultCode.success) { if (allowPartialAllocation) { continue; } throw new Exception("Unexpected status while allocing: " + progress.result.code); } vmSpec vmSpec = director.svc.getVMByIP_withoutLocking(progress.bladeName); bladeSpec vmServerSpec = director.svc.getBladeByIP_withoutLocking(vmSpec.parentBladeIP); snapshotDetails snapshotInfo = director.svc.getCurrentSnapshotDetails(vmSpec.VMIP); NASParams nasParams = director.svc.getNASParams(); hypervisor_vmware_FreeNAS newVM = utils.createHypForVM(vmSpec, vmServerSpec, snapshotInfo, nasParams); ipUtils.ensurePortIsFree(vmSpec.kernelDebugPort); newVM.setDisposalCallback(onDestruction); if (!toRet.TryAdd(vmSpec.VMIP, newVM)) { throw new Exception(); } } } catch (Exception) { foreach (KeyValuePair <string, hypervisorWithSpec <hypSpec_vmware> > allocedBlades in toRet) { if (allocedBlades.Key != null) { try { director.svc.ReleaseBladeOrVM(allocedBlades.Key); } catch (Exception) { // ... } } } throw; } allocWatch.Stop(); Debug.WriteLine("Allocated all VMs, took " + allocWatch.Elapsed.ToString()); return(toRet); } }