diff --git a/src/Runner.Common/Constants.cs b/src/Runner.Common/Constants.cs index 8533e931a..4f8694d53 100644 --- a/src/Runner.Common/Constants.cs +++ b/src/Runner.Common/Constants.cs @@ -90,7 +90,7 @@ namespace GitHub.Runner.Common public static readonly string Labels = "labels"; public static readonly string MonitorSocketAddress = "monitorsocketaddress"; public static readonly string Name = "name"; - public static readonly string Pool = "pool"; + public static readonly string RunnerGroup = "runnergroup"; public static readonly string StartupType = "startuptype"; public static readonly string Url = "url"; public static readonly string UserName = "username"; diff --git a/src/Runner.Listener/CommandSettings.cs b/src/Runner.Listener/CommandSettings.cs index 0d80c1d5e..364962610 100644 --- a/src/Runner.Listener/CommandSettings.cs +++ b/src/Runner.Listener/CommandSettings.cs @@ -42,7 +42,7 @@ namespace GitHub.Runner.Listener Constants.Runner.CommandLine.Args.Labels, Constants.Runner.CommandLine.Args.MonitorSocketAddress, Constants.Runner.CommandLine.Args.Name, - Constants.Runner.CommandLine.Args.Pool, + Constants.Runner.CommandLine.Args.RunnerGroup, Constants.Runner.CommandLine.Args.StartupType, Constants.Runner.CommandLine.Args.Token, Constants.Runner.CommandLine.Args.Url, @@ -169,6 +169,15 @@ namespace GitHub.Runner.Listener validator: Validators.NonEmptyValidator); } + public string GetRunnerGroupName(string defaultPoolName = null) + { + return GetArgOrPrompt( + name: Constants.Runner.CommandLine.Args.RunnerGroup, + description: "Enter the name of the runner group to add this runner to:", + defaultValue: defaultPoolName ?? "default", + validator: Validators.NonEmptyValidator); + } + public string GetToken() { return GetArgOrPrompt( diff --git a/src/Runner.Listener/Configuration/ConfigurationManager.cs b/src/Runner.Listener/Configuration/ConfigurationManager.cs index ce0863e1a..8e499adc7 100644 --- a/src/Runner.Listener/Configuration/ConfigurationManager.cs +++ b/src/Runner.Listener/Configuration/ConfigurationManager.cs @@ -159,17 +159,34 @@ namespace GitHub.Runner.Listener.Configuration _term.WriteSection("Runner Registration"); - //Get all the agent pools, and select the first private pool + // If we have more than one runner group available, allow the user to specify which one to be added into + string poolName = null; + TaskAgentPool agentPool = null; List agentPools = await _runnerServer.GetAgentPoolsAsync(); - TaskAgentPool agentPool = agentPools?.Where(x => x.IsHosted == false).FirstOrDefault(); + TaskAgentPool defaultPool = agentPools?.Where(x => x.IsInternal).FirstOrDefault(); - if (agentPool == null) + if (agentPools?.Where(x => !x.IsHosted).Count() > 1) { - throw new TaskAgentPoolNotFoundException($"Could not find any private pool. Contact support."); + poolName = command.GetRunnerGroupName(defaultPool?.Name); + _term.WriteLine(); + agentPool = agentPools.Where(x => string.Equals(poolName, x.Name, StringComparison.OrdinalIgnoreCase) && !x.IsHosted).FirstOrDefault(); } else { - Trace.Info("Found a private pool with id {1} and name {2}", agentPool.Id, agentPool.Name); + agentPool = defaultPool; + } + + if (agentPool == null && poolName == null) + { + throw new TaskAgentPoolNotFoundException($"Could not find any self-hosted runner groups. Contact support."); + } + else if (agentPool == null && poolName != null) + { + throw new TaskAgentPoolNotFoundException($"Could not find any self-hosted runner group named \"{poolName}\"."); + } + else + { + Trace.Info("Found a self-hosted runner group with id {1} and name {2}", agentPool.Id, agentPool.Name); runnerSettings.PoolId = agentPool.Id; runnerSettings.PoolName = agentPool.Name; } diff --git a/src/Sdk/DTWebApi/WebApi/TaskAgentPoolReference.cs b/src/Sdk/DTWebApi/WebApi/TaskAgentPoolReference.cs index bbef3809f..714860c1d 100644 --- a/src/Sdk/DTWebApi/WebApi/TaskAgentPoolReference.cs +++ b/src/Sdk/DTWebApi/WebApi/TaskAgentPoolReference.cs @@ -29,6 +29,7 @@ namespace GitHub.DistributedTask.WebApi this.PoolType = referenceToBeCloned.PoolType; this.Size = referenceToBeCloned.Size; this.IsLegacy = referenceToBeCloned.IsLegacy; + this.IsInternal = referenceToBeCloned.IsInternal; } public TaskAgentPoolReference Clone() @@ -67,6 +68,16 @@ namespace GitHub.DistributedTask.WebApi set; } + /// + /// Gets or sets a value indicating whether or not this pool is internal and can't be modified by users + /// + [DataMember] + public bool IsInternal + { + get; + set; + } + /// /// Gets or sets the type of the pool /// diff --git a/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs b/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs index 9cf3ad5ad..706a11cd7 100644 --- a/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs +++ b/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs @@ -39,10 +39,12 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration private string _expectedToken = "expectedToken"; private string _expectedServerUrl = "https://codedev.ms"; private string _expectedAgentName = "expectedAgentName"; - private string _expectedPoolName = "poolName"; + private string _defaultRunnerGroupName = "defaultRunnerGroup"; + private string _secondRunnerGroupName = "secondRunnerGroup"; private string _expectedAuthType = "pat"; private string _expectedWorkFolder = "_work"; - private int _expectedPoolId = 1; + private int _defaultRunnerGroupId = 1; + private int _secondRunnerGroupId = 2; private RSACryptoServiceProvider rsa = null; private RunnerSettings _configMgrAgentSettings = new RunnerSettings(); @@ -97,7 +99,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration _serviceControlManager.Setup(x => x.GenerateScripts(It.IsAny())); #endif - var expectedPools = new List() { new TaskAgentPool(_expectedPoolName) { Id = _expectedPoolId } }; + var expectedPools = new List() { new TaskAgentPool(_defaultRunnerGroupName) { Id = _defaultRunnerGroupId, IsInternal = true }, new TaskAgentPool(_secondRunnerGroupName) { Id = _secondRunnerGroupId } }; _runnerServer.Setup(x => x.GetAgentPoolsAsync(It.IsAny(), It.IsAny())).Returns(Task.FromResult(expectedPools)); var expectedAgents = new List(); @@ -155,7 +157,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration "configure", "--url", _expectedServerUrl, "--name", _expectedAgentName, - "--pool", _expectedPoolName, + "--runnergroup", _secondRunnerGroupName, "--work", _expectedWorkFolder, "--auth", _expectedAuthType, "--token", _expectedToken, @@ -175,7 +177,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration Assert.NotNull(s); Assert.True(s.ServerUrl.Equals(_expectedServerUrl)); Assert.True(s.AgentName.Equals(_expectedAgentName)); - Assert.True(s.PoolId.Equals(_expectedPoolId)); + Assert.True(s.PoolId.Equals(_secondRunnerGroupId)); Assert.True(s.WorkFolder.Equals(_expectedWorkFolder)); // validate GetAgentPoolsAsync gets called twice with automation pool type