Skip to content

Commit f5e4e7e

Browse files
authored
Support refresh runner configs with pipelines service. (#3706)
1 parent 68ca457 commit f5e4e7e

13 files changed

+1059
-21
lines changed

src/Runner.Common/ConfigurationStore.cs

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,11 @@ public interface IConfigurationStore : IRunnerService
119119
CredentialData GetCredentials();
120120
CredentialData GetMigratedCredentials();
121121
RunnerSettings GetSettings();
122+
RunnerSettings GetMigratedSettings();
122123
void SaveCredential(CredentialData credential);
124+
void SaveMigratedCredential(CredentialData credential);
123125
void SaveSettings(RunnerSettings settings);
126+
void SaveMigratedSettings(RunnerSettings settings);
124127
void DeleteCredential();
125128
void DeleteMigratedCredential();
126129
void DeleteSettings();
@@ -130,13 +133,15 @@ public sealed class ConfigurationStore : RunnerService, IConfigurationStore
130133
{
131134
private string _binPath;
132135
private string _configFilePath;
136+
private string _migratedConfigFilePath;
133137
private string _credFilePath;
134138
private string _migratedCredFilePath;
135139
private string _serviceConfigFilePath;
136140

137141
private CredentialData _creds;
138142
private CredentialData _migratedCreds;
139143
private RunnerSettings _settings;
144+
private RunnerSettings _migratedSettings;
140145

141146
public override void Initialize(IHostContext hostContext)
142147
{
@@ -154,6 +159,9 @@ public override void Initialize(IHostContext hostContext)
154159
_configFilePath = hostContext.GetConfigFile(WellKnownConfigFile.Runner);
155160
Trace.Info("ConfigFilePath: {0}", _configFilePath);
156161

162+
_migratedConfigFilePath = hostContext.GetConfigFile(WellKnownConfigFile.MigratedRunner);
163+
Trace.Info("MigratedConfigFilePath: {0}", _migratedConfigFilePath);
164+
157165
_credFilePath = hostContext.GetConfigFile(WellKnownConfigFile.Credentials);
158166
Trace.Info("CredFilePath: {0}", _credFilePath);
159167

@@ -169,23 +177,23 @@ public override void Initialize(IHostContext hostContext)
169177
public bool HasCredentials()
170178
{
171179
Trace.Info("HasCredentials()");
172-
bool credsStored = (new FileInfo(_credFilePath)).Exists || (new FileInfo(_migratedCredFilePath)).Exists;
180+
bool credsStored = new FileInfo(_credFilePath).Exists || new FileInfo(_migratedCredFilePath).Exists;
173181
Trace.Info("stored {0}", credsStored);
174182
return credsStored;
175183
}
176184

177185
public bool IsConfigured()
178186
{
179187
Trace.Info("IsConfigured()");
180-
bool configured = new FileInfo(_configFilePath).Exists;
188+
bool configured = new FileInfo(_configFilePath).Exists || new FileInfo(_migratedConfigFilePath).Exists;
181189
Trace.Info("IsConfigured: {0}", configured);
182190
return configured;
183191
}
184192

185193
public bool IsServiceConfigured()
186194
{
187195
Trace.Info("IsServiceConfigured()");
188-
bool serviceConfigured = (new FileInfo(_serviceConfigFilePath)).Exists;
196+
bool serviceConfigured = new FileInfo(_serviceConfigFilePath).Exists;
189197
Trace.Info($"IsServiceConfigured: {serviceConfigured}");
190198
return serviceConfigured;
191199
}
@@ -229,6 +237,25 @@ public RunnerSettings GetSettings()
229237
return _settings;
230238
}
231239

240+
public RunnerSettings GetMigratedSettings()
241+
{
242+
if (_migratedSettings == null)
243+
{
244+
RunnerSettings configuredSettings = null;
245+
if (File.Exists(_migratedConfigFilePath))
246+
{
247+
string json = File.ReadAllText(_migratedConfigFilePath, Encoding.UTF8);
248+
Trace.Info($"Read migrated setting file: {json.Length} chars");
249+
configuredSettings = StringUtil.ConvertFromJson<RunnerSettings>(json);
250+
}
251+
252+
ArgUtil.NotNull(configuredSettings, nameof(configuredSettings));
253+
_migratedSettings = configuredSettings;
254+
}
255+
256+
return _migratedSettings;
257+
}
258+
232259
public void SaveCredential(CredentialData credential)
233260
{
234261
Trace.Info("Saving {0} credential @ {1}", credential.Scheme, _credFilePath);
@@ -244,6 +271,21 @@ public void SaveCredential(CredentialData credential)
244271
File.SetAttributes(_credFilePath, File.GetAttributes(_credFilePath) | FileAttributes.Hidden);
245272
}
246273

274+
public void SaveMigratedCredential(CredentialData credential)
275+
{
276+
Trace.Info("Saving {0} migrated credential @ {1}", credential.Scheme, _migratedCredFilePath);
277+
if (File.Exists(_migratedCredFilePath))
278+
{
279+
// Delete existing credential file first, since the file is hidden and not able to overwrite.
280+
Trace.Info("Delete exist runner migrated credential file.");
281+
IOUtil.DeleteFile(_migratedCredFilePath);
282+
}
283+
284+
IOUtil.SaveObject(credential, _migratedCredFilePath);
285+
Trace.Info("Migrated Credentials Saved.");
286+
File.SetAttributes(_migratedCredFilePath, File.GetAttributes(_migratedCredFilePath) | FileAttributes.Hidden);
287+
}
288+
247289
public void SaveSettings(RunnerSettings settings)
248290
{
249291
Trace.Info("Saving runner settings.");
@@ -259,6 +301,21 @@ public void SaveSettings(RunnerSettings settings)
259301
File.SetAttributes(_configFilePath, File.GetAttributes(_configFilePath) | FileAttributes.Hidden);
260302
}
261303

304+
public void SaveMigratedSettings(RunnerSettings settings)
305+
{
306+
Trace.Info("Saving runner migrated settings");
307+
if (File.Exists(_migratedConfigFilePath))
308+
{
309+
// Delete existing settings file first, since the file is hidden and not able to overwrite.
310+
Trace.Info("Delete exist runner migrated settings file.");
311+
IOUtil.DeleteFile(_migratedConfigFilePath);
312+
}
313+
314+
IOUtil.SaveObject(settings, _migratedConfigFilePath);
315+
Trace.Info("Migrated Settings Saved.");
316+
File.SetAttributes(_migratedConfigFilePath, File.GetAttributes(_migratedConfigFilePath) | FileAttributes.Hidden);
317+
}
318+
262319
public void DeleteCredential()
263320
{
264321
IOUtil.Delete(_credFilePath, default(CancellationToken));
@@ -273,6 +330,12 @@ public void DeleteMigratedCredential()
273330
public void DeleteSettings()
274331
{
275332
IOUtil.Delete(_configFilePath, default(CancellationToken));
333+
IOUtil.Delete(_migratedConfigFilePath, default(CancellationToken));
334+
}
335+
336+
public void DeleteMigratedSettings()
337+
{
338+
IOUtil.Delete(_migratedConfigFilePath, default(CancellationToken));
276339
}
277340
}
278341
}

src/Runner.Common/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public enum WellKnownDirectory
1818
public enum WellKnownConfigFile
1919
{
2020
Runner,
21+
MigratedRunner,
2122
Credentials,
2223
MigratedCredentials,
2324
RSACredentials,

src/Runner.Common/HostContext.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@ public string GetConfigFile(WellKnownConfigFile configFile)
343343
".runner");
344344
break;
345345

346+
case WellKnownConfigFile.MigratedRunner:
347+
path = Path.Combine(
348+
GetDirectory(WellKnownDirectory.Root),
349+
".runner_migrated");
350+
break;
351+
346352
case WellKnownConfigFile.Credentials:
347353
path = Path.Combine(
348354
GetDirectory(WellKnownDirectory.Root),

src/Runner.Common/RunnerServer.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
using GitHub.DistributedTask.WebApi;
2-
using System;
1+
using System;
32
using System.Collections.Generic;
43
using System.Threading;
54
using System.Threading.Tasks;
6-
using GitHub.Services.WebApi;
7-
using GitHub.Services.Common;
5+
using GitHub.DistributedTask.WebApi;
86
using GitHub.Runner.Sdk;
7+
using GitHub.Services.Common;
8+
using GitHub.Services.WebApi;
99

1010
namespace GitHub.Runner.Common
1111
{
@@ -50,7 +50,10 @@ public interface IRunnerServer : IRunnerService
5050
Task<PackageMetadata> GetPackageAsync(string packageType, string platform, string version, bool includeToken, CancellationToken cancellationToken);
5151

5252
// agent update
53-
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace);
53+
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace, CancellationToken cancellationToken = default);
54+
55+
// runner config refresh
56+
Task<string> RefreshRunnerConfigAsync(int agentId, string configType, string encodedRunnerConfig, CancellationToken cancellationToken);
5457
}
5558

5659
public sealed class RunnerServer : RunnerService, IRunnerServer
@@ -315,10 +318,17 @@ public Task<PackageMetadata> GetPackageAsync(string packageType, string platform
315318
return _genericTaskAgentClient.GetPackageAsync(packageType, platform, version, includeToken, cancellationToken: cancellationToken);
316319
}
317320

318-
public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace)
321+
public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace, CancellationToken cancellationToken = default)
322+
{
323+
CheckConnection(RunnerConnectionType.Generic);
324+
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace, cancellationToken: cancellationToken);
325+
}
326+
327+
// runner config refresh
328+
public Task<string> RefreshRunnerConfigAsync(int agentId, string configType, string encodedRunnerConfig, CancellationToken cancellationToken)
319329
{
320330
CheckConnection(RunnerConnectionType.Generic);
321-
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace);
331+
return _genericTaskAgentClient.RefreshRunnerConfigAsync(agentId, configType, encodedRunnerConfig, cancellationToken: cancellationToken);
322332
}
323333
}
324334
}

src/Runner.Listener/MessageListener.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,8 @@ private bool IsSessionCreationExceptionRetriable(Exception ex)
533533
}
534534
else if (ex is TaskAgentPoolNotFoundException ||
535535
ex is AccessDeniedException ||
536-
ex is VssUnauthorizedException)
536+
ex is VssUnauthorizedException ||
537+
(ex is VssOAuthTokenRequestException oauthEx && oauthEx.Error != "server_error"))
537538
{
538539
Trace.Info($"Non-retriable exception: {ex.Message}");
539540
return false;

src/Runner.Listener/Runner.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,17 @@ ex is TaskOrchestrationJobAlreadyAcquiredException || // HTTP status 409
635635
Trace.Info("Received ForceTokenRefreshMessage");
636636
await _listener.RefreshListenerTokenAsync(messageQueueLoopTokenSource.Token);
637637
}
638+
else if (string.Equals(message.MessageType, RunnerRefreshConfigMessage.MessageType))
639+
{
640+
var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
641+
Trace.Info($"Received RunnerRefreshConfigMessage for '{runnerRefreshConfigMessage.ConfigType}' config file");
642+
var configUpdater = HostContext.GetService<IRunnerConfigUpdater>();
643+
await configUpdater.UpdateRunnerConfigAsync(
644+
runnerQualifiedId: runnerRefreshConfigMessage.RunnerQualifiedId,
645+
configType: runnerRefreshConfigMessage.ConfigType,
646+
serviceType: runnerRefreshConfigMessage.ServiceType,
647+
configRefreshUrl: runnerRefreshConfigMessage.ConfigRefreshUrl);
648+
}
638649
else
639650
{
640651
Trace.Error($"Received message {message.MessageId} with unsupported message type {message.MessageType}.");

0 commit comments

Comments
 (0)