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; } }
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); }
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); }
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; } }
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; } }