Beispiel #1
0
        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()));
        }
Beispiel #6
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #12
0
        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());
        }
Beispiel #13
0
        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
                    });
                }
            }
        }