public RunspaceData(IRunspaceInfo runspaceInfo) { Id = runspaceInfo.Id; Endpoint = runspaceInfo.Endpoint; CreationState = runspaceInfo.CreationState; CreationError = runspaceInfo.CreationError; }
private static void EnsureRunspaceEndpointIsAccessible(IRunspaceInfo runspaceInfo) { bool ready = false; var retryNum = 0; var maxRetryCount = 40; // 10 seconds max var retryDelayMs = 250; while (retryNum < maxRetryCount) { using (TcpClient tcpClient = new TcpClient()) { try { tcpClient.Connect(runspaceInfo.Endpoint.Address, runspaceInfo.Endpoint.Port); ready = true; break; } catch { // ignored } } Thread.Sleep(retryDelayMs); retryNum++; } if (!ready) { throw new RunspaceProviderException(Resources.K8sRunspaceProvider_Create_K8sServiceIsNotAccessible); } }
private static void EnsureRunspaceEndpointIsAccessible(IRunspaceInfo runspaceInfo) { if (runspaceInfo?.CreationState != RunspaceCreationState.Error) { bool ready = false; var retryNum = 0; var maxRetryCount = 20; var retryDelayMs = 500; Exception pingExc = null; while (retryNum < maxRetryCount) { using (TcpClient tcpClient = new TcpClient()) { try { tcpClient.Connect(runspaceInfo.Endpoint.Address, runspaceInfo.Endpoint.Port); ready = true; break; } catch (Exception exc) { pingExc = exc; } } Thread.Sleep(retryDelayMs); retryNum++; } if (!ready) { throw new RunspaceProviderException(Resources.Resources.DockerRunspaceProvider_Create_NewContainerIsNotAccessible, pingExc); } } }
public void Register(IRunspaceInfo runspaceInfo, string sessionId) { lock (this) { _runspaceStats.Add( _runspaceStatsFactory.Create( runspaceInfo.Id, new RunspaceSessionInfoProvider(sessionId), new ActiveIdleInfoProvider(runspaceInfo))); } }
public ActiveIdleInfoProvider(IRunspaceInfo runspaceInfo, IRunspaceClientFactory runspaceClientFactory = null) { _runspaceInfo = runspaceInfo; _creationTime = DateTime.Now; _runspaceClientFactory = runspaceClientFactory; if (_runspaceClientFactory == null) { _runspaceClientFactory = new RunspaceClientFactory(); } }
/// <summary> /// Creates a new instance of the RunspaceChangedEventArgs class. /// </summary> /// <param name="changeAction">The action which caused the runspace to change.</param> /// <param name="previousRunspace">The previously active runspace.</param> /// <param name="newRunspace">The newly active runspace.</param> public RunspaceChangedEventArgs( RunspaceChangeAction changeAction, IRunspaceInfo previousRunspace, IRunspaceInfo newRunspace) { Validate.IsNotNull(nameof(previousRunspace), previousRunspace); ChangeAction = changeAction; PreviousRunspace = previousRunspace; NewRunspace = newRunspace; }
internal static async Task <SymbolDetails> CreateAsync( SymbolReference symbolReference, IRunspaceInfo currentRunspace, IInternalPowerShellExecutionService executionService) { SymbolDetails symbolDetails = new() { SymbolReference = symbolReference }; switch (symbolReference.SymbolType) { case SymbolType.Function: CommandInfo commandInfo = await CommandHelpers.GetCommandInfoAsync( symbolReference.SymbolName, currentRunspace, executionService).ConfigureAwait(false); if (commandInfo != null) { symbolDetails.Documentation = await CommandHelpers.GetCommandSynopsisAsync( commandInfo, executionService).ConfigureAwait(false); if (commandInfo.CommandType == CommandTypes.Application) { symbolDetails.DisplayString = "(application) " + symbolReference.SymbolName; return(symbolDetails); } } symbolDetails.DisplayString = "function " + symbolReference.SymbolName; return(symbolDetails); case SymbolType.Parameter: // TODO: Get parameter help symbolDetails.DisplayString = "(parameter) " + symbolReference.SymbolName; return(symbolDetails); case SymbolType.Variable: symbolDetails.DisplayString = symbolReference.SymbolName; return(symbolDetails); default: return(symbolDetails); } } #endregion }
/// <summary> /// Instantiates, Starts, and Gets Container details through Docker API /// </summary> /// <returns>Instance of <see cref="IRunspaceInfo"/> for the started Runspace Container.</returns> public IRunspaceInfo StartCreate() { IRunspaceInfo result = null; const long CPUsCount = 1; const long BytesInMegaByte = 1048576; var containerConfig = new ContainerConfig( image: _runspaceContainerCreateSpec.ImageName, hostConfig: new HostConfig( networkMode: _runspaceContainerCreateSpec.NetworkName, cpuCount: CPUsCount, restartPolicy: new RestartPolicy(RestartPolicy.NameEnum.Empty), memory: BytesInMegaByte * _runspaceContainerCreateSpec.RunspaceContainerMemoryLimitMB)); ContainerCreateResponse runspaceContainerInstance; try { // Create Runspace Container Instance runspaceContainerInstance = _containerApi.ContainerCreate(containerConfig); // Start Runspace Container _containerApi.ContainerStart(runspaceContainerInstance.Id); result = Get(runspaceContainerInstance.Id); } catch (ApiException dockerApiException) { result = DockerRunspaceInfo.FromRunspaceProviderError( new RunspaceProviderException( Resources.Resources.DockerRunspaceProvider_Create_StartContainerDockerAPIFail, dockerApiException)); } try { if (_testConnectionToContainerOnCreate) { // Ensure Container is accessible over the network after creation EnsureRunspaceEndpointIsAccessible(result); } } catch (RunspaceProviderException exception) { // Kill the container that is not accessible, otherwise it will leak try { if (result.Id != null) { Kill(result.Id); } } catch (RunspaceProviderException) {} result = DockerRunspaceInfo.FromRunspaceProviderError(exception); } return(result); }
public async Task <INamedScriptExecution> StartScriptExecution( string userId, IRunspaceInfo runspace, IScriptExecutionRequest scriptExecutionRequest) { var runspaceClient = _runspaceClientFactory.Create(runspace.Endpoint) as ScriptRuntimeService.RunspaceClient.RunspaceClient; var scriptExecResult = await runspaceClient.StartScript( scriptExecutionRequest.Script, scriptExecutionRequest.OutputObjectsFormat, scriptExecutionRequest.Parameters); _scriptIdToRunspaceClient[scriptExecResult.Id] = runspaceClient; _scriptExecutionStorage.StartStoringScriptExecution(userId, runspaceClient, scriptExecResult.Id, scriptExecutionRequest.Name); return(new ScriptResult(scriptExecutionRequest.Name, scriptExecResult)); }
/// <summary> /// Creates a new instance of the DebuggerStoppedEventArgs class. /// </summary> /// <param name="originalEvent">The original DebuggerStopEventArgs instance from which this instance is based.</param> /// <param name="runspaceInfo">The RunspaceDetails of the runspace which raised this event.</param> /// <param name="localScriptPath">The local path of the remote script being debugged.</param> public DebuggerStoppedEventArgs( DebuggerStopEventArgs originalEvent, IRunspaceInfo runspaceInfo, string localScriptPath) { Validate.IsNotNull(nameof(originalEvent), originalEvent); Validate.IsNotNull(nameof(runspaceInfo), runspaceInfo); if (!string.IsNullOrEmpty(localScriptPath)) { ScriptPath = localScriptPath; RemoteScriptPath = originalEvent.InvocationInfo.ScriptName; } else { ScriptPath = originalEvent.InvocationInfo.ScriptName; } OriginalEvent = originalEvent; RunspaceInfo = runspaceInfo; }
public IRunspaceInfo WaitCreateCompletion(IRunspaceInfo runspaceInfo) { return(runspaceInfo); }
public IRunspaceInfo WaitCreateCompletion(IRunspaceInfo runspaceInfo) { var result = runspaceInfo; if (result != null && result.CreationState == RunspaceCreationState.Creating) { V1Pod pod = null; try { _logger.LogDebug($"Waiting k8s Pod '{runspaceInfo.Id}' to become ready"); _logger.LogDebug($"K8s API Call ReadNamespacedPod: {runspaceInfo.Id}"); pod = _client.ReadNamespacedPod(runspaceInfo.Id, _namespace); } catch (Exception exc) { result = new K8sRunspaceInfo { Id = result.Id, CreationState = RunspaceCreationState.Error, CreationError = new RunspaceProviderException( string.Format( Resources.K8sRunspaceProvider_WaitCreateComplation_PodNotFound, result.Id), exc) }; } if (pod != null) { // Set 10 minutes timeout for container creation. // Worst case would be image pulling from server. int maxRetryCount = 6000; int retryIntervalMs = 100; int retryCount = 1; // Wait Pod to become running and obtain IP Address _logger.LogDebug($"Start wating K8s Pod to become running: {pod.Metadata.Name}"); // There are three possible phases of a POD // Pending - awaiting containers to start // Running - Pod is initialized and all containers in the Pod are running or completed successfully // Terminating - Pod is terminating // The Pending phase could last forever when container image pull error occurred or some other error // in the container initialization happens. In order to stop waiting below we first monitor for Pod status to // phase to switch from pending to running. While Pod is pending phase we monitor the container // creation for errors and if such occur we break the waiting with error. // // The Container creation errors that are related to image pulling failura are stored in the // pod.Status.ContainerStatuses[0].State.Waiting propery is not null which is instance of V1ContainerStateWaiting // The errors are returned as strings in Reason property of the V1ContainerStateWaiting // The strings that represent errors are: // // ImagePullBackOff - Container image pull failed, kubelet is backing off image pull // ImageInspectError - Unable to inspect image // ErrImagePull - General image pull error // ErrImageNeverPull - Required Image is absent on host and PullPolicy is NeverPullImage // RegistryUnavailable - Get http error when pulling image from registry // InvalidImageName - Unable to parse the image name. while ( pod != null && string.IsNullOrEmpty(pod.Status?.PodIP) && (pod.Status?.Phase != "Running" || (pod.Status?.Phase == "Pending" && !HasErrrorInContainerStatus(pod.Status, out var _))) && retryCount < maxRetryCount) { Thread.Sleep(retryIntervalMs); _logger.LogDebug($"K8s API Call ReadNamespacedPod: {pod.Metadata.Name}"); pod = _client.ReadNamespacedPod(pod.Metadata.Name, _namespace); retryCount++; } if (retryCount >= maxRetryCount) { // Timeout result = new K8sRunspaceInfo { Id = result.Id, CreationState = RunspaceCreationState.Error, CreationError = new RunspaceProviderException(Resources.K8sRunspaceProvider_WaitCreateComplition_TimeOut) }; } else if (HasErrrorInContainerStatus(pod.Status, out var errorMessage)) { // Container Creation Error result = new K8sRunspaceInfo { Id = result.Id, CreationState = RunspaceCreationState.Error, CreationError = new RunspaceProviderException(errorMessage) }; } else { // Success, everything should be in place result = new K8sRunspaceInfo { Id = result.Id, Endpoint = new IPEndPoint( IPAddress.Parse(pod.Status.PodIP), _runspaceApiPort), CreationState = RunspaceCreationState.Ready }; } if (result.CreationState == RunspaceCreationState.Ready && _verifyRunspaceApiIsAccessibleOnCreate) { try { _logger.LogDebug($"EnsureRunspaceEndpointIsAccessible: Start"); // Ensure Container is accessible over the network after creation EnsureRunspaceEndpointIsAccessible(result); _logger.LogDebug($"EnsureRunspaceEndpointIsAccessible: Success"); } catch (RunspaceProviderException exc) { _logger.LogError(exc.ToString()); // Kill the container that is not accessible, otherwise it will leak try { Kill(result.Id); } catch (RunspaceProviderException rexc) { _logger.LogError(rexc.ToString()); } result = new K8sRunspaceInfo { Id = result.Id, CreationState = RunspaceCreationState.Error, CreationError = exc }; } } } } return(result); }
/// <summary> /// Creates a new instance of the DebuggerStoppedEventArgs class. /// </summary> /// <param name="originalEvent">The original DebuggerStopEventArgs instance from which this instance is based.</param> /// <param name="runspaceInfo">The RunspaceDetails of the runspace which raised this event.</param> public DebuggerStoppedEventArgs( DebuggerStopEventArgs originalEvent, IRunspaceInfo runspaceInfo) : this(originalEvent, runspaceInfo, null) { }