After service runs but before deployment

Dec 15, 2010 at 11:51 AM

The service is running on the macine that i need to deploy to. The service also picks up the event change notification and writes the following to the log,

Notification Event Received Details as follows.
EventXml:
<?xml version="1.0" encoding="utf-16"?><BuildStatusChangeEvent xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BuildUri>vstfs:///Build/Build/6426</BuildUri>
<TeamFoundationServerUrl>http://tfsdevlonuk:8080/tfs/Gazprom.MT</TeamFoundationServerUrl>
<TeamProject>Etrm</TeamProject>
<Title>Etrm Build ETRM (QA)_1.0.6.22 Quality Changed To Under Investigation</Title>
<Subscriber>xxx</Subscriber>
<Id>xxx</Id>
<Url>http://xxx:8080/tfs/web/build.aspx?pcguid=2edda319-18be-40fb-a157-7075694ad0bc&amp;builduri=vstfs:///Build/Build/6426</Url>
<TimeZone>GMT Standard Time</TimeZone>
<TimeZoneOffset>00:00:00</TimeZoneOffset>
<ChangedTime>12/15/2010 11:39:54 AM</ChangedTime>
<StatusChange>
<FieldName>Quality</FieldName>
<NewValue>Under Investigation</NewValue>
</StatusChange>
<ChangedBy>xxx</ChangedBy>
</BuildStatusChangeEvent> TfsIdentityXml: <TeamFoundationServer url="http://tfsdevlonuk:8080/tfs/Gazprom.MT/Services/v3.0/LocationService.asmx" /> 
---
Build Status Changed: Team Project Etrm  Team Build Version: ETRM (QA)_1.0.6.22 From  : Under Investigation
---
Reading Configuration File:C:\Documents and Settings\tarora\Local Settings\Temp\tmp8.tmp
---
 I have the following DeploymentMappings.xml 
<DeploymentMappings xmlns="http://www.readify.net/TfsDeployer/DeploymentMappings20100214">   
	<Mapping BuildDefinitionPattern="ETRM (QA)"           
	Computer="TNKTSAP01LONUK"          
	OriginalQuality="*" 
	NewQuality="Under Investigation" 
	Script="PrepareForInvestigation.ps1" 
	NotificationAddress=tarun.arora@xxx.com /> 
</DeploymentMappings>
 ---
PrepareForInvestigation.ps1
$Destination = "D:\deploy\Installed\Test"
New-Item -ItemType Directory -Path $Destination -Force
Get-ChildItem -Path $Destination | Remove-Item -Recurse -Force
$Source = Join-Path -Path $TfsDeployerBuildDetail.DropLocation -ChildPath PublishedWebsites\FooWeb
Get-ChildItem -Path $Source | Copy-Item -Destination $Destination -Recurse -Force
Question?
How do i debug whether the service once manages to pick up the alert for the build quality change is picking up the deployment script? And is there a way to 
monitor while the script is being executed?
Dec 15, 2010 at 2:24 PM

I have run the test ps1 and it successfully sends an email as well. So that bit is working as well. What am i missing?

Coordinator
Dec 16, 2010 at 10:17 PM

As for why your script isn't running, my best guess is that because the BuildDefinitionPattern attribute is a regular expression it is treating your value "ETRM (QA)" as just "ETRM QA" and not matching. Try specifying the pattern as "ETRM \(QA\)" to force the parentheses to be treated literally.

I will look into improving the logging when a mapping fails to match on the BuildDefinitionPattern attribute. The logging of the other fields is already quite verbose.

There is currently no mechanism for monitoring the script as it is executed, but this is something I am working on. In the mean time, something as simple as having your script log to a file as it runs may help.

Regards,

Jason

Dec 17, 2010 at 12:50 PM

Hi Jason,

I could figure this out seeing the code. You have some good unit tests :-)

I have moved many steps up the ladder now and am currently stuck with the following,

---

Mapping evaluation details:
    MachineName=TNKTSAP01LONUK, MappingComputer=TNKTSAP01LONUK
    BuildOldStatus=, BuildNewStatus=Under Investigation
    MappingOrigQuality=*, MappingNewQuality=Under Investigation
    UserIsPermitted=True, EventCausedBy=GAZPROMUK\tarora
    BuildStatus=Succeeded, MappingStatus=

----

Eval results:
    isComputerMatch=True, isOldValueMatch=True, isNewValueMatch=True, isUserPermitted=True, isBuildStatusMatch=True

----

Matching mapping found, running script PrepareForInvestigation.ps1

----

Getting files from $/xxx/TeamBuildProcessTemplates/Deployment to C:\Documents and Settings\tarora\Local Settings\Temp\b2f34050-b019-451f-a3a5-c28d361a2aa4

------

Getting files from Source code control. RootFolder:$/xxx/TeamBuildProcessTemplates/Deployment, Workspace Directory:C:\Documents and Settings\tarora\Local Settings\Temp\b2f34050-b019-451f-a3a5-c28d361a2aa4

------

Getting Workspace: bd13f6c0-877f-4a86-99b6-56515c44a8eb RootFolder: $/xxx/TeamBuildProcessTemplates/Deployment


------

Removing Workspace: bd13f6c0-877f-4a86-99b6-56515c44a8eb


------

TfsDeployer.DeployAgent.DeploymentHostUI.RawUI

------

TfsDeployer.DeployAgent.DeploymentHostUI.WriteErrorLine("The term 'C:\Documents' is not recognized as the name of a cmdlet, function, sc")

-----

TfsDeployer.DeployAgent.DeploymentHostUI.WriteLine("ERROR: The term 'C:\Documents' is not recognized as the name of a cmdlet, function, sc")

----

TfsDeployer.DeployAgent.DeploymentHostUI.WriteErrorLine("ript file, or operable program. Check the spelling of the name, or if a path wa")

------

TfsDeployer.DeployAgent.DeploymentHostUI.WriteLine("ERROR: ript file, or operable program. Check the spelling of the name, or if a path wa")

----

TfsDeployer.DeployAgent.DeploymentHostUI.WriteErrorLine("s included, verify that the path is correct and try again.")

----

TfsDeployer.DeployAgent.DeploymentHostUI.WriteErrorLine("+ C:\Documents <<<<  and Settings\tarora\Local Settings\Temp\b2f34050-b019-451f")

----

Sending email alert via server xxx.xxx.com'
 From: 'tarun.arora@xxx.com'
 To: 'tarun.arora@xxx.com'
 Subject: Failed:  TfsDeployer Ran Script PrepareForInvestigation.ps1 on Machine TNKTSAP01LONUK for xxx/xxx (QA)/xxx (QA)_1.0.6.31
 
Team Project/Build: xxx to xxx (QA)
Quality Change: * to Under Investigation
Drop Location: \\TFSBDEV01LONUK\Drops\xxx (QA)\xxx (QA)_1.0.6.31
Build Uri: vstfs:///Build/Build/6539
Script: PrepareForInvestigation.ps1
Executed on Machine: TNKTSAP01LONUK
Output:
ERROR: The term 'C:\Documents' is not recognized as the name of a cmdlet, function, sc
ERROR: ript file, or operable program. Check the spelling of the name, or if a path wa
ERROR: s included, verify that the path is correct and try again.
ERROR: At line:1 char:13
ERROR: + C:\Documents <<<<  and Settings\tarora\Local Settings\Temp\b2f34050-b019-451f
ERROR: -a3a5-c28d361a2aa4\PrepareForInvestigation.ps1
ERROR:     + CategoryInfo          : ObjectNotFound: (C:\Documents:String) [], Comman 
ERROR:    dNotFoundException
ERROR:     + FullyQualifiedErrorId : CommandNotFoundException
ERROR:  



For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
Sharing the power shell script, i guess it failes before running the ps script,
$buildNumber = $TfsDeployerBuildData.BuildNumber
$dropLocation = $TfsDeployerBuildData.DropLocation
if($buildNumber -eq $null)
{
  $buildNumber = $args[0]
  $dropLocation = $args[1]
}
Dec 17, 2010 at 1:55 PM

Is this a bug? When trying to read the script from the temp directory

TfsDeployer.DeployAgent.DeploymentHostUI.WriteErrorLine("+ C:\Documents <<<<  and Settings\tarora\Local Settings\Temp\fbcfe1bc-1c10-453f")

it breaks when interpreting the folder C:\Documents and Settings because of the space between "Documents and Settings"? 
http://poshoholic.com/2007/09/27/invoking-a-powershell-script-from-cmdexe-or-start-run/ 
Dec 17, 2010 at 2:14 PM
Is this where it trips of?
 
public class BatchFileDeployAgent : IDeployAgent
    {
        public DeployAgentResult Deploy(DeployAgentData deployAgentData)
        {
            //FIXME this method does way too much now. refactor.  -andrewh 27/10/2010

            var scriptToRun = Path.Combine(deployAgentData.DeployScriptRoot, deployAgentData.DeployScriptFile);

            if (!File.Exists(scriptToRun))
            {
                TraceHelper.TraceWarning(TraceSwitches.TfsDeployer, "BatchRunner - Could not find script: {0}", scriptToRun);

                return new DeployAgentResult
                {
                    HasErrors = true,
                    Output = string.Format("BatchRunner - Could not find script: {0}", scriptToRun),
                };
            }
Dec 17, 2010 at 2:21 PM

Windows 2003, XP, etc have the convention

C:\Documents and Settings\<userprofile>\Local Settings\Temp\...

While Vista, Windows 2008, etc

C:\Users\tarora\AppData\Local\Temp\ifnv5pdu.tam.ps1

Do you think we have narrowed down to why it's failing?

Dec 17, 2010 at 2:49 PM

If you run the unit test,

[TestMethod]
public void LocalPowerShellDeployAgent_should_unload_assemblies_loaded_by_scripts()

and modify the method that creates the temp file name to the following

public TemporaryFile(string extension, string content)
{
     if (!extension.StartsWith(".")) extension = "." + extension;
     var fileName = Path.GetRandomFileName() + extension;
     _fileInfo = new FileInfo(Path.Combine(@"C:\Documents and Setting\tarora\Local Settings\Temp\", fileName));
     //_fileInfo = new FileInfo(Path.Combine(Path.GetTempPath(), fileName));
     using (var stream = _fileInfo.OpenWrite())
     using (var writer = new StreamWriter(stream, Encoding.ASCII))
     {
           writer.Write(content);
     }
}

The following class has the execute method that would fail when it attemps to invoke the pipeline

public class LocalPowerShellScriptExecutor : MarshalByRefObject
    {
        public DeployAgentResult Execute(string scriptPath, IDictionary<string, object> variables)
        {
            var hasErrors = true;
            string output;

            var ui = new DeploymentHostUI();
            try
            {
                var host = new DeploymentHost(ui);
                using (var space = RunspaceFactory.CreateRunspace(host))
                {
                    space.Open();

                    if (null != variables)
                    {
                        foreach (var key in variables.Keys)
                        {
                            space.SessionStateProxy.SetVariable(key, variables[key]);
                        }
                    }

                    using (var pipeline = space.CreatePipeline())
                    {
                        var scriptCommand = new Command(scriptPath, true);
                        scriptCommand.MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
                        pipeline.Commands.Add(scriptCommand); // Value = {C:\Documents and Setting\tarora\Local Settings\Temp\npf03jra.mo3.ps1}

                        pipeline.Commands.Add("Out-Default");

                        pipeline.Invoke();
                        hasErrors = ui.HasErrors;
                        output = ui.Output;
                    }
                }
            }
            catch (RuntimeException ex)
            {
                var record = ex.ErrorRecord;
                var sb = new StringBuilder();
                sb.AppendLine(record.Exception.ToString());
                sb.AppendLine(record.InvocationInfo.PositionMessage);
                output = string.Format("{0}\n{1}", ui.Output, sb);
            }
            catch (Exception ex)
            {
                output = string.Format("{0}\n{1}", ui.Output, ex);
            }

            return new DeployAgentResult { HasErrors = hasErrors, Output = output };
        }
    }

 ui.Output = "ERROR: The term 'C:\\Documents' is not recognized as the name of a cmdlet, function, sc\r\nERROR: ript file, or operable program. Check the spelling of the name, or if a path wa\r\nERROR: s included, verify that the path is correct and try again.\r\nERROR:...

Possible fix

When adding the script command

 

pipeline.Commands.Add(scriptCommand);

if you could add '-noexit' it should ignore the space between the text. http://poshoholic.com/2007/09/27/invoking-a-powershell-script-from-cmdexe-or-start-run/ 

Coordinator
Dec 20, 2010 at 7:31 AM

TFS Deployer does not execute PowerShell.exe to run scripts, it hosts the scripts in-process using PowerShell Runspaces, so the "-noexit" switch does not apply. However, changeset 53962 now includes tests and fixes for script paths containing white space and other potentially problematic characters.

Regards,

Jason

Dec 20, 2010 at 8:17 AM

Thanks J,

As a workaround i had changed windows Temp folder to another folder that did not have " space ". Are you planning on converting the changeset to a release shortly?