Skip to content

Commit eeb0cf6

Browse files
Add --no-default-labels config option to self-hosted runners (#2443)
* Add --no-default-labels option Signed-off-by: Gabriel Adrian Samfira <[email protected]> * Add tests Signed-off-by: Gabriel Adrian Samfira <[email protected]> * . --------- Signed-off-by: Gabriel Adrian Samfira <[email protected]> Co-authored-by: Tingluo Huang <[email protected]>
1 parent f8a28c3 commit eeb0cf6

File tree

5 files changed

+133
-14
lines changed

5 files changed

+133
-14
lines changed

src/Runner.Common/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ public static class Flags
132132
public static readonly string GenerateServiceConfig = "generateServiceConfig";
133133
public static readonly string Help = "help";
134134
public static readonly string Local = "local";
135+
public static readonly string NoDefaultLabels = "no-default-labels";
135136
public static readonly string Replace = "replace";
136137
public static readonly string DisableUpdate = "disableupdate";
137138
public static readonly string Once = "once"; // Keep this around since customers still relies on it

src/Runner.Listener/CommandSettings.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,16 @@ public sealed class CommandSettings
2929
private readonly Dictionary<string, string[]> validOptions = new()
3030
{
3131
// Valid configure flags and args
32-
[Constants.Runner.CommandLine.Commands.Configure] =
33-
new string[]
32+
[Constants.Runner.CommandLine.Commands.Configure] =
33+
new string[]
3434
{
3535
Constants.Runner.CommandLine.Flags.DisableUpdate,
3636
Constants.Runner.CommandLine.Flags.Ephemeral,
3737
Constants.Runner.CommandLine.Flags.GenerateServiceConfig,
3838
Constants.Runner.CommandLine.Flags.Replace,
3939
Constants.Runner.CommandLine.Flags.RunAsService,
4040
Constants.Runner.CommandLine.Flags.Unattended,
41+
Constants.Runner.CommandLine.Flags.NoDefaultLabels,
4142
Constants.Runner.CommandLine.Args.Auth,
4243
Constants.Runner.CommandLine.Args.Labels,
4344
Constants.Runner.CommandLine.Args.MonitorSocketAddress,
@@ -85,6 +86,7 @@ public sealed class CommandSettings
8586
public bool Ephemeral => TestFlag(Constants.Runner.CommandLine.Flags.Ephemeral);
8687
public bool GenerateServiceConfig => TestFlag(Constants.Runner.CommandLine.Flags.GenerateServiceConfig);
8788
public bool Help => TestFlag(Constants.Runner.CommandLine.Flags.Help);
89+
public bool NoDefaultLabels => TestFlag(Constants.Runner.CommandLine.Flags.NoDefaultLabels);
8890
public bool Unattended => TestFlag(Constants.Runner.CommandLine.Flags.Unattended);
8991
public bool Version => TestFlag(Constants.Runner.CommandLine.Flags.Version);
9092
public bool RemoveLocalConfig => TestFlag(Constants.Runner.CommandLine.Flags.Local);
@@ -182,7 +184,7 @@ public string GetCommandName()
182184
{
183185
command = Constants.Runner.CommandLine.Commands.Warmup;
184186
}
185-
187+
186188
return command;
187189
}
188190

src/Runner.Listener/Configuration/ConfigurationManager.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ public async Task ConfigureAsync(CommandSettings command)
259259
if (command.GetReplace())
260260
{
261261
// Update existing agent with new PublicKey, agent version.
262-
agent = UpdateExistingAgent(agent, publicKey, userLabels, runnerSettings.Ephemeral, command.DisableUpdate);
262+
agent = UpdateExistingAgent(agent, publicKey, userLabels, runnerSettings.Ephemeral, command.DisableUpdate, command.NoDefaultLabels);
263263

264264
try
265265
{
@@ -293,7 +293,7 @@ public async Task ConfigureAsync(CommandSettings command)
293293
else
294294
{
295295
// Create a new agent.
296-
agent = CreateNewAgent(runnerSettings.AgentName, publicKey, userLabels, runnerSettings.Ephemeral, command.DisableUpdate);
296+
agent = CreateNewAgent(runnerSettings.AgentName, publicKey, userLabels, runnerSettings.Ephemeral, command.DisableUpdate, command.NoDefaultLabels);
297297

298298
try
299299
{
@@ -554,7 +554,7 @@ private ICredentialProvider GetCredentialProvider(CommandSettings command, strin
554554
}
555555

556556

557-
private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate)
557+
private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate, bool noDefaultLabels)
558558
{
559559
ArgUtil.NotNull(agent, nameof(agent));
560560
agent.Authorization = new TaskAgentAuthorization
@@ -571,9 +571,16 @@ private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey,
571571

572572
agent.Labels.Clear();
573573

574-
agent.Labels.Add(new AgentLabel("self-hosted", LabelType.System));
575-
agent.Labels.Add(new AgentLabel(VarUtil.OS, LabelType.System));
576-
agent.Labels.Add(new AgentLabel(VarUtil.OSArchitecture, LabelType.System));
574+
if (!noDefaultLabels)
575+
{
576+
agent.Labels.Add(new AgentLabel("self-hosted", LabelType.System));
577+
agent.Labels.Add(new AgentLabel(VarUtil.OS, LabelType.System));
578+
agent.Labels.Add(new AgentLabel(VarUtil.OSArchitecture, LabelType.System));
579+
}
580+
else if (userLabels.Count == 0)
581+
{
582+
throw new NotSupportedException("Disabling default labels via --no-default-labels without specifying --labels is not supported");
583+
}
577584

578585
foreach (var userLabel in userLabels)
579586
{
@@ -583,7 +590,7 @@ private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey,
583590
return agent;
584591
}
585592

586-
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate)
593+
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate, bool noDefaultLabels)
587594
{
588595
TaskAgent agent = new(agentName)
589596
{
@@ -598,9 +605,16 @@ private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet
598605
DisableUpdate = disableUpdate
599606
};
600607

601-
agent.Labels.Add(new AgentLabel("self-hosted", LabelType.System));
602-
agent.Labels.Add(new AgentLabel(VarUtil.OS, LabelType.System));
603-
agent.Labels.Add(new AgentLabel(VarUtil.OSArchitecture, LabelType.System));
608+
if (!noDefaultLabels)
609+
{
610+
agent.Labels.Add(new AgentLabel("self-hosted", LabelType.System));
611+
agent.Labels.Add(new AgentLabel(VarUtil.OS, LabelType.System));
612+
agent.Labels.Add(new AgentLabel(VarUtil.OSArchitecture, LabelType.System));
613+
}
614+
else if (userLabels.Count == 0)
615+
{
616+
throw new NotSupportedException("Disabling default labels via --no-default-labels without specifying --labels is not supported");
617+
}
604618

605619
foreach (var userLabel in userLabels)
606620
{

src/Runner.Listener/Runner.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,8 @@ private void PrintUsage(CommandSettings command)
683683
--token string Registration token. Required if unattended
684684
--name string Name of the runner to configure (default {Environment.MachineName ?? "myrunner"})
685685
--runnergroup string Name of the runner group to add this runner to (defaults to the default runner group)
686-
--labels string Extra labels in addition to the default: 'self-hosted,{Constants.Runner.Platform},{Constants.Runner.PlatformArchitecture}'
686+
--labels string Custom labels that will be added to the runner. This option is mandatory if --no-default-labels is used.
687+
--no-default-labels Disables adding the default labels: 'self-hosted,{Constants.Runner.Platform},{Constants.Runner.PlatformArchitecture}'
687688
--local Removes the runner config files from your local machine. Used as an option to the remove command
688689
--work string Relative runner work directory (default {Constants.Path.WorkDirectory})
689690
--replace Replace any existing runner with the same name (default false)

src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,107 @@ public async Task CanEnsureConfigure()
206206
}
207207
}
208208

209+
[Fact]
210+
[Trait("Level", "L0")]
211+
[Trait("Category", "ConfigurationManagement")]
212+
public async Task ConfigureErrorDefaultLabelsDisabledWithNoCustomLabels()
213+
{
214+
using (TestHostContext tc = CreateTestContext())
215+
{
216+
Tracing trace = tc.GetTrace();
217+
218+
trace.Info("Creating config manager");
219+
IConfigurationManager configManager = new ConfigurationManager();
220+
configManager.Initialize(tc);
221+
222+
trace.Info("Preparing command line arguments");
223+
var command = new CommandSettings(
224+
tc,
225+
new[]
226+
{
227+
"configure",
228+
"--url", _expectedServerUrl,
229+
"--name", _expectedAgentName,
230+
"--runnergroup", _secondRunnerGroupName,
231+
"--work", _expectedWorkFolder,
232+
"--auth", _expectedAuthType,
233+
"--token", _expectedToken,
234+
"--no-default-labels",
235+
"--ephemeral",
236+
"--disableupdate",
237+
"--unattended",
238+
});
239+
trace.Info("Constructed.");
240+
_store.Setup(x => x.IsConfigured()).Returns(false);
241+
_configMgrAgentSettings = null;
242+
243+
trace.Info("Ensuring configure fails if default labels are disabled and no custom labels are set");
244+
var ex = await Assert.ThrowsAsync<NotSupportedException>(() => configManager.ConfigureAsync(command));
245+
246+
Assert.Contains("--no-default-labels without specifying --labels is not supported", ex.Message);
247+
}
248+
}
249+
250+
[Fact]
251+
[Trait("Level", "L0")]
252+
[Trait("Category", "ConfigurationManagement")]
253+
public async Task ConfigureDefaultLabelsDisabledWithCustomLabels()
254+
{
255+
using (TestHostContext tc = CreateTestContext())
256+
{
257+
Tracing trace = tc.GetTrace();
258+
259+
trace.Info("Creating config manager");
260+
IConfigurationManager configManager = new ConfigurationManager();
261+
configManager.Initialize(tc);
262+
263+
var userLabels = "userlabel1,userlabel2";
264+
265+
trace.Info("Preparing command line arguments");
266+
var command = new CommandSettings(
267+
tc,
268+
new[]
269+
{
270+
"configure",
271+
"--url", _expectedServerUrl,
272+
"--name", _expectedAgentName,
273+
"--runnergroup", _secondRunnerGroupName,
274+
"--work", _expectedWorkFolder,
275+
"--auth", _expectedAuthType,
276+
"--token", _expectedToken,
277+
"--labels", userLabels,
278+
"--no-default-labels",
279+
"--ephemeral",
280+
"--disableupdate",
281+
"--unattended",
282+
});
283+
trace.Info("Constructed.");
284+
_store.Setup(x => x.IsConfigured()).Returns(false);
285+
_configMgrAgentSettings = null;
286+
287+
trace.Info("Ensuring all the required parameters are available in the command line parameter");
288+
await configManager.ConfigureAsync(command);
289+
290+
_store.Setup(x => x.IsConfigured()).Returns(true);
291+
292+
trace.Info("Configured, verifying all the parameter value");
293+
var s = configManager.LoadSettings();
294+
Assert.NotNull(s);
295+
Assert.True(s.ServerUrl.Equals(_expectedServerUrl));
296+
Assert.True(s.AgentName.Equals(_expectedAgentName));
297+
Assert.True(s.PoolId.Equals(_secondRunnerGroupId));
298+
Assert.True(s.WorkFolder.Equals(_expectedWorkFolder));
299+
Assert.True(s.Ephemeral.Equals(true));
300+
301+
// validate GetAgentPoolsAsync gets called twice with automation pool type
302+
_runnerServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Exactly(2));
303+
304+
var expectedLabels = userLabels.Split(",").ToList();
305+
306+
_runnerServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Select(x => x.Name).ToHashSet().SetEquals(expectedLabels))), Times.Once);
307+
}
308+
}
309+
209310
[Fact]
210311
[Trait("Level", "L0")]
211312
[Trait("Category", "ConfigurationManagement")]

0 commit comments

Comments
 (0)