public override void PowerOn(CancellationTokenSource cancellation) { MachineStart.Run(_machine.Name, () => { if (cancellation.Token.IsCancellationRequested) { return; } TraceFactory.Logger.Debug("{0}: Reverting".FormatWith(_machine.Name)); UpdateStatus("Revert"); _machine.Revert(); if (cancellation.Token.IsCancellationRequested) { return; } TraceFactory.Logger.Debug("{0}: Power On".FormatWith(_machine.Name)); UpdateStatus("PowerOn"); _machine.PowerOn(); if (!VMController.WaitOnMachineAvailable(_machine.Name, cancellation.Token)) { TraceFactory.Logger.Debug("Cancellation received"); throw new OperationCanceledException("Cancellation received"); } }); }
private void StartSimulatorHandler() { bool alreadyRetried = false; TraceFactory.Logger.Debug("Starting simulator {0}".FormatWith(_machine.Name)); while (true) { try { if (_machine.IsPoweredOn()) { // The machine is already powered on, see if the simulator is responsive // and handle accordingly. TraceFactory.Logger.Debug("{0} is already powered on...".FormatWith(_machine.Name)); if (JediSimulatorManager.IsSimulatorReady(_machine.Name)) { // The simulator is on and ready to go, just return return; } else { // Since the machine is running, but the simulator doesn't respond // attempt to stop the simulator try { // Attempt to shutdown the simulator. If this fails then log it and continue TraceFactory.Logger.Debug("Attempting to shutdown the simulator"); JediSimulatorManager.ShutdownSimulator(_machine.Name); } catch (Exception ex) { TraceFactory.Logger.Debug("Simulator shutdown failed, error: {0}".FormatWith(ex.Message)); } } } else { // The machine isn't on, so boot it and then try to start the simulator. try { MachineStart.Run(_machine.Name, () => { TraceFactory.Logger.Debug("Booting {0}".FormatWith(_machine.Name)); MapElement.UpdateStatus("Booting"); // Don't track "In Use" for simulator VMs, they are already handled through // asset reservation. _machine.PowerOn(setInUse: false); }); } catch (Exception ex) { TraceFactory.Logger.Error("Error booting virtual machine", ex); MapElement.UpdateStatus("Error booting VM", RuntimeState.Error); return; } MapElement.UpdateStatus("ReadyWait"); if (!VMController.WaitOnMachineAvailable(_machine.Name, _cancel.Token)) { TraceFactory.Logger.Debug("Cancellation request received, returning..."); throw new OperationCanceledException("Cancellation received"); } } // Now the machine should be booted and ready to start the simulator. MapElement.UpdateStatus("Starting"); JediSimulatorManager.LaunchSimulator(_machine.Name, ((JediSimulatorDetail)Asset).Product, _machine.Name, _cancel.Token); return; } catch (Exception ex) { // If an exception is hit trying to start on the first attempt, then try one // more time after first shutting down the machine. TraceFactory.Logger.Debug("Error starting simulator on {0}".FormatWith(_machine.Name)); if (alreadyRetried) { MapElement.UpdateStatus("Unable to start this simulator: {0}".FormatWith(ex.Message), RuntimeState.Error); throw new OperationCanceledException("Cancellation received"); } else { // Unable to start the simulator, so perform a hard restart and try one more time. _machine.Shutdown(); alreadyRetried = true; } } } }