Example #1
0
            static async Task <Possible <List <string> > > launchExternalProcessAndParseOutputAsync(Process process)
            {
                var result = new List <string>();

                using (var pooledList = Pools.GetStringList())
                {
                    var stdErrContent = pooledList.Instance;

                    using (var processExecutor = new AsyncProcessExecutor(
                               process,
                               s_externalProcessTimeout,
                               outputBuilder: line => { if (line != null)
                                                        {
                                                            result.Add(line);
                                                        }
                               },
                               errorBuilder: line => { if (line != null)
                                                       {
                                                           stdErrContent.Add(line);
                                                       }
                               }))
                    {
                        processExecutor.Start();
                        await processExecutor.WaitForExitAsync();

                        await processExecutor.WaitForStdOutAndStdErrAsync();

                        if (processExecutor.Process.ExitCode != 0)
                        {
                            var stdOut = $"{Environment.NewLine}{string.Join(Environment.NewLine, result)}";
                            var stdErr = $"{Environment.NewLine}{string.Join(Environment.NewLine, stdErrContent)}";
                            return(new Failure <string>($"{describeProcess(process)} Process failed with an exit code {processExecutor.Process.ExitCode}{stdOut}{stdErr}"));
                        }

                        if (result.Count == 0)
                        {
                            return(new Failure <string>($"{describeProcess(process)} Parser exited cleanly, but no output was written."));
                        }

                        if (!int.TryParse(result[0], out var expectedCount))
                        {
                            var stdOut = $"{Environment.NewLine}{string.Join(Environment.NewLine, result)}";
                            return(new Failure <string>($"{describeProcess(process)} Failed to parse tool output: {stdOut}"));
                        }

                        if (expectedCount != result.Count - 1)
                        {
                            var stdOut = $"{Environment.NewLine}{string.Join(Environment.NewLine, result)}";
                            return(new Failure <string>($"{describeProcess(process)} Output line count does not match the expected count: {stdOut}"));
                        }

                        result.RemoveAt(0);
                        return(result);
                    }
                }
            }
Example #2
0
        private async Task InitVmAsync()
        {
            // (1) Create and serialize 'StartBuild' request.
            string startBuildRequestPath = Path.GetTempFileName();

            using (var password = LowPrivilegeAccountUtils.GetLowPrivilegeBuildPassword())
            {
                //This will be temporary, will fix the problem exposing the password
                var startBuildRequest = new StartBuildRequest
                {
                    HostLowPrivilegeUsername = LowPrivilegeAccountUtils.GetLowPrivilegeBuildAccount(),
                    HostLowPrivilegePassword = LowPrivilegeAccountUtils.GetUnsecuredString(password)
                };
                VmSerializer.SerializeToFile(startBuildRequestPath, startBuildRequest);
            }


            // (2) Create a process to execute VmCommandProxy.
            string arguments = $"{VmCommand.StartBuild} /{VmCommand.Param.InputJsonFile}:\"{startBuildRequestPath}\"";
            var    process   = CreateVmCommandProxyProcess(arguments, Path.GetDirectoryName(startBuildRequestPath));

            var stdOutForStartBuild = new StringBuilder();
            var stdErrForStartBuild = new StringBuilder();

            // (3) Run VmCommandProxy to start build.
            using (var executor = new AsyncProcessExecutor(
                       process,
                       TimeSpan.FromMilliseconds(-1),
                       line => { if (line != null)
                                 {
                                     stdOutForStartBuild.AppendLine(line);
                                 }
                       },
                       line => { if (line != null)
                                 {
                                     stdErrForStartBuild.AppendLine(line);
                                 }
                       }))
            {
                executor.Start();
                await executor.WaitForExitAsync();

                await executor.WaitForStdOutAndStdErrAsync();

                if (executor.Process.ExitCode != 0)
                {
                    string stdOut = $"{Environment.NewLine}StdOut:{Environment.NewLine}{stdOutForStartBuild.ToString()}";
                    string stdErr = $"{Environment.NewLine}StdErr:{Environment.NewLine}{stdErrForStartBuild.ToString()}";
                    throw new BuildXLException($"Failed to init VM '{VmCommandProxy} {arguments}', with exit code {executor.Process.ExitCode}{stdOut}{stdErr}");
                }
            }
        }
Example #3
0
        /// <summary>
        /// Executes a Process
        /// </summary>
        /// <param name="exePath">Path to exe file</param>
        /// <param name="args">Args to be passed to exe</param>
        /// <param name="tempDir">Working directory for exe</param>
        /// <returns>(<see cref="Process.ExitCode"/> == 0 AND !timeOut, StdErr, StdOut)</returns>
        private async static Task <Possible <bool> > TryExecuteProcessAsync(string exePath, string args, string tempDir)
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo(exePath, args)
                {
                    CreateNoWindow         = true,
                    UseShellExecute        = false,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    WorkingDirectory       = tempDir
                },
                EnableRaisingEvents = true
            };

            StringBuilder stdOutBuilder = new StringBuilder();
            StringBuilder stdErrBuilder = new StringBuilder();

            using (var executor = new AsyncProcessExecutor(
                       process,
                       TimeSpan.FromMinutes(ExecutableMaxRuntimeInMinute),
                       line => { if (line != null)
                                 {
                                     stdOutBuilder.AppendLine(line);
                                 }
                       },
                       line => { if (line != null)
                                 {
                                     stdErrBuilder.AppendLine(line);
                                 }
                       }))
            {
                executor.Start();
                await executor.WaitForExitAsync();

                await executor.WaitForStdOutAndStdErrAsync();

                if (executor.Process.ExitCode == 0 && !executor.TimedOut)
                {
                    return(true);
                }

                string errorReturn = $"StdErr: { stdErrBuilder }, StdOut: { stdOutBuilder }";

                return(new Failure <string>(errorReturn));
            }
        }
Example #4
0
        private async Task InitVmAsync()
        {
            // (1) Create a process to execute VmCommandProxy.
            string arguments = $"{VmCommands.InitializeVm}";
            var    process   = CreateVmCommandProxyProcess(arguments, Path.GetDirectoryName(Path.GetTempFileName()));

            m_logStartInit?.Invoke($"{VmCommandProxy} {arguments}");

            var stdOutForStartBuild = new StringBuilder();
            var stdErrForStartBuild = new StringBuilder();

            string provenance = $"[{nameof(VmInitializer)}]";

            // (2) Run VmCommandProxy to start build.
            using (var executor = new AsyncProcessExecutor(
                       process,
                       TimeSpan.FromMinutes(InitVmTimeoutInMinute),
                       line => { if (line != null)
                                 {
                                     stdOutForStartBuild.AppendLine(line);
                                 }
                       },
                       line => { if (line != null)
                                 {
                                     stdErrForStartBuild.AppendLine(line);
                                 }
                       },
                       provenance: provenance,
                       logger: message => m_logInitExecution?.Invoke(message)))
            {
                executor.Start();
                await executor.WaitForExitAsync();

                await executor.WaitForStdOutAndStdErrAsync();

                string stdOut = $"{Environment.NewLine}StdOut:{Environment.NewLine}{stdOutForStartBuild.ToString()}";
                string stdErr = $"{Environment.NewLine}StdErr:{Environment.NewLine}{stdErrForStartBuild.ToString()}";

                if (executor.Process.ExitCode != 0)
                {
                    throw new BuildXLException($"Failed to init VM '{VmCommandProxy} {arguments}', with exit code {executor.Process.ExitCode}{stdOut}{stdErr}");
                }

                m_logEndInit?.Invoke($"Exit code {executor.Process.ExitCode}{stdOut}{stdErr}");
            }
        }