public async Task <Boolean> CreateSessionAsync(CancellationToken token) { Trace.Entering(); // Settings var configManager = HostContext.GetService <IConfigurationManager>(); _settings = configManager.LoadSettings(); var serverUrl = _settings.ServerUrl; Trace.Info(_settings); // Create connection. Trace.Info("Loading Credentials"); var credMgr = HostContext.GetService <ICredentialManager>(); VssCredentials creds = credMgr.LoadCredentials(); var agent = new TaskAgentReference { Id = _settings.AgentId, Name = _settings.AgentName, Version = BuildConstants.RunnerPackage.Version, OSDescription = RuntimeInformation.OSDescription, }; string sessionName = $"{Environment.MachineName ?? "RUNNER"}"; var taskAgentSession = new TaskAgentSession(sessionName, agent); string errorMessage = string.Empty; bool encounteringError = false; while (true) { token.ThrowIfCancellationRequested(); Trace.Info($"Attempt to create session."); try { Trace.Info("Connecting to the Runner Server..."); await _runnerServer.ConnectAsync(new Uri(serverUrl), creds); Trace.Info("VssConnection created"); _term.WriteLine(); _term.WriteSuccessMessage("Connected to GitHub"); _term.WriteLine(); _session = await _runnerServer.CreateAgentSessionAsync( _settings.PoolId, taskAgentSession, token); Trace.Info($"Session created."); if (encounteringError) { _term.WriteLine($"{DateTime.UtcNow:u}: Runner reconnected."); _sessionCreationExceptionTracker.Clear(); encounteringError = false; } return(true); } catch (OperationCanceledException) when(token.IsCancellationRequested) { Trace.Info("Session creation has been cancelled."); throw; } catch (TaskAgentAccessTokenExpiredException) { Trace.Info("Runner OAuth token has been revoked. Session creation failed."); throw; } catch (Exception ex) { Trace.Error("Catch exception during create session."); Trace.Error(ex); if (ex is VssOAuthTokenRequestException && creds.Federated is VssOAuthCredential vssOAuthCred) { // Check whether we get 401 because the runner registration already removed by the service. // If the runner registration get deleted, we can't exchange oauth token. Trace.Error("Test oauth app registration."); var oauthTokenProvider = new VssOAuthTokenProvider(vssOAuthCred, new Uri(serverUrl)); var authError = await oauthTokenProvider.ValidateCredentialAsync(token); if (string.Equals(authError, "invalid_client", StringComparison.OrdinalIgnoreCase)) { _term.WriteError("Failed to create a session. The runner registration has been deleted from the server, please re-configure."); return(false); } } if (!IsSessionCreationExceptionRetriable(ex)) { _term.WriteError($"Failed to create session. {ex.Message}"); return(false); } if (!encounteringError) //print the message only on the first error { _term.WriteError($"{DateTime.UtcNow:u}: Runner connect error: {ex.Message}. Retrying until reconnected."); encounteringError = true; } Trace.Info("Sleeping for {0} seconds before retrying.", _sessionCreationRetryInterval.TotalSeconds); await HostContext.Delay(_sessionCreationRetryInterval, token); } } }
public async Task <Boolean> CreateSessionAsync(CancellationToken token) { Trace.Entering(); // Settings var configManager = HostContext.GetService <IConfigurationManager>(); _settings = configManager.LoadSettings(); var serverUrl = _settings.ServerUrl; Trace.Info(_settings); // Create connection. Trace.Info("Loading Credentials"); _useMigratedCredentials = !StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_SPSAUTHURL")); VssCredentials creds = _credMgr.LoadCredentials(_useMigratedCredentials); var agent = new TaskAgentReference { Id = _settings.AgentId, Name = _settings.AgentName, Version = BuildConstants.RunnerPackage.Version, OSDescription = RuntimeInformation.OSDescription, }; string sessionName = $"{Environment.MachineName ?? "RUNNER"}"; var taskAgentSession = new TaskAgentSession(sessionName, agent); string errorMessage = string.Empty; bool encounteringError = false; var originalCreds = _configStore.GetCredentials(); var migratedCreds = _configStore.GetMigratedCredentials(); if (migratedCreds == null) { _useMigratedCredentials = false; if (originalCreds.Scheme == Constants.Configuration.OAuth) { _needToCheckAuthorizationUrlUpdate = true; } } while (true) { token.ThrowIfCancellationRequested(); Trace.Info($"Attempt to create session."); try { Trace.Info("Connecting to the Runner Server..."); await _runnerServer.ConnectAsync(new Uri(serverUrl), creds); Trace.Info("VssConnection created"); _term.WriteLine(); _term.WriteSuccessMessage("Connected to GitHub"); _term.WriteLine(); _session = await _runnerServer.CreateAgentSessionAsync( _settings.PoolId, taskAgentSession, token); Trace.Info($"Session created."); if (encounteringError) { _term.WriteLine($"{DateTime.UtcNow:u}: Runner reconnected."); _sessionCreationExceptionTracker.Clear(); encounteringError = false; } if (_needToCheckAuthorizationUrlUpdate) { // start background task try to get new authorization url _authorizationUrlMigrationBackgroundTask = GetNewOAuthAuthorizationSetting(token); } return(true); } catch (OperationCanceledException) when(token.IsCancellationRequested) { Trace.Info("Session creation has been cancelled."); throw; } catch (TaskAgentAccessTokenExpiredException) { Trace.Info("Runner OAuth token has been revoked. Session creation failed."); throw; } catch (Exception ex) { Trace.Error("Catch exception during create session."); Trace.Error(ex); if (ex is VssOAuthTokenRequestException && creds.Federated is VssOAuthCredential vssOAuthCred) { // Check whether we get 401 because the runner registration already removed by the service. // If the runner registration get deleted, we can't exchange oauth token. Trace.Error("Test oauth app registration."); var oauthTokenProvider = new VssOAuthTokenProvider(vssOAuthCred, new Uri(serverUrl)); var authError = await oauthTokenProvider.ValidateCredentialAsync(token); if (string.Equals(authError, "invalid_client", StringComparison.OrdinalIgnoreCase)) { _term.WriteError("Failed to create a session. The runner registration has been deleted from the server, please re-configure."); return(false); } } if (!IsSessionCreationExceptionRetriable(ex)) { if (_useMigratedCredentials) { // migrated credentials might cause lose permission during permission check, // we will force to use original credential and try again _useMigratedCredentials = false; var reattemptBackoff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromHours(24), TimeSpan.FromHours(36)); _authorizationUrlRollbackReattemptDelayBackgroundTask = HostContext.Delay(reattemptBackoff, token); // retry migrated creds in 24-36 hours. creds = _credMgr.LoadCredentials(false); Trace.Error("Fallback to original credentials and try again."); } else { _term.WriteError($"Failed to create session. {ex.Message}"); return(false); } } if (!encounteringError) //print the message only on the first error { _term.WriteError($"{DateTime.UtcNow:u}: Runner connect error: {ex.Message}. Retrying until reconnected."); encounteringError = true; } Trace.Info("Sleeping for {0} seconds before retrying.", _sessionCreationRetryInterval.TotalSeconds); await HostContext.Delay(_sessionCreationRetryInterval, token); } } }