/// <summary>
        /// Create a DockerContainerInstance from the results of docker ps in JSON format
        /// </summary>
        public static bool TryCreate(string json, out DockerContainerInstance instance)
        {
            instance = null;
            try
            {
                JObject obj = JObject.Parse(json);
                instance = obj.ToObject <DockerContainerInstance>();
            }
            catch (Exception e)
            {
                HostTelemetry.SendEvent(TelemetryHelper.Event_DockerPSParseFailure, new KeyValuePair <string, object>[] {
                    new KeyValuePair <string, object>(TelemetryHelper.Property_ExceptionName, e.GetType().Name)
                });

                string error = e.ToString();
                VsOutputWindowWrapper.WriteLine(StringResources.Error_DockerPSParseFailed.FormatCurrentCultureWithArgs(json, error), StringResources.Docker_PSName);
                Debug.Fail(error);
            }
            return(instance != null);
        }
示例#2
0
        public static IEnumerable <string> GetInstalledDistros()
        {
            HashSet <string> distributions = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            ThreadHelper.JoinableTaskFactory.Run(StringResources.WaitingOp_EnumeratingWSLDistros, async(progress, cancellationToken) =>
            {
                ProcessStartInfo startInfo = GetWSLStartInfo("-l -v", Encoding.Unicode);

                ProcessResult processResult = await LocalProcessAsyncRunner.ExecuteProcessAsync(startInfo, cancellationToken);
                if (processResult.ExitCode != 0)
                {
                    const int NoDistrosExitCode = -1;
                    if (processResult.ExitCode == NoDistrosExitCode)
                    {
                        // Older versions of wsl don't like the '-v' and will also fail with -1 for that reason. Check if this is why we are seeing the failure
                        ProcessResult retryResult = await LocalProcessAsyncRunner.ExecuteProcessAsync(GetWSLStartInfo("-l", Encoding.Unicode), cancellationToken);

                        // If the exit code is still NoDistros then they really don't have any distros
                        if (retryResult.ExitCode == NoDistrosExitCode)
                        {
                            throw new WSLException(StringResources.Error_WSLNoDistros);
                        }
                        // For any other code, they don't have WSL 2 installed.
                        else
                        {
                            throw new WSLException(StringResources.WSL_V2Required);
                        }
                    }
                    else
                    {
                        if (processResult.StdErr.Count > 0)
                        {
                            VsOutputWindowWrapper.WriteLine(StringResources.Error_WSLExecErrorOut_Args2.FormatCurrentCultureWithArgs(startInfo.FileName, startInfo.Arguments));
                            foreach (string line in processResult.StdErr)
                            {
                                VsOutputWindowWrapper.WriteLine("\t" + line);
                            }
                        }

                        throw new WSLException(StringResources.Error_WSLEnumDistrosFailed_Args1.FormatCurrentCultureWithArgs(processResult.ExitCode));
                    }
                }

                // Parse the installed distributions

                /* Ouput looks like:
                 *  NAME                   STATE           VERSION
                 * Ubuntu                 Stopped         2
                 *  docker-desktop-data    Running         2
                 *  docker-desktop         Running         2
                 */
                Regex distributionRegex = new Regex(@"^\*?\s+(?<name>\S+)\s");
                foreach (string line in processResult.StdOut.Skip(1))
                {
                    Match match = distributionRegex.Match(line);
                    if (match.Success)
                    {
                        string distroName = match.Groups["name"].Value;
                        if (distroName.StartsWith("docker-desktop", StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        distributions.Add(distroName);
                    }
                }
            });
            if (distributions.Count == 0)
            {
                throw new WSLException(StringResources.Error_WSLNoDistros);
            }

            return(distributions);
        }