HaveComputerWillCode.Com

Welcome!
Life is a Non-Deterministic Finite State Automata
Automation ? (*pGeekiness)++ : Code /eneration;

September 22, 2010

Automating Microsoft Lab Center API/SDK: Part 4

Filed under: ALM — Tags: , , — admin @ 9:51 am

This is a multi-part post for programmatically automating Microsoft Lab Center 2010 / Visual Studio Lab Management 2010 / Lab Manager 2010 (not VS/TFS2012) via C#:

  • Part 1Source Code – Enumerate Environments
  • Part 2Source Code – Deploy Environment
  • Part 3Source Code – Deploy Environment, Monitor Operations, Start, Stop, Delete Environment
  • Part 4 – Source Code – Part 3 + Network Isolation, RDP/Connect, Thumbnail Control
  • The entry point to the API / SDK documentation is here via the GetService call (LabService is the main one, but also see LabAdminService and LabFrameworkService)

    Getting in…
    When an environment is running within Lab Center, how do you programmatically ‘get inside’ that Environment and find out the names of the running machines? What about the internal and external computer names? In the case of a Network Isolated environment that has been deployed, you need to know the world-facing DNS and IP Address name so that you can connect to it remotely or initiate custom deployments.

    How to do this?

    I’ve modified the UI so that each deployed environment lists it’s virtual machines as children. Each LabEnvironment object has a LabSystems property containing a list of all virtual machines contained within. I mean, really: could it be any easier?! Of interest to us are the ‘LabSystem.IsolationOptions’ through which we can find the Internal and External computer names:

    The code of interest to us is:

                    // ls==LabSystem
                    if (ls.ExtendedInfo != null)
                    {
                        string roles = String.Format("Roles: {0}", ls.Roles);
                        string hostOs = String.Format("Guess Operation System: {0}", ls.ExtendedInfo.GuestOperatingSystem);
                        string hasVmAdditions = String.Format("Has Vm Additions: {0}", ls.ExtendedInfo.HasVMAdditions);
                        
                        // This is the Hyper-V System hosting this virtual machine. 
                        string hostname = String.Format("Virutalization Host Name: {0}", ls.ExtendedInfo.HostName);
    
                        string remoteSessionInfo = "Remote Session Info: (Not Available)";
    
                        if (ls.ExtendedInfo.RemoteInfo != null)
                        {
                            // The DNS name we will use to connect to a machine in a Network Isolated environment. 
                            string computerName = String.Format("Computer Name: {0}", ls.ExtendedInfo.RemoteInfo.ComputerName);
    
                            // The internal name of the machine on the Isolated Network. 
                            string internalName = String.Format("Internal Name: {0}", ls.ExtendedInfo.RemoteInfo.InternalComputerName);
    
                            remoteSessionInfo = String.Format("Remote Session Info:\r\n{0}\r\n{1}", computerName, internalName);
                        }
    
                        string vmInformation = String.Format("Extended Info:\r\n{0}\r\n{1}\r\n{2}\r\n{3}\r\n{4}\r\n", new object[] { hostOs, hasVmAdditions, hostname, remoteSessionInfo, roles });
    

    From the LabSystem and LabSystem.ExtendedInfo objects you can get at the OS Profile, hardware profile, roles, machine ID’s so I’ve provided a subset of those properties at the bottom… in fact, you can get at *EVERYTHING* that you normally set up and enter when you create a new environment with Lab Center. It’s easy, and it’s very easy to relate those properties to what you see in the UI.

    What good is this? A lot! After deploying or connecting to an environment you can ‘discover’ the environment, identify custom properties associated with it at the time of deployment and direct interaction with it. With this information, it is trivial to use RDP to connect through to the machine in question (I have added a ‘Connect’ button to the bottom of the dialog). In this example, I am launching MSTSC but you might be better off using an embedded RDP6 Interop so you can host the RDP session directly within your application (when using Lab Center and “Connect” to a machine the large view on the right hand side is just a hosted RDP Active-X Control…):

    string RdpPath = Environment.ExpandEnvironmentVariables(@"%windir%\system32\mstsc.exe");
    
    ProcessStartInfo psi = new ProcessStartInfo();
    
    psi.Arguments = String.Format("/v:{0}", ls.ExtendedInfo.RemoteInfo.ComputerName);
    psi.FileName = RdpPath;
    
    Process.Start(psi);
    

    But something is missing! When using Lab Center, you get a really cool Thumbnail view of each host:

    I WANT THAT! Where does that come from?! Not from Lab Center: it comes from Hyper-V. There is a class called ‘SystemThumbnail’ in *.LEViewer.DLL but didn’t pursue it because it’s not part of the API Documentation I could find. Instead, I found a post that explains how you obtain an image of a running environment on Hyper-V. I won’t elaborate (all the code is there and *ALL* credit goes to that guy):

    I modified a few things so that it did not actually save a Thumbnail file – instead, I just extract the returned Bitmap and assign it as the BackgroundImage on the control:

    Thumbnail thumbnail = new Thumbnail(Width, this.Height);
    Bitmap result = thumbnail.GetVirtualSystemThumbnailImage(LabSystem.VMName, LabSystem.ExtendedInfo.HostName);
    
    this.BackgroundImage = result;
    

    It is set to refresh every 5 seconds at the moment and you need to have a virtual machine (not environment) selected for it to appear… be patient :-)

    Recall that when you deploy an Environment in Lab Center, you chose a Host Group to apply it to – the ultimate Hyper-V Host it was deployed to (based on how SCVMM calculated the resources and suitability for the environment you are deploying) can be obtained with a call to theLabSystem.ExtendedInfo.HostName.

    I’ve wrapped the whole thing up in ‘ThumbnailControl.cs’ (without any error checking) which works the same as ‘EnvironmentMonitorControl.cs’ – you Bind a Virtual Machine to it, and every few seconds it will refresh the display.

    Tchau!

    September 21, 2010

    Automating Microsoft Lab Center API/SDK: Part 3

    Filed under: ALM — Tags: , , — admin @ 8:46 am

    This is a multi-part post for programmatically automating Microsoft Lab Center 2010 / Visual Studio Lab Management 2010 / Lab Manager 2010 (not VS/TFS2012) via C#:

  • Part 1Source Code – Enumerate Environments
  • Part 2Source Code – Deploy Environment
  • Part 3 – Source Code – Deploy Environment, Monitor Operations, Start, Stop, Delete Environment
  • Part 4Source Code – Part 3 + Network Isolation, RDP/Connect, Thumbnail Control
  • The entry point to the API / SDK documentation is here via the GetService call (LabService is the main one, but also see LabAdminService and LabFrameworkService)

    If you’ve ever used System Centre Virtual Machine Manager, you’ll be familiar with the tree-view display that gives you feedback on every single operation that is occurring:

    The structure of a running operation in Lab Center is similar but only one deep. Every LabEnvironment object – including operations that create new environments such as CloneAndDeploy – has a ‘LabOperation’ object that in turn has ‘SubLabOperations’. That means its easy to build a nested tree structure showing the progress of each individual operation by discovering it’s operations like this:

    As you can see: I hate writing user interfaces with a passion so I’m sticking as much as possible on the one dialog :-) Rather than using aesthetically pleasing things like color I’m sticking with numbers. Remember: this is a proof of concept and has zero error checking!! Any of the operations can fail but at the moment, it will end with a glorious exception.

    I’ve modified the UI so that when you click on any environment under the Deployed Environments node its state and operations show up on the right:

    The tree view on the right and the progress bar are all hosted in the sample ‘EnvironmentMonitorControl.cs’. This simple control just accepts a LabEnvironment and LabService reference via the Bind method. Every few seconds it will refresh itself by calling the GetLabEnvironment and updating the control:

    // 2.
    LabEnvironment le = null;
                
    try
    {
    	le = LabService.GetLabEnvironment(LabEnvironment.Uri);
    }
    catch (Microsoft.TeamFoundation.Lab.Client.LabObjectNotFoundException ex)
    {
    	Unbind();
    	return;
    }
    
    // 3.
    progressRootOperation.Value = le.LabOperation.Progress;
    labelOperation.Text = le.StatusInfo.State.ToString();
    

    At the moment, I am calling that inline as a response to the Timer Message but you’ll probably want to farm that off to another thread.

    Once you have a running environment, it’s then just a simple case of building up a single treeview of the operations:

    public void RenderOperations(TreeNode node, LabOperation operation)
    {
    	if (null == operation) throw new System.ArgumentNullException("operation");
    	if (null == node) throw new System.ArgumentNullException("node");
    
    	node.Text = operation.OperationState + "(" + operation.OperationState.ToString() + " - " + operation.Progress.ToString() + "%)";
    
    	foreach (SubLabOperation childOperation in operation.SubLabOperations)
    	{
    		TreeNode childNode = new TreeNode();
    
    		childNode.Text = childOperation.Description + " - " + childOperation.Progress.ToString() + "%";
    
    		node.Nodes.Add(childNode);
    	}
    }
    

    I’ve added a Start, Stop and Delete operation to the (increasingly cramped!) dialog box (with no error checking). Hopefully, you’ll see the integration possibilities the Lab Center API’s open up… in the next post, I’ll drill into the running environments so we can identify each running machine, obtain it’s Network Isolation information and (if I’ve time :-) ) something else…

    Automating Microsoft Lab Center API/SDK: Part 2

    Filed under: ALM — Tags: , , — admin @ 12:10 am

    This is a multi-part post for programmatically automating Microsoft Lab Center 2010 / Visual Studio Lab Management 2010 / Lab Manager 2010 (not VS/TFS2012) via C#:

  • Part 1Source Code – Enumerate Environments
  • Part 2 – Source Code – Deploy Environment
  • Part 3Source Code – Deploy Environment, Monitor Operations, Start, Stop, Delete Environment
  • Part 4Source Code – Part 3 + Network Isolation, RDP/Connect, Thumbnail Control
  • The entry point to the API / SDK documentation is here via the GetService call (LabService is the main one, but also see LabAdminService and LabFrameworkService)

    Now that we can enumerate all of the environments (see Part 1), programmatically deploying an environment is easy: there is a single method called CloneAndDeploy. I think Microsoft called it that because it’s a method. That clones. And deploys. An environment :-)

    What you normally do in Test Lab Center is manually right click on a stored environment, select Deploy and enter some deployment parameters:

    For the purposes of the sample, I have provided a 1-to-1 mapping between the dialogs:

    The only complication was obtaining the Project Host Groups. This information can be obtained directly from the Lab Service Call:

    // 1.
    TeamProjectHostGroupQuerySpec spec = new TeamProjectHostGroupQuerySpec();
    
    spec.Project = ProjectName;
    
    ICollection groups = LabService.QueryTeamProjectHostGroups(spec);
    

    Deploying the environment is just as easy:

    private void buttonDeploy_Click(object sender, EventArgs e)
    {       
    	// TODO: Replace the User Name with your account name...
    	LabEnvironment lv = LabGoldenEnvironment.CloneAndDeploy((comboBoxProjectHostGroup.SelectedItem as TeamProjectHostGroup).Uri, textBoxEnvironmentName.Text, textBoxEnvironmentDescription.Text, "WOOHOO\\Administrator", null);
    
    	DialogResult = System.Windows.Forms.DialogResult.OK;
    	Close();
    }
    

    CloneAndDeploy is a long running operation – but it doesn’t block! What you get back is a ‘LabEnvironment’ whose properties you can use as a handle to keep querying the status of that Lab Environment, it’s state and any operations. I was going to incorporate the monitoring of the deployment operation into this post using a pretty green progress bar, but the way the long running operations are handled in their API is such a general theme that I’m going to leave it until Part 3 :-)

    REALLY: Hat’s off to the Microsoft guys. These are the kind of API’s I *WANT* to integrate with!

    After hitting deployment in our custom UI, we can see the Deployment by hitting ‘Refresh Environments’ (manually for now). We can also see the deployment occuring in Lab Center proper:

    Recall that you configure which Host Groups are available to the Team Project using the Team Foundation Service Administration Console / Application Tier / Team Project Collections / Lab Management. It is the Host Groups listed there that appear in the drop-down combo when you Deploy…

    September 20, 2010

    Automating Microsoft Lab Center API/SDK: Part 1

    Filed under: ALM — Tags: , , — admin @ 9:48 am

    This is a multi-part post for programmatically automating Microsoft Lab Center 2010 / Visual Studio Lab Management 2010 / Lab Manager 2010 (not VS/TFS2012) via C#:

  • Part 1 – Source Code – Enumerate Environments
  • Part 2Source Code – Deploy Environment
  • Part 3Source Code – Deploy Environment, Monitor Operations, Start, Stop, Delete Environment
  • Part 4Source Code – Part 3 + Network Isolation, RDP/Connect, Thumbnail Control
  • The entry point to the API / SDK documentation is here via the GetService call (LabService is the main one, but also see LabAdminService and LabFrameworkService)

    In my job, I spend a lot of time thinking about how companies can use Microsoft Lab Center to automate their integration, system and functional testing but one of the issues I kept hitting was how to make the experience slicker. There is a lot of infrastructure in the Lab Center / Hyper-V space that can be leveraged for much more awesomeness than nature originally intended! A typical gripe is the manual nature of deploying virtual environments: currently, assuming you have a Network Isolated environment and want to deploy a copy for each developer, each developer needs to go to Lab Center and deploy themselves a private instance of that stored environment (‘Golden Environment’) by hand:


    In this case, the Stored XP Standalone Environment (‘Golden Environment’) is a Network Isolated Environment that will be deployed by lots of devs

    Each deployed copy then turns up in the ‘Lab’ area:

    What I want to do is to automate that deployment within my own applications – and possibly integrate it into Visual Studio and do all other kinds of awesomeness with it. As it happens, and without having to host the supported Workflow Activities, there appears to be an API to do just this! (see GetService – LabService, LabFrameworkService, LabAdminService). As a proof of concept, I might want to automate the deployment of an environment in my own application via C#:

    Before going on, things get a little murky here and I’m confused. You see, floating around the Internet are various references to a mysterious Lab Management/Lab Center SDK (and even a sample…). But that was in the days when Lab Center was its own product… so it looks like it’s all been rolled up into the Team Foundation SDK and that all Lab Center functionality is available via a ProjectCollection.GetService call. As of today, if I Google for “TeamProjectHostGroupQuerySpec“, for example, I get *ZERO HITS* but I can get to the information directly via this link. So I am assuming it is an officially supported API – if it turns out not to be, it should be!

    So with that in mind, let’s get to it!

    With the provided API’s, it looks like it is possible to automate 100% of the Lab Center UI in your own tools: you could replace it entirely with your own tool. In these posts, I’ll go over some of the basics I needed to get up & running but the possibilities for integrating with other virtual environments (such as VmWare) have risen somewhat because of these API’s.

    So let’s get started…

    When you start up Microsoft Test Manager, you only see the Environments associated with that Team Project so we need to do the same in our app. It’s a trivial task to connect to your TFS Team Project and there is a dedicated control as part of the Team Foundation Server SDK to do this. I won’t elaborate on how to do this (everything you need to know is here and if you want to use Impersonation to connect as someone else you can find that here:

    The source code to do this is straight forward:

    // 1.
    TeamProjectPicker picker = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
    
    // 2.
    DialogResult result = picker.ShowDialog();
    if (result != System.Windows.Forms.DialogResult.OK) return;
    if (picker.SelectedProjects.Length == 0) return;
    

    At which point you’re ready to enumerate the Golden Environments and any Deployed Environments:

    // 3.
    textBoxProjectCollection.Text = picker.SelectedTeamProjectCollection.Name; 
    textBoxTeamProjectUri.Text = picker.SelectedProjects[0].Uri;
    textBoxTeamProject.Text = picker.SelectedProjects[0].Name;
    
    // 4.
    // It looks like all of the services for integrating with Lab Manager are available via LabService and two others:
    // See http://msdn.microsoft.com/en-us/library/bb286958.aspx
    LabService labService = picker.SelectedTeamProjectCollection.GetService();
    if (labService == null) throw new System.ArgumentOutOfRangeException("Unable to get hold of LabService...");
    
    // 5.
    // THIS IS TOO EASY!
    LabEnvironmentQuerySpec spec = new LabEnvironmentQuerySpec();
    spec.Project = textBoxTeamProject.Text;
    ICollection environments = labService.QueryLabEnvironments(spec);
    

    With that, we have the information we need:

    The source code in the download has more comments but it’s straight forward (source available from link at top of post). In the API, there is a distinction between a ‘Stored’ environment (ready for Deployment by lots of developers – for a Network Isolated environment that will be deployed multiple times in its entirety, I refer to this as a ‘Golden Environment’) and an ‘Active’ environment (ready to be started – in this case, MyDeployment1).

    All we need to do is to deploy it. But that’s for Part 2 :-) Of interest, were the four references I had to add to my project:

    You might have to modify the Microsoft.TeamFoundation.Lab.Client.DLL reference (it will be on your MTM / Lab Center client machine and you might have to search the GAC for it). In Part 2, we’ll deploy…

    Older Posts »

    Powered by WordPress