diff --git a/src/Runner.Common/RunnerDotcomServer.cs b/src/Runner.Common/RunnerDotcomServer.cs index 77fdaf88e..41cc0816d 100644 --- a/src/Runner.Common/RunnerDotcomServer.cs +++ b/src/Runner.Common/RunnerDotcomServer.cs @@ -17,7 +17,7 @@ namespace GitHub.Runner.Common { Task> GetRunnersAsync(int runnerGroupId, string githubUrl, string githubToken, string agentName); - Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken, string publicKey, string hostId); + Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken, string publicKey); Task> GetRunnerGroupsAsync(string githubUrl, string githubToken); string GetGitHubRequestId(HttpResponseHeaders headers); @@ -136,7 +136,7 @@ namespace GitHub.Runner.Common return agentPools?.ToAgentPoolList(); } - public async Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken, string publicKey, string hostId) + public async Task AddRunnerAsync(int runnerGroupId, TaskAgent agent, string githubUrl, string githubToken, string publicKey) { var gitHubUrlBuilder = new UriBuilder(githubUrl); var path = gitHubUrlBuilder.Path.Split('/', '\\', StringSplitOptions.RemoveEmptyEntries); @@ -159,20 +159,12 @@ namespace GitHub.Runner.Common {"updates_disabled", agent.DisableUpdate}, {"ephemeral", agent.Ephemeral}, {"labels", agent.Labels}, - {"public_key", publicKey}, - {"host_id", hostId}, + {"public_key", publicKey} }; var body = new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"); - var runner = await RetryRequest(githubApiUrl, githubToken, RequestType.Post, 3, "Failed to add agent", body); - agent.Id = runner.Id; - agent.Authorization = new TaskAgentAuthorization() - { - AuthorizationUrl = runner.RunnerAuthorization.AuthorizationUrl, - ClientId = new Guid(runner.RunnerAuthorization.ClientId), - }; - return agent; + return await RetryRequest(githubApiUrl, githubToken, RequestType.Post, 3, "Failed to add agent", body); } private async Task RetryRequest(string githubApiUrl, string githubToken, RequestType requestType, int maxRetryAttemptsCount = 5, string errorMessage = null, StringContent body = null) diff --git a/src/Runner.Listener/BrokerMessageListener.cs b/src/Runner.Listener/BrokerMessageListener.cs index 93259c8e5..aa3e81886 100644 --- a/src/Runner.Listener/BrokerMessageListener.cs +++ b/src/Runner.Listener/BrokerMessageListener.cs @@ -196,6 +196,11 @@ namespace GitHub.Runner.Listener var configManager = HostContext.GetService(); _settings = configManager.LoadSettings(); + if (_settings.ServerUrlV2 == null) + { + throw new InvalidOperationException("ServerUrlV2 is not set"); + } + var credMgr = HostContext.GetService(); VssCredentials creds = credMgr.LoadCredentials(); await _brokerServer.ConnectAsync(new Uri(_settings.ServerUrlV2), creds); diff --git a/src/Runner.Listener/Configuration/ConfigurationManager.cs b/src/Runner.Listener/Configuration/ConfigurationManager.cs index 327879474..9fb9e5b3a 100644 --- a/src/Runner.Listener/Configuration/ConfigurationManager.cs +++ b/src/Runner.Listener/Configuration/ConfigurationManager.cs @@ -117,7 +117,6 @@ namespace GitHub.Runner.Listener.Configuration VssCredentials creds = null; _term.WriteSection("Authentication"); string registerToken = string.Empty; - string hostId = string.Empty; while (true) { // When testing against a dev deployment of Actions Service, set this environment variable @@ -142,7 +141,6 @@ namespace GitHub.Runner.Listener.Configuration _term.WriteLine($"Using V2 flow: {runnerSettings.UseV2Flow}"); creds = authResult.ToVssCredentials(); Trace.Info("cred retrieved via GitHub auth"); - hostId = GetHostId(authResult.Token); } try @@ -302,7 +300,9 @@ namespace GitHub.Runner.Listener.Configuration { if (runnerSettings.UseV2Flow) { - agent = await _dotcomServer.AddRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML, hostId); + var runner = await _dotcomServer.AddRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML); + runner.ApplyToTaskAgent(agent); + runnerSettings.ServerUrlV2 = runner.RunnerAuthorization.ServerUrl; } else { @@ -359,24 +359,28 @@ namespace GitHub.Runner.Listener.Configuration } // Testing agent connection, detect any potential connection issue, like local clock skew that cause OAuth token expired. - var credMgr = HostContext.GetService(); - VssCredentials credential = credMgr.LoadCredentials(); - try + + if (!runnerSettings.UseV2Flow) { - await _runnerServer.ConnectAsync(new Uri(runnerSettings.ServerUrl), credential); - // ConnectAsync() hits _apis/connectionData which is an anonymous endpoint - // Need to hit an authenticate endpoint to trigger OAuth token exchange. - await _runnerServer.GetAgentPoolsAsync(); - _term.WriteSuccessMessage("Runner connection is good"); - } - catch (VssOAuthTokenRequestException ex) when (ex.Message.Contains("Current server time is")) - { - // there are two exception messages server send that indicate clock skew. - // 1. The bearer token expired on {jwt.ValidTo}. Current server time is {DateTime.UtcNow}. - // 2. The bearer token is not valid until {jwt.ValidFrom}. Current server time is {DateTime.UtcNow}. - Trace.Error("Catch exception during test agent connection."); - Trace.Error(ex); - throw new Exception("The local machine's clock may be out of sync with the server time by more than five minutes. Please sync your clock with your domain or internet time and try again."); + var credMgr = HostContext.GetService(); + VssCredentials credential = credMgr.LoadCredentials(); + try + { + await _runnerServer.ConnectAsync(new Uri(runnerSettings.ServerUrl), credential); + // ConnectAsync() hits _apis/connectionData which is an anonymous endpoint + // Need to hit an authenticate endpoint to trigger OAuth token exchange. + await _runnerServer.GetAgentPoolsAsync(); + _term.WriteSuccessMessage("Runner connection is good"); + } + catch (VssOAuthTokenRequestException ex) when (ex.Message.Contains("Current server time is")) + { + // there are two exception messages server send that indicate clock skew. + // 1. The bearer token expired on {jwt.ValidTo}. Current server time is {DateTime.UtcNow}. + // 2. The bearer token is not valid until {jwt.ValidFrom}. Current server time is {DateTime.UtcNow}. + Trace.Error("Catch exception during test agent connection."); + Trace.Error(ex); + throw new Exception("The local machine's clock may be out of sync with the server time by more than five minutes. Please sync your clock with your domain or internet time and try again."); + } } _term.WriteSection("Runner settings"); @@ -778,12 +782,5 @@ namespace GitHub.Runner.Listener.Configuration } return null; } - - // Temporary hack for sending legacy host id using v2 flow - private string GetHostId(string accessToken) - { - var claims = JsonWebToken.Create(accessToken).ExtractClaims(); - return claims.FirstOrDefault(x => x.Type == "aud").Value.Split(':').LastOrDefault(); - } } } diff --git a/src/Sdk/DTWebApi/WebApi/Runner.cs b/src/Sdk/DTWebApi/WebApi/Runner.cs index 7e981bc97..41a3ad3ac 100644 --- a/src/Sdk/DTWebApi/WebApi/Runner.cs +++ b/src/Sdk/DTWebApi/WebApi/Runner.cs @@ -8,6 +8,9 @@ namespace GitHub.DistributedTask.WebApi public class Authorization { + /// + /// The url to refresh tokens + /// [JsonProperty("authorization_url")] public Uri AuthorizationUrl { @@ -15,6 +18,19 @@ namespace GitHub.DistributedTask.WebApi internal set; } + /// + /// The url to connect to to poll for messages + /// + [JsonProperty("server_url")] + public string ServerUrl + { + get; + internal set; + } + + /// + /// The client id to use when connecting to the authorization_url + /// [JsonProperty("client_id")] public string ClientId { @@ -43,5 +59,16 @@ namespace GitHub.DistributedTask.WebApi get; internal set; } + + public TaskAgent ApplyToTaskAgent(TaskAgent agent) + { + agent.Id = this.Id; + agent.Authorization = new TaskAgentAuthorization() + { + AuthorizationUrl = this.RunnerAuthorization.AuthorizationUrl, + ClientId = new Guid(this.RunnerAuthorization.ClientId) + }; + return agent; + } } }