private string PrepareImportGlobalVariablesScript(DeployAgentData deployAgentData) { const int serializationDepth = 5; const string clixmlFile = "TfsDeployer.variables.clixml"; const string scriptTemplate = "(Import-Clixml -Path {0}).GetEnumerator() | ForEach-Object {{ Set-Variable -Name $_.Key -Value $_.Value -Scope global }};"; var globalVariables = LocalPowerShellDeployAgent.CreateCommonVariables(deployAgentData); if (deployAgentData.DeployScriptParameters != null) { foreach (var deployParam in deployAgentData.DeployScriptParameters) { globalVariables[deployParam.Name] = deployParam.Value; } } using (var shell = PowerShell.Create()) { var clixmlPath = Path.Combine(deployAgentData.DeployScriptRoot, clixmlFile); shell.AddCommand("Export-Clixml").AddParameter("Depth", serializationDepth).AddParameter("Path", clixmlPath); shell.Invoke(new[] { globalVariables }); } return(String.Format(scriptTemplate, clixmlFile)); }
private static string GeneratePipelineCommand(DeployAgentData deployAgentData) { string command = Path.Combine(deployAgentData.DeployScriptRoot, deployAgentData.DeployScriptFile); command = string.Format(".\"{0}\"", command); return(command); }
public DeployAgentResult Deploy(DeployAgentData deployAgentData) { var variables = CreateVariables(deployAgentData); var scriptPath = Path.Combine(deployAgentData.DeployScriptRoot, deployAgentData.DeployScriptFile); var result = ExecuteCommand(scriptPath, variables); return(result); }
private static IDictionary <string, object> CreateVariables(DeployAgentData deployAgentData) { var dict = CreateCommonVariables(deployAgentData); foreach (var parameter in deployAgentData.DeployScriptParameters) { dict.Add(parameter.Name, parameter.Value); } return(dict); }
private static string CreateArguments(DeployAgentData deployAgentData) { var buildDetail = deployAgentData.TfsBuildDetail; var defaultArguments = new[] { buildDetail.DropLocation, buildDetail.BuildNumber }; var extraArguments = deployAgentData.DeployScriptParameters.Select(p => p.Value); var escapedArguments = defaultArguments.Concat(extraArguments).Select(EscapeArgument); return(string.Join(" ", escapedArguments.ToArray())); }
private static string CreateArguments(DeployAgentData deployAgentData) { var buildData = deployAgentData.Tfs2008BuildDetail; var arguments = new StringBuilder(); arguments.AppendFormat("{0}, {1} ", buildData.DropLocation, buildData.BuildNumber); foreach (var param in deployAgentData.DeployScriptParameters) { arguments.AppendFormat(", {0}", param.Value); } return(arguments.ToString()); }
private static IDictionary <string, object> CreateCommonVariables(DeployAgentData deployAgentData) { var dict = new Dictionary <string, object>(); dict.Add("TfsDeployerComputer", deployAgentData.DeployServer); dict.Add("TfsDeployerNewQuality", deployAgentData.NewQuality); dict.Add("TfsDeployerOriginalQuality", deployAgentData.OriginalQuality); dict.Add("TfsDeployerScript", deployAgentData.DeployScriptFile); dict.Add("TfsDeployerBuildData", deployAgentData.Tfs2005BuildData); dict.Add("TfsDeployerBuildDetail", deployAgentData.Tfs2008BuildDetail); return(dict); }
private static IDictionary <string, object> CreateCommonVariables(DeployAgentData deployAgentData) { var dict = new Dictionary <string, object> { { "TfsDeployerComputer", deployAgentData.DeployServer }, { "TfsDeployerNewQuality", deployAgentData.NewQuality }, { "TfsDeployerOriginalQuality", deployAgentData.OriginalQuality }, { "TfsDeployerScript", deployAgentData.DeployScriptFile }, { "TfsDeployerBuildDetail", deployAgentData.TfsBuildDetail } }; return(dict); }
public DeployAgentResult Deploy(DeployAgentData deployAgentData) { var errorOccurred = true; string output = string.Empty; var scriptToRun = Path.Combine(deployAgentData.DeployScriptRoot, deployAgentData.DeployScriptFile); if (!File.Exists(scriptToRun)) { TraceHelper.TraceWarning(TraceSwitches.TfsDeployer, "BatchRunner - Could not find script: {0}", scriptToRun); output = string.Format("BatchRunner - Could not find script: {0}", scriptToRun); } else { var psi = new ProcessStartInfo(scriptToRun); psi.UseShellExecute = false; psi.RedirectStandardOutput = true; psi.RedirectStandardInput = true; psi.RedirectStandardError = true; psi.WorkingDirectory = deployAgentData.DeployScriptRoot; psi.Arguments = CreateArguments(deployAgentData); TraceHelper.TraceInformation(TraceSwitches.TfsDeployer, "BatchRunner - Executing Scripts: {0} with arguments {1} in working directory {2}", scriptToRun, psi.Arguments, psi.WorkingDirectory); // Start the process var proc = Process.Start(psi); if (proc == null) { TraceHelper.TraceError(TraceSwitches.TfsDeployer, "Process.Start(...) returned null"); } else { using (var sOut = proc.StandardOutput) { proc.WaitForExit(); output = sOut.ReadToEnd().Trim(); TraceHelper.TraceInformation(TraceSwitches.TfsDeployer, "BatchRunner - Output From Command: {0}", output); } errorOccurred = false; } } var result = new DeployAgentResult { HasErrors = errorOccurred, Output = output }; return(result); }
public DeployAgentResult Deploy(DeployAgentData deployAgentData) { var variables = CreateVariables(deployAgentData); string command = GeneratePipelineCommand(deployAgentData); ExecuteCommand(command, variables); var result = new DeployAgentResult { HasErrors = _errorOccurred, Output = _output }; return(result); }
public DeployAgentData Create(string deployScriptRoot, Mapping mapping, BuildDetail buildDetail, BuildStatusChangeEvent buildStatusChangeEvent) { var data = new DeployAgentData { NewQuality = buildStatusChangeEvent.StatusChange.NewValue, OriginalQuality = buildStatusChangeEvent.StatusChange.OldValue, DeployServer = mapping.Computer, DeployScriptFile = mapping.Script, DeployScriptRoot = deployScriptRoot, DeployScriptParameters = CreateParameters(mapping.ScriptParameters), Timeout = mapping.TimeoutSeconds == 0 ? TimeSpan.MaxValue : TimeSpan.FromSeconds(mapping.TimeoutSeconds), TfsBuildDetail = buildDetail }; return(data); }
private string PrepareDeploymentScript(DeployAgentData deployAgentData) { var fullDeployScriptPath = Path.Combine(deployAgentData.DeployScriptRoot, deployAgentData.DeployScriptFile); var commandBuilder = new StringBuilder(); commandBuilder.AppendFormat("& '{0}'", fullDeployScriptPath.Replace("'", "''")); if (deployAgentData.DeployScriptParameters != null && deployAgentData.DeployScriptParameters.Any()) { CommandInfo commandInfo; using (var shell = PowerShell.Create()) { shell.AddCommand("Get-Command").AddParameter("Name", fullDeployScriptPath); commandInfo = shell.Invoke <CommandInfo>().FirstOrDefault(); } foreach (var deployParam in deployAgentData.DeployScriptParameters) { if (commandInfo.Parameters.ContainsKey(deployParam.Name)) { var commandParam = commandInfo.Parameters[deployParam.Name]; if (commandParam.SwitchParameter) { var value = "$false"; if (Convert.ToBoolean(deployParam.Value)) { value = "$true"; } commandBuilder.AppendFormat(" -{0}:{1}", commandParam.Name, value); } else { commandBuilder.AppendFormat(" -{0} '{1}'", commandParam.Name, deployParam.Value.Replace("'", "''")); } //TODO aliases, shortest unique name } } } return(commandBuilder.ToString()); }
public DeployAgentResult Deploy(DeployAgentData deployAgentData) { var request = new AgentRequest { NoProfile = true, Command = PrepareImportGlobalVariablesScript(deployAgentData) + PrepareDeploymentScript(deployAgentData) }; var runner = new PowerShellAgentRunner(request, deployAgentData.DeployScriptRoot, deployAgentData.Timeout, _clrVersion); if (_deploymentEventRecorder != null) { _deploymentEventRecorder.SetDeploymentOutputDelegate(deployAgentData.DeploymentId, () => runner.Output); } var exitCode = runner.Run(); var result = new DeployAgentResult { HasErrors = exitCode != 0, Output = runner.Output }; return(result); }
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), }); } var psi = new ProcessStartInfo(scriptToRun) { UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardInput = true, RedirectStandardError = true, WorkingDirectory = deployAgentData.DeployScriptRoot, CreateNoWindow = true, Arguments = CreateArguments(deployAgentData), }; TraceHelper.TraceInformation(TraceSwitches.TfsDeployer, "BatchRunner - Executing Scripts: {0} with arguments {1} in working directory {2}", scriptToRun, psi.Arguments, psi.WorkingDirectory); // Start the process var proc = Process.Start(psi); using (var sOut = proc.StandardOutput) { using (var sErr = proc.StandardError) { var errorOccurred = false; var output = string.Empty; // The calls to .ReadToEnd() below will block so we can't make those calls and also check timeouts in the same thread. new Thread(() => { // FIXME we should extract this to an instance method but this class needs to be refactored first so that it's a single-use, // throw-away class. -andrewh 22/12/2010 var timeoutMilliseconds = int.MaxValue; if (deployAgentData.Timeout != TimeSpan.MaxValue) { timeoutMilliseconds = (int)Math.Floor(deployAgentData.Timeout.TotalMilliseconds); } var hasExited = proc.WaitForExit(timeoutMilliseconds); if (hasExited) { return; } try { errorOccurred = true; proc.KillRecursive(); } catch (InvalidOperationException) { // swallow. This occurs if the process exits or is killed between when we decide to kill it and when we actually make the call. } }) { IsBackground = true, Name = "StalledDeploymentMonitor", }.Start(); // try to read from the process's output stream - even if we've killed it. This is an entirely legitimate // thing to do and allows us to capture at least partial output and send it back with any alerts. try { output += sOut.ReadToEnd().Trim(); output += sErr.ReadToEnd().Trim(); } catch { // swallow. grab what we can, but don't complain if the streams are nuked already. } if (errorOccurred) { output += "The deployment process failed to complete within the specified time limit and was terminated.\n"; } TraceHelper.TraceInformation(TraceSwitches.TfsDeployer, "BatchRunner - Output From Command: {0}", output); return(new DeployAgentResult { HasErrors = errorOccurred, Output = output }); } } }