public void Reserve(UserCredential credential, RequestedVMDictionary requestedVMs, VMQuantityDictionary requiredVMQuantity) { var virtualMachines = VMInventoryManager.RequestVMs(_sessionId, credential, requestedVMs, requiredVMQuantity); try { foreach (VirtualMachine machine in virtualMachines) { TraceFactory.Logger.Debug("{0} : {1}".FormatWith(machine.Name, machine.MachineType)); var machineType = EnumUtil.GetByDescription <ManagedMachineType>(machine.MachineType); var machineInstance = new ManagedMachine(machine.Name, machineType); GetMachineQueueForPlatform(machine.PlatformUsage).Enqueue(machineInstance); } } catch (Exception ex) { TraceFactory.Logger.Error(ex); // Something bad happened. Release everything. foreach (var machine in virtualMachines) { using (var machineInstance = new ManagedMachine(machine.Name, EnumUtil.GetByDescription <ManagedMachineType>(machine.MachineType))) { machineInstance.ReleaseReservation(); } } Dispose(); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="SessionTicket"/> class. /// </summary> public SessionTicket() { SessionId = CreateSessionId(); ScenarioIds = new List <Guid>(); SessionName = string.Empty; SessionCycle = string.Empty; SessionOwner = null; SessionNotes = null; DurationHours = 1; ExpirationDate = DateTime.Now.AddHours(1); RequestedVMs = new RequestedVMDictionary(); DurationHours = 1; StartupToken = SequentialGuid.NewGuid(); AssociatedProductList = new List <AssociatedProductSerializable>(); CollectEventLogs = false; CollectDARTLogs = false; FailureCount = -1; FailureTime = TimeSpan.MaxValue; LogLocation = string.Empty; RemoveUnresponsiveDevices = true; }
private static List <VirtualMachine> GetMasterList(UserCredential credential, RequestedVMDictionary requestedVMs) { List <VirtualMachine> masterMachineList = null; if (requestedVMs.Count == 0) { TraceFactory.Logger.Debug("No specific machines requested."); // Add all available VMs with no hold ID to the master list masterMachineList = VirtualMachine.Select(VMPowerState.PoweredOff, VMUsageState.Available, holdId: null).ToList(); } else { TraceFactory.Logger.Debug("Specific machines requested."); // Add all available VMs with no hold ID to the master list masterMachineList = VirtualMachine.Select(VMPowerState.PoweredOff, VMUsageState.Available).ToList(); // The user requested specific machines, so throw out any machines that are not on that list IEnumerable <string> requestedVMNames = requestedVMs.SelectMany(n => n.Value); masterMachineList.RemoveAll(n => !requestedVMNames.Contains(n.Name, StringComparer.OrdinalIgnoreCase)); } // If user is not an admin, check for user group rights to the VMs if (!credential.HasPrivilege(UserRole.Administrator)) { TraceFactory.Logger.Debug("{0} total machines BEFORE quota".FormatWith(masterMachineList.Count)); using (var enterpriseTestContext = DbConnect.EnterpriseTestContext()) { var allowedVMs = enterpriseTestContext.UserGroups .Where(n => n.Users.Any(m => m.UserName == credential.UserName)) .SelectMany(n => n.FrameworkClients) .Select(n => n.FrameworkClientHostName).ToList(); masterMachineList.RemoveAll(n => !allowedVMs.Contains(n.Name, StringComparer.OrdinalIgnoreCase)); } TraceFactory.Logger.Debug("{0} total machines AFTER quota".FormatWith(masterMachineList.Count)); } return(masterMachineList); }
/// <summary> /// Reserves the requested VMs. /// </summary> /// <param name="sessionId">The session id.</param> /// <param name="credential">The user requesting the reservation.</param> /// <param name="requestedVMs">The requested VMs.</param> /// <param name="requiredVMQuantity">The required VM quantity.</param> /// <returns></returns> public static bool Reserve(string sessionId, UserCredential credential, RequestedVMDictionary requestedVMs, VMQuantityDictionary requiredVMQuantity) { if (requiredVMQuantity == null) { throw new ArgumentNullException("requiredVMQuantity"); } if (requestedVMs == null) { throw new ArgumentNullException("requestedVMs"); } DateTime currentTime = DateTime.Now; TraceFactory.Logger.Debug(requiredVMQuantity.ToString()); LockToken lockToken = new GlobalLockToken("VirtualMachineReservation", new TimeSpan(0, 1, 0), new TimeSpan(0, 2, 0)); ExecutionServices.CriticalSection.Run(lockToken, () => { // Need to work with a master list of VMs. If the requested set is empty, then the master list // will come from the database. Otherwise it will come from the requested set. List <VirtualMachine> masterMachineList = GetMasterList(credential, requestedVMs); // Copy the required VMs (by Platform) to their own dictionary as items will be removed. Dictionary <string, int> remainingPlatforms = requiredVMQuantity.ToDictionary(entry => entry.Key, entry => entry.Value); using (AssetInventoryContext context = DbConnect.AssetInventoryContext()) { // Iterate over each item in the required VM dictionary and process while (remainingPlatforms.Count > 0) { // Get the target platform and required count for each entry string targetPlatformId = remainingPlatforms.ElementAt(0).Key; int targetPlatformCount = remainingPlatforms.ElementAt(0).Value; TraceFactory.Logger.Debug("Target Platform {0} and machine count {1}".FormatWith(targetPlatformId, targetPlatformCount)); List <VirtualMachineSelection> machineSelections = GetMachineSelections(targetPlatformId, masterMachineList, remainingPlatforms); // Now try to reserve the VMs. If the required VMs are more than the available, then // this is an error. Otherwise work down the list for the number of VMs required. Since // they are now ordered the VMs selected will be the least unique and those will more // special associations will be further down the list. TraceFactory.Logger.Debug("Machine Platform: {0} - {1} Requested, {2} Available".FormatWith(targetPlatformId, targetPlatformCount, machineSelections.Count)); if (machineSelections.Count >= targetPlatformCount) { for (int i = 0; i < targetPlatformCount; i++) { Reserve ( context, machineSelections[i].Machine.Name, targetPlatformId, currentTime, sessionId, GlobalSettings.Environment ); //Once the machine is reserved, remove it from the master list. masterMachineList.Remove(machineSelections[i].Machine); TraceFactory.Logger.Debug("Host {0} reserved".FormatWith(machineSelections[i].Machine.Name)); } } else { throw new VMInventoryException("Only {0} {1} machines available of {2} requested." .FormatWith(machineSelections.Count, targetPlatformId, targetPlatformCount)); } // Remove the platform that was just processed remainingPlatforms.Remove(targetPlatformId); } // Save all the final changes. Do this at the end so that if there // is a problem, there is nothing to roll back. context.SaveChanges(); } //AssetInventoryContext }); //reservation.Run return(true); }
/// <summary> /// Reserves the requested block of VMs. /// </summary> /// <param name="sessionId">The session Id.</param> /// <param name="credential">Credentials for reserving the VMs</param> /// <param name="requestedVMs">The platforms of the requested VMs.</param> /// <param name="requiredVMQuantity">The quantity per platform of requested VMs.</param> /// <returns>Whether or not the requested VMs were reserved.</returns> public static Collection <VirtualMachine> RequestVMs(string sessionId, UserCredential credential, RequestedVMDictionary requestedVMs, VMQuantityDictionary requiredVMQuantity) { bool reserved; lock (_resourceLock) { TraceFactory.Logger.Debug("Reserving virtual machines..."); reserved = VMInventoryManager.Reserve(sessionId, credential, requestedVMs, requiredVMQuantity); } if (!reserved) { throw new VMInventoryException("Unable to reserve requested virtual machines"); } var reservedVMs = VMInventoryManager.GetReservedList(sessionId); TraceFactory.Logger.Info("Successfully reserved {0} virtual machines".FormatWith(reservedVMs.Count)); return(reservedVMs); }