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);
        }
Example #3
0
        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);
            }
        }