/// <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); }