Programmatically use a server as the Build Server for multiple Project Collections

by Ewald Hofman 25. November 2010 05:41

Important: With this post you create an unsupported scenario by Microsoft. It will break your support for this server with Microsoft. So handle with care.

I am the administrator an a TFS environment with a lot of Project Collections. In the supported configuration of Microsoft 2010 you need one Build Controller per Project Collection, and it is not supported to have multiple Build Controllers installed. Jim Lamb created a post how you can modify your system to change this behaviour. But since I have so many Project Collections, I automated this with the API of TFS.

When you install a new build server via the UI, you do the following steps

  1. Register the build service (with this you hook the windows server into the build server environment)
  2. Add a new build controller
  3. Add a new build agent

So in pseudo code, the code would look like

foreach (projectCollection in GetAllProjectCollections)
{
      CreateNewWindowsService();
      RegisterService();
      AddNewController();
      AddNewAgent();
}

The following code fragements show you the most important parts of the method implementations. Attached is the full project.

CreateNewWindowsService

We create a new windows service with the SC command via the Diagnostics.Process class:

            var pi = new ProcessStartInfo("sc.exe")
                         {
                             Arguments =
                                
string
.Format(
                                    
"create \"{0}\" start= auto binpath= \"C:\\Program Files\\Microsoft Team Foundation Server 2010\\Tools\\TfsBuildServiceHost.exe
             /NamedInstance:{0}\" DisplayName= \"Visual Studio Team Foundation Build Service Host ({1})\""
,
                                     serviceHostName, tpcName)
                         };
           
Process
.Start(pi);

            pi.Arguments =
string.Format("failure {0} reset= 86400 actions= restart/60000"
, serviceHostName);
           
Process.Start(pi);

RegisterService

The trick in this method is that we set the NamedInstance static property. This property is Internal, so we need to set it through reflection. To get information on these you need nice Microsoft friends and the .Net reflectorSmile .

            // Indicate which build service host instance we are using
            typeof(BuildServiceHostUtilities).Assembly.GetType("Microsoft.TeamFoundation.Build.Config.BuildServiceHostProcess").InvokeMember("NamedInstance",
             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.Static, null, null, new object[] { serviceName });

           
// Create the build service host
            serviceHost = buildServer.CreateBuildServiceHost(serviceName, endPoint);
            serviceHost.Save();

           
// Register the build service host
            BuildServiceHostUtilities
.Register(serviceHost, user, password);

AddNewController and AddNewAgent

Once you have the BuildServerHost, the rest is pretty straightforward. There are methods on the BuildServerHost to modify the controllers and the agents

                controller = serviceHost.CreateBuildController(controllerName);
                agent = controller.ServiceHost.CreateBuildAgent(agentName, buildDirectory, controller);
                controller.AddBuildAgent(agent);
You have now seen the highlights of the application. If you need it and want to have sample information when you work in this area, download the app
TFS2010_RegisterBuildServerToTPCs

Tags:

TFS SDK | VSTS 2010 | Team Build

Comments are closed

Powered by BlogEngine.NET 1.6.1.0
Theme by Mads Kristensen


ClusterMap

Statistics

Statistics created at 09 Sep 2009

121 posts
488 comments
326 raters
1896666 visit (1042 per day)
20 users online

Recent comments

Comment RSS