コード例 #1
0
        // This is only used by build artifact. This isn't a officially supported artifact type in RM
        public async Task DownloadArtifactAsync(IExecutionContext executionContext, IHostContext hostContext, ArtifactDefinition artifactDefinition, string dropLocation, string localFolderPath)
        {
            ArgUtil.NotNull(artifactDefinition, nameof(artifactDefinition));
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNullOrEmpty(localFolderPath, nameof(localFolderPath));
            ArgUtil.NotNullOrEmpty(dropLocation, nameof(dropLocation));

            var trimChars = new[] { '\\', '/' };
            var relativePath = artifactDefinition.Details.RelativePath;

            // If user has specified a relative folder in the drop, change the drop location itself. 
            dropLocation = Path.Combine(dropLocation.TrimEnd(trimChars), relativePath.Trim(trimChars));

            var fileSystemManager = hostContext.CreateService<IReleaseFileSystemManager>();
            List<string> filePaths =
                new DirectoryInfo(dropLocation).EnumerateFiles("*", SearchOption.AllDirectories)
                    .Select(path => path.FullName)
                    .ToList();

            if (filePaths.Any())
            {
                foreach (var filePath in filePaths)
                {
                    var filePathRelativeToDrop = filePath.Replace(dropLocation, string.Empty).Trim(trimChars);
                    using (var fileReader = fileSystemManager.GetFileReader(filePath))
                    {
                        await fileSystemManager.WriteStreamToFile(fileReader.BaseStream, Path.Combine(localFolderPath, filePathRelativeToDrop));
                    }
                }
            }
            else
            {
                executionContext.Warning(StringUtil.Loc("RMNoArtifactsFound", relativePath));
            }
        }
コード例 #2
0
        // This is only used by build artifact. This isn't a officially supported artifact type in RM
        public async Task DownloadArtifactAsync(IExecutionContext executionContext, IHostContext hostContext, ArtifactDefinition artifactDefinition, string dropLocation, string localFolderPath)
        {
            ArgUtil.NotNull(artifactDefinition, nameof(artifactDefinition));
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNullOrEmpty(localFolderPath, nameof(localFolderPath));
            ArgUtil.NotNullOrEmpty(dropLocation, nameof(dropLocation));

            var trimChars    = new[] { '\\', '/' };
            var relativePath = artifactDefinition.Details.RelativePath;

            // If user has specified a relative folder in the drop, change the drop location itself.
            dropLocation = Path.Combine(dropLocation.TrimEnd(trimChars), relativePath.Trim(trimChars));

            var           fileSystemManager = hostContext.CreateService <IReleaseFileSystemManager>();
            List <string> filePaths         =
                new DirectoryInfo(dropLocation).EnumerateFiles("*", SearchOption.AllDirectories)
                .Select(path => path.FullName)
                .ToList();

            if (filePaths.Any())
            {
                foreach (var filePath in filePaths)
                {
                    var filePathRelativeToDrop = filePath.Replace(dropLocation, string.Empty).Trim(trimChars);
                    using (var fileReader = fileSystemManager.GetFileReader(filePath))
                    {
                        await fileSystemManager.WriteStreamToFile(fileReader.BaseStream, Path.Combine(localFolderPath, filePathRelativeToDrop));
                    }
                }
            }
            else
            {
                executionContext.Warning(StringUtil.Loc("RMNoArtifactsFound", relativePath));
            }
        }
コード例 #3
0
ファイル: RSAFileKeyManager.cs プロジェクト: jikuma/vsts
        public RSA CreateKey()
        {
            RSA rsa = null;

            if (!File.Exists(_keyFile))
            {
                Trace.Info("Creating new RSA key using 2048-bit key length");

                rsa         = RSA.Create();
                rsa.KeySize = 2048;

                // Now write the parameters to disk
                IOUtil.SaveObject(rsa.ExportParameters(true), _keyFile);
                Trace.Info("Successfully saved RSA key parameters to file {0}", _keyFile);

                // Try to lock down the credentials_key file to the owner/group
                var whichUtil = _context.GetService <IWhichUtil>();
                var chmodPath = whichUtil.Which("chmod");
                if (!String.IsNullOrEmpty(chmodPath))
                {
                    var arguments = $"600 {new FileInfo(_keyFile).FullName}";
                    using (var invoker = _context.CreateService <IProcessInvoker>())
                    {
                        var exitCode = invoker.ExecuteAsync(IOUtil.GetRootPath(), chmodPath, arguments, null, default(CancellationToken)).GetAwaiter().GetResult();
                        if (exitCode == 0)
                        {
                            Trace.Info("Successfully set permissions for RSA key parameters file {0}", _keyFile);
                        }
                        else
                        {
                            Trace.Warning("Unable to succesfully set permissions for RSA key parameters file {0}. Received exit code {1} from {2}", _keyFile, exitCode, chmodPath);
                        }
                    }
                }
                else
                {
                    Trace.Warning("Unable to locate chmod to set permissions for RSA key parameters file {0}.", _keyFile);
                }
            }
            else
            {
                Trace.Info("Found existing RSA key parameters file {0}", _keyFile);

                rsa = RSA.Create();
                rsa.ImportParameters(IOUtil.LoadObject <RSAParameters>(_keyFile));
            }

            return(rsa);
        }
コード例 #4
0
            public async Task CheckToolOutputAsync(string name, string fileName, string arguments)
            {
                _trace.Entering();
                ArgUtil.NotNullOrEmpty(name, nameof(name));
                ArgUtil.NotNullOrEmpty(fileName, nameof(fileName));
                try
                {
                    // Attempt to locate the tool.
                    string filePath = _whichUtil.Which(fileName);
                    if (string.IsNullOrEmpty(filePath))
                    {
                        return;
                    }

                    // Invoke the tool and capture the output.
                    var output = new StringBuilder();
                    using (var processInvoker = _hostContext.CreateService <IProcessInvoker>())
                    {
                        processInvoker.OutputDataReceived +=
                            (object sender, ProcessDataReceivedEventArgs args) =>
                        {
                            if (!string.IsNullOrEmpty(args.Data))
                            {
                                output.Append(args.Data);
                            }
                        };
                        await processInvoker.ExecuteAsync(
                            workingDirectory : string.Empty,
                            fileName : filePath,
                            arguments : arguments ?? string.Empty,
                            environment : null,
                            cancellationToken : _cancellationToken);
                    }

                    // Add the capability.
                    if (output.Length > 0)
                    {
                        string value = output.ToString();
                        _trace.Info($"Adding '{name}': '{value}'");
                        _capabilities.Add(new Capability(name, value));
                    }
                }
                catch (Exception ex) when(!(ex is OperationCanceledException))
                {
                    _trace.Error(ex);
                }
            }
コード例 #5
0
        private async Task DownloadArtifactUsingFileSystemManagerAsync(IExecutionContext executionContext, IHostContext hostContext, ArtifactDefinition artifactDefinition, string dropLocation, string localFolderPath)
        {
            var trimChars    = new[] { '\\', '/' };
            var relativePath = artifactDefinition.Details.RelativePath;

            // If user has specified a relative folder in the drop, change the drop location itself.
            dropLocation = Path.Combine(dropLocation.TrimEnd(trimChars), relativePath.Trim(trimChars));

            var           fileSystemManager = hostContext.CreateService <IReleaseFileSystemManager>();
            List <string> filePaths         =
                new DirectoryInfo(dropLocation).EnumerateFiles("*", SearchOption.AllDirectories)
                .Select(path => path.FullName)
                .ToList();

            if (filePaths.Any())
            {
                int bufferSize = executionContext.Variables.Release_Download_BufferSize ?? DefaultBufferSize;

                foreach (var filePath in filePaths)
                {
                    string fullPath = Path.GetFullPath(filePath);
                    if (File.Exists(fullPath))
                    {
                        string filePathRelativeToDrop = filePath.Replace(dropLocation, string.Empty).Trim(trimChars);
                        using (StreamReader fileReader = fileSystemManager.GetFileReader(filePath))
                        {
                            await
                            fileSystemManager.WriteStreamToFile(
                                fileReader.BaseStream,
                                Path.Combine(localFolderPath, filePathRelativeToDrop),
                                bufferSize,
                                executionContext.CancellationToken);
                        }
                    }
                    else
                    {
                        executionContext.Warning(StringUtil.Loc("FileNotFound", fullPath));
                    }
                }
            }
            else
            {
                executionContext.Warning(StringUtil.Loc("RMArtifactEmpty"));
            }
        }
コード例 #6
0
        public static async Task SetEncoding(IHostContext hostContext, Tracing trace, CancellationToken cancellationToken)
        {
#if OS_WINDOWS
            try
            {
                if (Console.InputEncoding.CodePage != 65001)
                {
                    using (var p = hostContext.CreateService <IProcessInvoker>())
                    {
                        // Use UTF8 code page
                        int exitCode = await p.ExecuteAsync(workingDirectory : hostContext.GetDirectory(WellKnownDirectory.Work),
                                                            fileName : WhichUtil.Which("chcp", true, trace),
                                                            arguments : "65001",
                                                            environment : null,
                                                            requireExitCodeZero : false,
                                                            outputEncoding : null,
                                                            killProcessOnCancel : false,
                                                            redirectStandardIn : null,
                                                            inheritConsoleHandler : true,
                                                            cancellationToken : cancellationToken);

                        if (exitCode == 0)
                        {
                            trace.Info("Successfully returned to code page 65001 (UTF8)");
                        }
                        else
                        {
                            trace.Warning($"'chcp 65001' failed with exit code {exitCode}");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                trace.Warning($"'chcp 65001' failed with exception {ex.Message}");
            }
#endif
            // Dummy variable to prevent compiler error CS1998: "This async method lacks 'await' operators and will run synchronously..."
            await Task.CompletedTask;
        }
コード例 #7
0
        private async Task DownloadArtifactUsingRobocopyAsync(IExecutionContext executionContext, IHostContext hostContext, ArtifactDefinition artifactDefinition, string dropLocation, string downloadFolderPath)
        {
            int? robocopyMT = executionContext.Variables.GetInt(Constants.Variables.Release.RobocopyMT);
            bool verbose    = executionContext.Variables.GetBoolean(Constants.Variables.System.Debug) ?? false;

            if (robocopyMT != null)
            {
                if (robocopyMT < 1)
                {
                    robocopyMT = 1;
                }
                else if (robocopyMT > 128)
                {
                    robocopyMT = 128;
                }
            }

            executionContext.Output(StringUtil.Loc("RMDownloadingArtifactUsingRobocopy"));
            using (var processInvoker = hostContext.CreateService <IProcessInvoker>())
            {
                // Save STDOUT from worker, worker will use STDOUT report unhandle exception.
                processInvoker.OutputDataReceived += delegate(object sender, ProcessDataReceivedEventArgs stdout)
                {
                    if (!string.IsNullOrEmpty(stdout.Data))
                    {
                        executionContext.Output(stdout.Data);
                    }
                };

                // Save STDERR from worker, worker will use STDERR on crash.
                processInvoker.ErrorDataReceived += delegate(object sender, ProcessDataReceivedEventArgs stderr)
                {
                    if (!string.IsNullOrEmpty(stderr.Data))
                    {
                        executionContext.Error(stderr.Data);
                    }
                };

                var trimChars    = new[] { '\\', '/' };
                var relativePath = artifactDefinition.Details.RelativePath;

                dropLocation       = Path.Combine(dropLocation.TrimEnd(trimChars), relativePath.Trim(trimChars));
                downloadFolderPath = downloadFolderPath.TrimEnd(trimChars);

                string robocopyArguments = "\"" + dropLocation + "\" \"" + downloadFolderPath + "\" /E /Z /NP /R:3";
                if (verbose != true)
                {
                    robocopyArguments = robocopyArguments + " /NDL /NFL";
                }

                if (robocopyMT != null)
                {
                    robocopyArguments = robocopyArguments + " /MT:" + robocopyMT;
                }

                int exitCode = await processInvoker.ExecuteAsync(
                    workingDirectory : "",
                    fileName : "robocopy",
                    arguments : robocopyArguments,
                    environment : null,
                    requireExitCodeZero : false,
                    outputEncoding : null,
                    killProcessOnCancel : true,
                    cancellationToken : executionContext.CancellationToken);

                executionContext.Output(StringUtil.Loc("RMRobocopyBasedArtifactDownloadExitCode", exitCode));

                if (exitCode >= 8)
                {
                    throw new ArtifactDownloadException(StringUtil.Loc("RMRobocopyBasedArtifactDownloadFailed", exitCode));
                }
            }
        }
コード例 #8
0
        private static string GetEnvironmentVariableUsingPs(Process process, IHostContext hostContext, string variable)
        {
            // On OSX, there is no /proc folder for us to read environment for given process,
            // So we have call `ps e -p <pid> -o command` to print out env to STDOUT,
            // However, the output env are not format in a parseable way, it's just a string that concatenate all envs with space,
            // It doesn't escape '=' or ' ', so we can't parse the output into a dictionary of all envs.
            // So we only look for the env you request, in the format of variable=value. (it won't work if you variable contains = or space)
            var trace = hostContext.GetTrace(nameof(ProcessExtensions));

            trace.Info($"Read env from output of `ps e -p {process.Id} -o command`");

            Dictionary <string, string> env = new Dictionary <string, string>();
            List <string> psOut             = new List <string>();
            object        outputLock        = new object();

            using (var p = hostContext.CreateService <IProcessInvoker>())
            {
                p.OutputDataReceived += delegate(object sender, ProcessDataReceivedEventArgs stdout)
                {
                    if (!string.IsNullOrEmpty(stdout.Data))
                    {
                        lock (outputLock)
                        {
                            psOut.Add(stdout.Data);
                        }
                    }
                };

                p.ErrorDataReceived += delegate(object sender, ProcessDataReceivedEventArgs stderr)
                {
                    if (!string.IsNullOrEmpty(stderr.Data))
                    {
                        lock (outputLock)
                        {
                            trace.Error(stderr.Data);
                        }
                    }
                };

                int exitCode = p.ExecuteAsync(workingDirectory: hostContext.GetDirectory(WellKnownDirectory.Root),
                                              fileName: "ps",
                                              arguments: $"e -p {process.Id} -o command",
                                              environment: null,
                                              cancellationToken: CancellationToken.None).GetAwaiter().GetResult();
                if (exitCode == 0)
                {
                    trace.Info($"Successfully dump environment variables for {process.Id}");
                    if (psOut.Count > 0)
                    {
                        string psOutputString = string.Join(" ", psOut);
                        trace.Verbose($"ps output: '{psOutputString}'");

                        int varStartIndex = psOutputString.IndexOf(variable, StringComparison.Ordinal);
                        if (varStartIndex >= 0)
                        {
                            string rightPart = psOutputString.Substring(varStartIndex + variable.Length + 1);
                            if (rightPart.IndexOf(' ') > 0)
                            {
                                string value = rightPart.Substring(0, rightPart.IndexOf(' '));
                                env[variable] = value;
                            }
                            else
                            {
                                env[variable] = rightPart;
                            }

                            trace.Verbose($"PID:{process.Id} ({variable}={env[variable]})");
                        }
                    }
                }
            }

            if (env.TryGetValue(variable, out string envVariable))
            {
                return(envVariable);
            }
            else
            {
                return(null);
            }
        }
コード例 #9
0
ファイル: CheckUtil.cs プロジェクト: rust-lang/gha-runner
        public static async Task <CheckResult> DownloadExtraCA(this IHostContext hostContext, string url, string pat)
        {
            var result = new CheckResult();

            try
            {
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ****                                                                                                       ****");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ****     Download SSL Certificate from {url} ");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ****                                                                                                       ****");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");

                var uri = new Uri(url);
                var env = new Dictionary <string, string>()
                {
                    { "HOSTNAME", uri.Host },
                    { "PORT", uri.IsDefaultPort ? (uri.Scheme.ToLowerInvariant() == "https" ? "443" : "80") : uri.Port.ToString() },
                    { "PATH", uri.AbsolutePath },
                    { "PAT", pat }
                };

                var proxy = hostContext.WebProxy.GetProxy(uri);
                if (proxy != null)
                {
                    env["PROXYHOST"] = proxy.Host;
                    env["PROXYPORT"] = proxy.IsDefaultPort ? (proxy.Scheme.ToLowerInvariant() == "https" ? "443" : "80") : proxy.Port.ToString();
                    if (hostContext.WebProxy.HttpProxyUsername != null ||
                        hostContext.WebProxy.HttpsProxyUsername != null)
                    {
                        env["PROXYUSERNAME"] = hostContext.WebProxy.HttpProxyUsername ?? hostContext.WebProxy.HttpsProxyUsername;
                        env["PROXYPASSWORD"] = hostContext.WebProxy.HttpProxyPassword ?? hostContext.WebProxy.HttpsProxyPassword;
                    }
                    else
                    {
                        env["PROXYUSERNAME"] = "";
                        env["PROXYPASSWORD"] = "";
                    }
                }
                else
                {
                    env["PROXYHOST"]     = "";
                    env["PROXYPORT"]     = "";
                    env["PROXYUSERNAME"] = "";
                    env["PROXYPASSWORD"] = "";
                }

                using (var processInvoker = hostContext.CreateService <IProcessInvoker>())
                {
                    processInvoker.OutputDataReceived += new EventHandler <ProcessDataReceivedEventArgs>((sender, args) =>
                    {
                        if (!string.IsNullOrEmpty(args.Data))
                        {
                            result.Logs.Add($"{DateTime.UtcNow.ToString("O")} [STDOUT] {args.Data}");
                        }
                    });

                    processInvoker.ErrorDataReceived += new EventHandler <ProcessDataReceivedEventArgs>((sender, args) =>
                    {
                        if (!string.IsNullOrEmpty(args.Data))
                        {
                            result.Logs.Add($"{DateTime.UtcNow.ToString("O")} [STDERR] {args.Data}");
                        }
                    });

                    var downloadCertScript = Path.Combine(hostContext.GetDirectory(WellKnownDirectory.Bin), "checkScripts", "downloadCert");
                    var node12             = Path.Combine(hostContext.GetDirectory(WellKnownDirectory.Externals), "node12", "bin", $"node{IOUtil.ExeExtension}");
                    result.Logs.Add($"{DateTime.UtcNow.ToString("O")} Run '{node12} \"{downloadCertScript}\"' ");
                    result.Logs.Add($"{DateTime.UtcNow.ToString("O")} {StringUtil.ConvertToJson(env)}");
                    await processInvoker.ExecuteAsync(
                        hostContext.GetDirectory(WellKnownDirectory.Root),
                        node12,
                        $"\"{downloadCertScript}\"",
                        env,
                        true,
                        CancellationToken.None);
                }

                result.Pass = true;
            }
            catch (Exception ex)
            {
                result.Pass = false;
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ****                                                                                                       ****");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ****     Download SSL Certificate from '{url}' failed with error: {ex}");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ****                                                                                                       ****");
                result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");
            }

            return(result);
        }
コード例 #10
0
 public override void Initialize(IHostContext hostContext)
 {
     base.Initialize(hostContext);
     ActionCommandManager = hostContext.CreateService <IActionCommandManager>();
 }