Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support refresh runner configs with pipelines service. #3706

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 66 additions & 3 deletions src/Runner.Common/ConfigurationStore.cs
Original file line number Diff line number Diff line change
@@ -119,8 +119,11 @@ public interface IConfigurationStore : IRunnerService
CredentialData GetCredentials();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is basic add things back from https://github.com/actions/runner/pull/513/files#diff-8ef9a7b7967d070375a6e4773f2bbeb1ae60e986bff48a4171256ae1b3869872

and introduce migrated config file (.runner) in addition to the migrated credentials file (.credentials).

CredentialData GetMigratedCredentials();
RunnerSettings GetSettings();
RunnerSettings GetMigratedSettings();
void SaveCredential(CredentialData credential);
void SaveMigratedCredential(CredentialData credential);
void SaveSettings(RunnerSettings settings);
void SaveMigratedSettings(RunnerSettings settings);
void DeleteCredential();
void DeleteMigratedCredential();
void DeleteSettings();
@@ -130,13 +133,15 @@ public sealed class ConfigurationStore : RunnerService, IConfigurationStore
{
private string _binPath;
private string _configFilePath;
private string _migratedconfigFilePath;
private string _credFilePath;
private string _migratedCredFilePath;
private string _serviceConfigFilePath;

private CredentialData _creds;
private CredentialData _migratedCreds;
private RunnerSettings _settings;
private RunnerSettings _migratedSettings;

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

_migratedconfigFilePath = hostContext.GetConfigFile(WellKnownConfigFile.MigratedRunner);
Trace.Info("MigratedConfigFilePath: {0}", _migratedconfigFilePath);

_credFilePath = hostContext.GetConfigFile(WellKnownConfigFile.Credentials);
Trace.Info("CredFilePath: {0}", _credFilePath);

@@ -169,23 +177,23 @@ public override void Initialize(IHostContext hostContext)
public bool HasCredentials()
{
Trace.Info("HasCredentials()");
bool credsStored = (new FileInfo(_credFilePath)).Exists || (new FileInfo(_migratedCredFilePath)).Exists;
bool credsStored = new FileInfo(_credFilePath).Exists || new FileInfo(_migratedCredFilePath).Exists;
Trace.Info("stored {0}", credsStored);
return credsStored;
}

public bool IsConfigured()
{
Trace.Info("IsConfigured()");
bool configured = new FileInfo(_configFilePath).Exists;
bool configured = new FileInfo(_configFilePath).Exists || new FileInfo(_migratedconfigFilePath).Exists;
Trace.Info("IsConfigured: {0}", configured);
return configured;
}

public bool IsServiceConfigured()
{
Trace.Info("IsServiceConfigured()");
bool serviceConfigured = (new FileInfo(_serviceConfigFilePath)).Exists;
bool serviceConfigured = new FileInfo(_serviceConfigFilePath).Exists;
Trace.Info($"IsServiceConfigured: {serviceConfigured}");
return serviceConfigured;
}
@@ -229,6 +237,25 @@ public RunnerSettings GetSettings()
return _settings;
}

public RunnerSettings GetMigratedSettings()
{
if (_migratedSettings == null)
{
RunnerSettings configuredSettings = null;
if (File.Exists(_migratedconfigFilePath))
{
string json = File.ReadAllText(_migratedconfigFilePath, Encoding.UTF8);
Trace.Info($"Read migrated setting file: {json.Length} chars");
configuredSettings = StringUtil.ConvertFromJson<RunnerSettings>(json);
}

ArgUtil.NotNull(configuredSettings, nameof(configuredSettings));
_migratedSettings = configuredSettings;
}

return _migratedSettings;
}

public void SaveCredential(CredentialData credential)
{
Trace.Info("Saving {0} credential @ {1}", credential.Scheme, _credFilePath);
@@ -244,6 +271,21 @@ public void SaveCredential(CredentialData credential)
File.SetAttributes(_credFilePath, File.GetAttributes(_credFilePath) | FileAttributes.Hidden);
}

public void SaveMigratedCredential(CredentialData credential)
{
Trace.Info("Saving {0} migrated credential @ {1}", credential.Scheme, _migratedCredFilePath);
if (File.Exists(_migratedCredFilePath))
{
// Delete existing credential file first, since the file is hidden and not able to overwrite.
Trace.Info("Delete exist runner migrated credential file.");
IOUtil.DeleteFile(_migratedCredFilePath);
}

IOUtil.SaveObject(credential, _migratedCredFilePath);
Trace.Info("Migrated Credentials Saved.");
File.SetAttributes(_migratedCredFilePath, File.GetAttributes(_migratedCredFilePath) | FileAttributes.Hidden);
}

public void SaveSettings(RunnerSettings settings)
{
Trace.Info("Saving runner settings.");
@@ -259,6 +301,21 @@ public void SaveSettings(RunnerSettings settings)
File.SetAttributes(_configFilePath, File.GetAttributes(_configFilePath) | FileAttributes.Hidden);
}

public void SaveMigratedSettings(RunnerSettings settings)
{
Trace.Info("Saving runner migrated settings");
if (File.Exists(_migratedconfigFilePath))
{
// Delete existing settings file first, since the file is hidden and not able to overwrite.
Trace.Info("Delete exist runner migrated settings file.");
IOUtil.DeleteFile(_migratedconfigFilePath);
}

IOUtil.SaveObject(settings, _migratedconfigFilePath);
Trace.Info("Migrated Settings Saved.");
File.SetAttributes(_migratedconfigFilePath, File.GetAttributes(_migratedconfigFilePath) | FileAttributes.Hidden);
}

public void DeleteCredential()
{
IOUtil.Delete(_credFilePath, default(CancellationToken));
@@ -273,6 +330,12 @@ public void DeleteMigratedCredential()
public void DeleteSettings()
{
IOUtil.Delete(_configFilePath, default(CancellationToken));
IOUtil.Delete(_migratedconfigFilePath, default(CancellationToken));
}

public void DeleteMigratedSettings()
{
IOUtil.Delete(_migratedconfigFilePath, default(CancellationToken));
}
}
}
1 change: 1 addition & 0 deletions src/Runner.Common/Constants.cs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ public enum WellKnownDirectory
public enum WellKnownConfigFile
{
Runner,
MigratedRunner,
Credentials,
MigratedCredentials,
RSACredentials,
6 changes: 6 additions & 0 deletions src/Runner.Common/HostContext.cs
Original file line number Diff line number Diff line change
@@ -343,6 +343,12 @@ public string GetConfigFile(WellKnownConfigFile configFile)
".runner");
break;

case WellKnownConfigFile.MigratedRunner:
path = Path.Combine(
GetDirectory(WellKnownDirectory.Root),
".runner_migrated");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are going to reuse .credentials_migrated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

break;

case WellKnownConfigFile.Credentials:
path = Path.Combine(
GetDirectory(WellKnownDirectory.Root),
24 changes: 17 additions & 7 deletions src/Runner.Common/RunnerServer.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using GitHub.DistributedTask.WebApi;
using System;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using GitHub.Services.WebApi;
using GitHub.Services.Common;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Sdk;
using GitHub.Services.Common;
using GitHub.Services.WebApi;

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

// agent update
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace);
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace, CancellationToken cancellationToken = default);

// runner config refresh
Task<string> RefreshRunnerConfigAsync(int agentId, string configType, string encodedRunnerConfig, CancellationToken cancellationToken);
}

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

public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only add cancellation token

public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, ulong agentId, string currentState, string trace, CancellationToken cancellationToken = default)
{
CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace, cancellationToken: cancellationToken);
}

// runner config refresh
public Task<string> RefreshRunnerConfigAsync(int agentId, string configType, string encodedRunnerConfig, CancellationToken cancellationToken)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace);
return _genericTaskAgentClient.RefreshRunnerConfigAsync(agentId, configType, encodedRunnerConfig, cancellationToken: cancellationToken);
}
}
}
3 changes: 2 additions & 1 deletion src/Runner.Listener/MessageListener.cs
Original file line number Diff line number Diff line change
@@ -528,7 +528,8 @@ private bool IsSessionCreationExceptionRetriable(Exception ex)
}
else if (ex is TaskAgentPoolNotFoundException ||
ex is AccessDeniedException ||
ex is VssUnauthorizedException)
ex is VssUnauthorizedException ||
(ex is VssOAuthTokenRequestException oauthEx && oauthEx.Error != "server_error"))
{
Trace.Info($"Non-retriable exception: {ex.Message}");
return false;
11 changes: 11 additions & 0 deletions src/Runner.Listener/Runner.cs
Original file line number Diff line number Diff line change
@@ -635,6 +635,17 @@ ex is TaskOrchestrationJobAlreadyAcquiredException || // HTTP status 409
Trace.Info("Received ForceTokenRefreshMessage");
await _listener.RefreshListenerTokenAsync(messageQueueLoopTokenSource.Token);
}
else if (string.Equals(message.MessageType, RunnerRefreshConfigMessage.MessageType))
{
var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
Trace.Info($"Received RunnerRefreshConfigMessage for '{runnerRefreshConfigMessage.ConfigType}' config file");
var configUpdater = HostContext.GetService<IRunnerConfigUpdater>();
await configUpdater.UpdateRunnerConfigAsync(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UpdateRunnerConfigAsync does not throw.

runnerQualifiedId: runnerRefreshConfigMessage.RunnerQualifiedId,
configType: runnerRefreshConfigMessage.ConfigType,
serviceType: runnerRefreshConfigMessage.ServiceType,
configRefreshUrl: runnerRefreshConfigMessage.ConfigRefreshUrl);
}
else
{
Trace.Error($"Received message {message.MessageId} with unsupported message type {message.MessageType}.");
Loading
Oops, something went wrong.