示例#1
0
 public RunspaceData(IRunspaceInfo runspaceInfo)
 {
     Id            = runspaceInfo.Id;
     Endpoint      = runspaceInfo.Endpoint;
     CreationState = runspaceInfo.CreationState;
     CreationError = runspaceInfo.CreationError;
 }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
 public void Register(IRunspaceInfo runspaceInfo, string sessionId)
 {
     lock (this) {
         _runspaceStats.Add(
             _runspaceStatsFactory.Create(
                 runspaceInfo.Id,
                 new RunspaceSessionInfoProvider(sessionId),
                 new ActiveIdleInfoProvider(runspaceInfo)));
     }
 }
示例#5
0
 public ActiveIdleInfoProvider(IRunspaceInfo runspaceInfo, IRunspaceClientFactory runspaceClientFactory = null)
 {
     _runspaceInfo          = runspaceInfo;
     _creationTime          = DateTime.Now;
     _runspaceClientFactory = runspaceClientFactory;
     if (_runspaceClientFactory == null)
     {
         _runspaceClientFactory = new RunspaceClientFactory();
     }
 }
示例#6
0
        /// <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;
        }
示例#7
0
        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
    }
示例#8
0
        /// <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);
        }
示例#9
0
        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));
        }
示例#10
0
        /// <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;
        }
示例#11
0
 public IRunspaceInfo WaitCreateCompletion(IRunspaceInfo runspaceInfo)
 {
     return(runspaceInfo);
 }
示例#12
0
        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);
        }
示例#13
0
 /// <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)
 {
 }