Пример #1
0
        public async Task <bool> SelfUpdate(AgentRefreshMessage updateMessage, IJobDispatcher jobDispatcher, bool restartInteractiveRunner, CancellationToken token)
        {
            Busy = true;
            try
            {
                if (!await UpdateNeeded(updateMessage.TargetVersion, token))
                {
                    Trace.Info($"Can't find available update package.");
                    return(false);
                }

                Trace.Info($"An update is available.");

                // Print console line that warn user not shutdown runner.
                await UpdateRunnerUpdateStateAsync("Runner update in progress, do not shutdown runner.");
                await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner");

                await DownloadLatestRunner(token);

                Trace.Info($"Download latest runner and unzip into runner root.");

                // wait till all running job finish
                await UpdateRunnerUpdateStateAsync("Waiting for current job finish running.");

                await jobDispatcher.WaitAsync(token);

                Trace.Info($"All running job has exited.");

                // delete runner backup
                DeletePreviousVersionRunnerBackup(token);
                Trace.Info($"Delete old version runner backup.");

                // generate update script from template
                await UpdateRunnerUpdateStateAsync("Generate and execute update script.");

                string updateScript = GenerateUpdateScript(restartInteractiveRunner);
                Trace.Info($"Generate update script into: {updateScript}");

                // kick off update script
                Process invokeScript = new Process();
#if OS_WINDOWS
                invokeScript.StartInfo.FileName  = WhichUtil.Which("cmd.exe", trace: Trace);
                invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
#elif (OS_OSX || OS_LINUX)
                invokeScript.StartInfo.FileName  = WhichUtil.Which("bash", trace: Trace);
                invokeScript.StartInfo.Arguments = $"\"{updateScript}\"";
#endif
                invokeScript.Start();
                Trace.Info($"Update script start running");

                await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should back online within 10 seconds.");

                return(true);
            }
            finally
            {
                Busy = false;
            }
        }
Пример #2
0
        public async Task <bool> SelfUpdate(AgentRefreshMessage updateMessage, IJobDispatcher jobDispatcher, bool restartInteractiveAgent, CancellationToken token)
        {
            ArgUtil.NotNull(updateMessage, nameof(updateMessage));
            ArgUtil.NotNull(jobDispatcher, nameof(jobDispatcher));
            if (!await UpdateNeeded(updateMessage.TargetVersion, token))
            {
                Trace.Info($"Can't find available update package.");
                return(false);
            }

            Trace.Info($"An update is available.");

            // Print console line that warn user not shutdown agent.
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("UpdateInProgress"));
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("DownloadAgent", _targetPackage.Version));

            await DownloadLatestAgent(token);

            Trace.Info($"Download latest agent and unzip into agent root.");

            // wait till all running job finish
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("EnsureJobFinished"));

            await jobDispatcher.WaitAsync(token);

            Trace.Info($"All running jobs have exited.");

            // delete agent backup
            DeletePreviousVersionAgentBackup(token);
            Trace.Info($"Delete old version agent backup.");

            // generate update script from template
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("GenerateAndRunUpdateScript"));

            string updateScript = GenerateUpdateScript(restartInteractiveAgent);

            Trace.Info($"Generate update script into: {updateScript}");

            // kick off update script
            Process invokeScript = new Process();

            if (PlatformUtil.RunningOnWindows)
            {
                invokeScript.StartInfo.FileName  = WhichUtil.Which("cmd.exe", trace: Trace);
                invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
            }
            else
            {
                invokeScript.StartInfo.FileName  = WhichUtil.Which("bash", trace: Trace);
                invokeScript.StartInfo.Arguments = $"\"{updateScript}\"";
            }
            invokeScript.Start();
            Trace.Info($"Update script start running");

            await UpdateAgentUpdateStateAsync(StringUtil.Loc("AgentExit"));

            return(true);
        }
Пример #3
0
        public async Task <bool> SelfUpdate(AgentRefreshMessage updateMessage, IJobDispatcher jobDispatcher, bool restartInteractiveAgent, CancellationToken token)
        {
            if (!await UpdateNeeded(updateMessage.TargetVersion, token))
            {
                Trace.Info($"Can't find available update package.");
                return(false);
            }

            Trace.Info($"An update is available.");

            // Print console line that warn user not shutdown agent.
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("UpdateInProgress"));
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("DownloadAgent", _targetPackage.Version));

            await DownloadLatestAgent(token);

            Trace.Info($"Download latest agent and unzip into agent root.");

            // wait till all running job finish
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("EnsureJobFinished"));

            await jobDispatcher.WaitAsync(token);

            Trace.Info($"All running job has exited.");

            // delete agent backup
            DeletePreviousVersionAgentBackup(token);
            Trace.Info($"Delete old version agent backup.");

            // generate update script from template
            await UpdateAgentUpdateStateAsync(StringUtil.Loc("GenerateAndRunUpdateScript"));

            string updateScript = GenerateUpdateScript(restartInteractiveAgent);

            Trace.Info($"Generate update script into: {updateScript}");

            // kick off update script
            Process invokeScript = new Process();
            var     whichUtil    = HostContext.GetService <IWhichUtil>();

#if OS_WINDOWS
            invokeScript.StartInfo.FileName  = whichUtil.Which("cmd.exe");
            invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
#elif (OS_OSX || OS_LINUX)
            invokeScript.StartInfo.FileName  = whichUtil.Which("bash");
            invokeScript.StartInfo.Arguments = $"\"{updateScript}\"";
#endif
            invokeScript.Start();
            Trace.Info($"Update script start running");

            await UpdateAgentUpdateStateAsync(StringUtil.Loc("AgentExit"));

            return(true);
        }
Пример #4
0
        public async Task <bool> SelfUpdate(AgentRefreshMessage updateMessage, IJobDispatcher jobDispatcher, bool restartInteractiveRunner, CancellationToken token)
        {
            Busy = true;
            try
            {
                if (!await UpdateNeeded(updateMessage.TargetVersion, token))
                {
                    Trace.Info($"Can't find available update package.");
                    return(false);
                }

                Trace.Info($"An update is available.");

                var runnerUpdateNotification = Environment.GetEnvironmentVariable("_INTERNAL_RUNNER_LIFECYCLE_NOTIFICATION");
                if (!string.IsNullOrEmpty(runnerUpdateNotification))
                {
                    HostContext.GetService <ITerminal>().WriteLine($"{DateTime.UtcNow:u}: Publish RunnerUpdate to {runnerUpdateNotification}");
                    using (var runnerUpdateInvoker = HostContext.CreateService <IProcessInvoker>())
                    {
                        runnerUpdateInvoker.OutputDataReceived += delegate(object sender, ProcessDataReceivedEventArgs stdout)
                        {
                            if (!string.IsNullOrEmpty(stdout.Data))
                            {
                                Trace.Info($"RunnerUpdateNotification: {stdout.Data}");
                            }
                        };

                        runnerUpdateInvoker.ErrorDataReceived += delegate(object sender, ProcessDataReceivedEventArgs stderr)
                        {
                            if (!string.IsNullOrEmpty(stderr.Data))
                            {
                                if (!string.IsNullOrEmpty(stderr.Data))
                                {
                                    Trace.Error($"RunnerUpdateNotification: {stderr.Data}");
                                }
                            }
                        };

                        try
                        {
                            await runnerUpdateInvoker.ExecuteAsync(
                                workingDirectory : HostContext.GetDirectory(WellKnownDirectory.Root),
                                fileName : WhichUtil.Which("bash"),
                                arguments : $"-c \"{runnerUpdateNotification} RUNNERUPDATE {DateTime.UtcNow.ToString("O")}\"",
                                environment : null,
                                requireExitCodeZero : true,
                                outputEncoding : null,
                                killProcessOnCancel : true,
                                redirectStandardIn : null,
                                inheritConsoleHandler : false,
                                keepStandardInOpen : false,
                                highPriorityProcess : true,
                                cancellationToken : new CancellationTokenSource(10000).Token);
                        }
                        catch (Exception ex)
                        {
                            Trace.Error($"Fail to publish RunnerUpdate notification: {ex}");
                        }
                    }
                }
                // Print console line that warn user not shutdown runner.
                await UpdateRunnerUpdateStateAsync("Runner update in progress, do not shutdown runner.");
                await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner");

                await DownloadLatestRunner(token);

                Trace.Info($"Download latest runner and unzip into runner root.");

                // wait till all running job finish
                await UpdateRunnerUpdateStateAsync("Waiting for current job finish running.");

                await jobDispatcher.WaitAsync(token);

                Trace.Info($"All running job has exited.");

                // delete runner backup
                DeletePreviousVersionRunnerBackup(token);
                Trace.Info($"Delete old version runner backup.");

                // generate update script from template
                await UpdateRunnerUpdateStateAsync("Generate and execute update script.");

                string updateScript = GenerateUpdateScript(restartInteractiveRunner);
                Trace.Info($"Generate update script into: {updateScript}");

                // kick off update script
                Process invokeScript = new Process();
#if OS_WINDOWS
                invokeScript.StartInfo.FileName  = WhichUtil.Which("cmd.exe", trace: Trace);
                invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
#elif (OS_OSX || OS_LINUX)
                invokeScript.StartInfo.FileName  = WhichUtil.Which("bash", trace: Trace);
                invokeScript.StartInfo.Arguments = $"\"{updateScript}\"";
#endif
                invokeScript.Start();
                Trace.Info($"Update script start running");

                await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should back online within 10 seconds.");

                return(true);
            }
            finally
            {
                Busy = false;
            }
        }
Пример #5
0
        public async Task <bool> SelfUpdate(AgentRefreshMessage updateMessage, IJobDispatcher jobDispatcher, bool restartInteractiveRunner, CancellationToken token)
        {
            Busy = true;
            try
            {
                var totalUpdateTime = Stopwatch.StartNew();

                if (!await UpdateNeeded(updateMessage.TargetVersion, token))
                {
                    Trace.Info($"Can't find available update package.");
                    return(false);
                }

                Trace.Info($"An update is available.");
                _updateTrace.Add($"RunnerPlatform: {_targetPackage.Platform}");

                // RUST: disable self-updates
                var rustAvoidUnreachableCodeError = true;
                if (rustAvoidUnreachableCodeError)
                {
                    Console.WriteLine("RUST: prevented self-update");
                    return(false);
                }

                // Print console line that warn user not shutdown runner.
                await UpdateRunnerUpdateStateAsync("Runner update in progress, do not shutdown runner.");
                await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner");

                await DownloadLatestRunner(token);

                Trace.Info($"Download latest runner and unzip into runner root.");

                // wait till all running job finish
                await UpdateRunnerUpdateStateAsync("Waiting for current job finish running.");

                await jobDispatcher.WaitAsync(token);

                Trace.Info($"All running job has exited.");

                // We need to keep runner backup around for macOS until we fixed https://github.com/actions/runner/issues/743
                // delete runner backup
                var stopWatch = Stopwatch.StartNew();
                DeletePreviousVersionRunnerBackup(token);
                Trace.Info($"Delete old version runner backup.");
                stopWatch.Stop();
                // generate update script from template
                _updateTrace.Add($"DeleteRunnerBackupTime: {stopWatch.ElapsedMilliseconds}ms");
                await UpdateRunnerUpdateStateAsync("Generate and execute update script.");

                string updateScript = GenerateUpdateScript(restartInteractiveRunner);
                Trace.Info($"Generate update script into: {updateScript}");

                // kick off update script
                Process invokeScript = new Process();
#if OS_WINDOWS
                invokeScript.StartInfo.FileName  = WhichUtil.Which("cmd.exe", trace: Trace);
                invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
#elif (OS_OSX || OS_LINUX)
                invokeScript.StartInfo.FileName  = WhichUtil.Which("bash", trace: Trace);
                invokeScript.StartInfo.Arguments = $"\"{updateScript}\"";
#endif
                invokeScript.Start();
                Trace.Info($"Update script start running");

                totalUpdateTime.Stop();

                _updateTrace.Add($"TotalUpdateTime: {totalUpdateTime.ElapsedMilliseconds}ms");
                await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should be back online within 10 seconds.");

                return(true);
            }
            catch (Exception ex)
            {
                _updateTrace.Add(ex.ToString());
                throw;
            }
            finally
            {
                await UpdateRunnerUpdateStateAsync("Runner update process finished.");

                Busy = false;
            }
        }