Exemple #1
0
        public ContainerInfo(IHostContext hostContext, Pipelines.ContainerResource container, Boolean isJobContainer = true)
        {
            this.ContainerName = container.Alias;

            string containerImage = container.Properties.Get <string>("image");

            ArgUtil.NotNullOrEmpty(containerImage, nameof(containerImage));

            this.ContainerImage            = containerImage;
            this.ContainerDisplayName      = $"{container.Alias}_{Pipelines.Validation.NameValidation.Sanitize(containerImage)}_{Guid.NewGuid().ToString("N").Substring(0, 6)}";
            this.ContainerRegistryEndpoint = container.Endpoint?.Id ?? Guid.Empty;
            this.ContainerCreateOptions    = container.Properties.Get <string>("options");
            this.SkipContainerImagePull    = container.Properties.Get <bool>("localimage");
            _environmentVariables          = container.Environment;
            this.ContainerCommand          = container.Properties.Get <string>("command", defaultValue: "");
            this.IsJobContainer            = isJobContainer;

#if OS_WINDOWS
            _pathMappings[hostContext.GetDirectory(WellKnownDirectory.Tools)] = "C:\\__t"; // Tool cache folder may come from ENV, so we need a unique folder to avoid collision
            _pathMappings[hostContext.GetDirectory(WellKnownDirectory.Work)]  = "C:\\__w";
            _pathMappings[hostContext.GetDirectory(WellKnownDirectory.Root)]  = "C:\\__a";
            // add -v '\\.\pipe\docker_engine:\\.\pipe\docker_engine' when they are available (17.09)
#else
            _pathMappings[hostContext.GetDirectory(WellKnownDirectory.Tools)] = "/__t"; // Tool cache folder may come from ENV, so we need a unique folder to avoid collision
            _pathMappings[hostContext.GetDirectory(WellKnownDirectory.Work)]  = "/__w";
            _pathMappings[hostContext.GetDirectory(WellKnownDirectory.Root)]  = "/__a";
            if (this.IsJobContainer)
            {
                this.MountVolumes.Add(new MountVolume("/var/run/docker.sock", "/var/run/docker.sock"));
            }
#endif
            if (container.Ports?.Count > 0)
            {
                foreach (var port in container.Ports)
                {
                    UserPortMappings[port] = port;
                }
            }
            if (container.Volumes?.Count > 0)
            {
                foreach (var volume in container.Volumes)
                {
                    UserMountVolumes[volume] = volume;
                }
            }
        }
        public ContainerInfo(IHostContext hostContext, Pipelines.JobContainer container, bool isJobContainer = true, string networkAlias = null)
        {
            this.ContainerName = container.Alias;

            string containerImage = container.Image;

            ArgUtil.NotNullOrEmpty(containerImage, nameof(containerImage));

            this.ContainerImage         = containerImage;
            this.ContainerDisplayName   = $"{container.Alias}_{Pipelines.Validation.NameValidation.Sanitize(containerImage)}_{Guid.NewGuid().ToString("N").Substring(0, 6)}";
            this.ContainerCreateOptions = container.Options;
            _environmentVariables       = container.Environment;
            this.IsJobContainer         = isJobContainer;
            this.ContainerNetworkAlias  = networkAlias;

#if OS_WINDOWS
            _pathMappings.Add(new PathMapping(hostContext.GetDirectory(WellKnownDirectory.Work), "C:\\__w"));
            _pathMappings.Add(new PathMapping(hostContext.GetDirectory(WellKnownDirectory.Tools), "C:\\__t")); // Tool cache folder may come from ENV, so we need a unique folder to avoid collision
            _pathMappings.Add(new PathMapping(hostContext.GetDirectory(WellKnownDirectory.Externals), "C:\\__e"));
            // add -v '\\.\pipe\docker_engine:\\.\pipe\docker_engine' when they are available (17.09)
#else
            _pathMappings.Add(new PathMapping(hostContext.GetDirectory(WellKnownDirectory.Work), "/__w"));
            _pathMappings.Add(new PathMapping(hostContext.GetDirectory(WellKnownDirectory.Tools), "/__t")); // Tool cache folder may come from ENV, so we need a unique folder to avoid collision
            _pathMappings.Add(new PathMapping(hostContext.GetDirectory(WellKnownDirectory.Externals), "/__e"));
            if (this.IsJobContainer)
            {
                this.MountVolumes.Add(new MountVolume("/var/run/docker.sock", "/var/run/docker.sock"));
            }
#endif
            if (container.Ports?.Count > 0)
            {
                foreach (var port in container.Ports)
                {
                    UserPortMappings[port] = port;
                }
            }
            if (container.Volumes?.Count > 0)
            {
                foreach (var volume in container.Volumes)
                {
                    UserMountVolumes[volume] = volume;
                }
            }
        }
        // Return code definition: (this will be used by service host to determine whether it will re-launch agent.listener)
        // 0: Agent exit
        // 1: Terminate failure
        // 2: Retriable failure
        // 3: Exit for self update
        public async static Task <int> MainAsync(IHostContext context, string[] args)
        {
            Tracing trace = context.GetTrace("AgentProcess");

            trace.Info($"Agent package {BuildConstants.AgentPackage.PackageName}.");
            trace.Info($"Running on {PlatformUtil.HostOS} ({PlatformUtil.HostArchitecture}).");
            trace.Info($"RuntimeInformation: {RuntimeInformation.OSDescription}.");
            context.WritePerfCounter("AgentProcessStarted");
            var terminal = context.GetService <ITerminal>();

            // TODO: check that the right supporting tools are available for this platform
            // (replaces the check for build platform vs runtime platform)

            try
            {
                trace.Info($"Version: {BuildConstants.AgentPackage.Version}");
                trace.Info($"Commit: {BuildConstants.Source.CommitHash}");
                trace.Info($"Culture: {CultureInfo.CurrentCulture.Name}");
                trace.Info($"UI Culture: {CultureInfo.CurrentUICulture.Name}");

                // Validate directory permissions.
                string agentDirectory = context.GetDirectory(WellKnownDirectory.Root);
                trace.Info($"Validating directory permissions for: '{agentDirectory}'");
                try
                {
                    IOUtil.ValidateExecutePermission(agentDirectory);
                }
                catch (Exception e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }

                if (PlatformUtil.RunningOnWindows)
                {
                    // Validate PowerShell 3.0 or higher is installed.
                    var powerShellExeUtil = context.GetService <IPowerShellExeUtil>();
                    try
                    {
                        powerShellExeUtil.GetPath();
                    }
                    catch (Exception e)
                    {
                        terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                        trace.Error(e);
                        return(Constants.Agent.ReturnCode.TerminatedError);
                    }

                    // Validate .NET Framework 4.5 or higher is installed.
                    if (!NetFrameworkUtil.Test(new Version(4, 5), trace))
                    {
                        terminal.WriteError(StringUtil.Loc("MinimumNetFramework"));
                        return(Constants.Agent.ReturnCode.TerminatedError);
                    }
                }

                // Add environment variables from .env file
                string envFile = Path.Combine(context.GetDirectory(WellKnownDirectory.Root), ".env");
                if (File.Exists(envFile))
                {
                    var envContents = File.ReadAllLines(envFile);
                    foreach (var env in envContents)
                    {
                        if (!string.IsNullOrEmpty(env) && env.IndexOf('=') > 0)
                        {
                            string envKey   = env.Substring(0, env.IndexOf('='));
                            string envValue = env.Substring(env.IndexOf('=') + 1);
                            Environment.SetEnvironmentVariable(envKey, envValue);
                        }
                    }
                }

                // Parse the command line args.
                var command = new CommandSettings(context, args);
                trace.Info("Arguments parsed");

                // Up front validation, warn for unrecognized commandline args.
                var unknownCommandlines = command.Validate();
                if (unknownCommandlines.Count > 0)
                {
                    terminal.WriteError(StringUtil.Loc("UnrecognizedCmdArgs", string.Join(", ", unknownCommandlines)));
                }

                // Defer to the Agent class to execute the command.
                IAgent agent = context.GetService <IAgent>();
                try
                {
                    return(await agent.ExecuteCommand(command));
                }
                catch (OperationCanceledException) when(context.AgentShutdownToken.IsCancellationRequested)
                {
                    trace.Info("Agent execution been cancelled.");
                    return(Constants.Agent.ReturnCode.Success);
                }
                catch (NonRetryableException e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
            }
            catch (Exception e)
            {
                terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                trace.Error(e);
                return(Constants.Agent.ReturnCode.RetryableError);
            }
        }
 public override void Initialize(IHostContext hostContext)
 {
     base.Initialize(hostContext);
     DockerPath          = WhichUtil.Which("docker", true, Trace);
     DockerInstanceLabel = IOUtil.GetPathHash(hostContext.GetDirectory(WellKnownDirectory.Root)).Substring(0, 6);
 }
Exemple #5
0
        // Return code definition: (this will be used by service host to determine whether it will re-launch Runner.Listener)
        // 0: Runner exit
        // 1: Terminate failure
        // 2: Retriable failure
        // 3: Exit for self update
        private async static Task <int> MainAsync(IHostContext context, string[] args)
        {
            Tracing trace = context.GetTrace(nameof(GitHub.Runner.Listener));

            trace.Info($"Runner is built for {Constants.Runner.Platform} ({Constants.Runner.PlatformArchitecture}) - {BuildConstants.RunnerPackage.PackageName}.");
            trace.Info($"RuntimeInformation: {RuntimeInformation.OSDescription}.");
            context.WritePerfCounter("RunnerProcessStarted");
            var terminal = context.GetService <ITerminal>();

            // Validate the binaries intended for one OS are not running on a different OS.
            switch (Constants.Runner.Platform)
            {
            case Constants.OSPlatform.Linux:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    terminal.WriteLine("This runner version is built for Linux. Please install a correct build for your OS.");
                    return(Constants.Runner.ReturnCode.TerminatedError);
                }
                break;

            case Constants.OSPlatform.OSX:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    terminal.WriteLine("This runner version is built for OSX. Please install a correct build for your OS.");
                    return(Constants.Runner.ReturnCode.TerminatedError);
                }
                break;

            case Constants.OSPlatform.Windows:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    terminal.WriteLine("This runner version is built for Windows. Please install a correct build for your OS.");
                    return(Constants.Runner.ReturnCode.TerminatedError);
                }
                break;

            default:
                terminal.WriteLine($"Running the runner on this platform is not supported. The current platform is {RuntimeInformation.OSDescription} and it was built for {Constants.Runner.Platform.ToString()}.");
                return(Constants.Runner.ReturnCode.TerminatedError);
            }

            try
            {
                trace.Info($"Version: {BuildConstants.RunnerPackage.Version}");
                trace.Info($"Commit: {BuildConstants.Source.CommitHash}");
                trace.Info($"Culture: {CultureInfo.CurrentCulture.Name}");
                trace.Info($"UI Culture: {CultureInfo.CurrentUICulture.Name}");

                // Validate directory permissions.
                string runnerDirectory = context.GetDirectory(WellKnownDirectory.Root);
                trace.Info($"Validating directory permissions for: '{runnerDirectory}'");
                try
                {
                    IOUtil.ValidateExecutePermission(runnerDirectory);
                }
                catch (Exception e)
                {
                    terminal.WriteError($"An error occurred: {e.Message}");
                    trace.Error(e);
                    return(Constants.Runner.ReturnCode.TerminatedError);
                }

                // Parse the command line args.
                var command = new CommandSettings(context, args);
                trace.Info("Arguments parsed");

                // Up front validation, warn for unrecognized commandline args.
                var unknownCommandlines = command.Validate();
                if (unknownCommandlines.Count > 0)
                {
                    terminal.WriteError($"Unrecognized command-line input arguments: '{string.Join(", ", unknownCommandlines)}'. For usage refer to: .\\config.cmd --help or ./config.sh --help");
                }

                // Defer to the Runner class to execute the command.
                IRunner runner = context.GetService <IRunner>();
                try
                {
                    return(await runner.ExecuteCommand(command));
                }
                catch (OperationCanceledException) when(context.RunnerShutdownToken.IsCancellationRequested)
                {
                    trace.Info("Runner execution been cancelled.");
                    return(Constants.Runner.ReturnCode.Success);
                }
                catch (NonRetryableException e)
                {
                    terminal.WriteError($"An error occurred: {e.Message}");
                    trace.Error(e);
                    return(Constants.Runner.ReturnCode.TerminatedError);
                }
            }
            catch (Exception e)
            {
                terminal.WriteError($"An error occurred: {e.Message}");
                trace.Error(e);
                return(Constants.Runner.ReturnCode.RetryableError);
            }
        }
Exemple #6
0
        // Return code definition: (this will be used by service host to determine whether it will re-launch agent.listener)
        // 0: Agent exit
        // 1: Terminate failure
        // 2: Retriable failure
        // 3: Exit for self update
        public async static Task <int> MainAsync(IHostContext context, string[] args)
        {
            Tracing trace = context.GetTrace("AgentProcess");

            trace.Info($"Agent is built for {Constants.Agent.Platform} - {BuildConstants.AgentPackage.PackageName}.");
            trace.Info($"RuntimeInformation: {RuntimeInformation.OSDescription}.");
            var terminal = context.GetService <ITerminal>();

            // Validate the binaries intended for one OS are not running on a different OS.
            switch (Constants.Agent.Platform)
            {
            case Constants.OSPlatform.Linux:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    terminal.WriteLine(StringUtil.Loc("NotLinux"));
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
                break;

            case Constants.OSPlatform.OSX:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    terminal.WriteLine(StringUtil.Loc("NotOSX"));
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
                break;

            case Constants.OSPlatform.Windows:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    terminal.WriteLine(StringUtil.Loc("NotWindows"));
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
                break;

            default:
                terminal.WriteLine(StringUtil.Loc("PlatformNotSupport", RuntimeInformation.OSDescription, Constants.Agent.Platform.ToString()));
                return(Constants.Agent.ReturnCode.TerminatedError);
            }

            try
            {
                trace.Info($"Version: {Constants.Agent.Version}");
                trace.Info($"Commit: {BuildConstants.Source.CommitHash}");
                trace.Info($"Culture: {CultureInfo.CurrentCulture.Name}");
                trace.Info($"UI Culture: {CultureInfo.CurrentUICulture.Name}");

                // Validate directory permissions.
                string agentDirectory = context.GetDirectory(WellKnownDirectory.Root);
                trace.Info($"Validating directory permissions for: '{agentDirectory}'");
                try
                {
                    IOUtil.ValidateExecutePermission(agentDirectory);
                }
                catch (Exception e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }

#if OS_WINDOWS
                // Validate PowerShell 3.0 or higher is installed.
                var powerShellExeUtil = context.GetService <IPowerShellExeUtil>();
                try
                {
                    powerShellExeUtil.GetPath();
                }
                catch (Exception e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }

                // Validate .NET Framework 4.5 or higher is installed.
                var netFrameworkUtil = context.GetService <INetFrameworkUtil>();
                if (!netFrameworkUtil.Test(new Version(4, 5)))
                {
                    terminal.WriteError(StringUtil.Loc("MinimumNetFramework"));
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
#endif

                // Add environment variables from .env file
                string envFile = Path.Combine(context.GetDirectory(WellKnownDirectory.Root), ".env");
                if (File.Exists(envFile))
                {
                    var envContents = File.ReadAllLines(envFile);
                    foreach (var env in envContents)
                    {
                        if (!string.IsNullOrEmpty(env) && env.IndexOf('=') > 0)
                        {
                            string envKey   = env.Substring(0, env.IndexOf('='));
                            string envValue = env.Substring(env.IndexOf('=') + 1);
                            Environment.SetEnvironmentVariable(envKey, envValue);
                        }
                    }
                }

                // Parse the command line args.
                var command = new CommandSettings(context, args);
                trace.Info("Arguments parsed");

                // Up front validation, warn for unrecognized commandline args.
                var unknownCommandlines = command.Validate();
                if (unknownCommandlines.Count > 0)
                {
                    terminal.WriteError(StringUtil.Loc("UnrecognizedCmdArgs", string.Join(", ", unknownCommandlines)));
                }

                // Defer to the Agent class to execute the command.
                IAgent agent = context.GetService <IAgent>();
                try
                {
                    return(await agent.ExecuteCommand(command));
                }
                catch (OperationCanceledException) when(context.AgentShutdownToken.IsCancellationRequested)
                {
                    trace.Info("Agent execution been cancelled.");
                    return(Constants.Agent.ReturnCode.Success);
                }
                catch (NonRetryableException e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
            }
            catch (Exception e)
            {
                terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                trace.Error(e);
                return(Constants.Agent.ReturnCode.RetryableError);
            }
        }
Exemple #7
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);
            }
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        // Return code definition: (this will be used by service host to determine whether it will re-launch agent.listener)
        // 0: Agent exit
        // 1: Terminate failure
        // 2: Retriable failure
        // 3: Exit for self update
        private async static Task <int> MainAsync(IHostContext context, string[] args)
        {
            Tracing trace = context.GetTrace("AgentProcess");

            trace.Info($"Agent package {BuildConstants.AgentPackage.PackageName}.");
            trace.Info($"Running on {PlatformUtil.HostOS} ({PlatformUtil.HostArchitecture}).");
            trace.Info($"RuntimeInformation: {RuntimeInformation.OSDescription}.");
            context.WritePerfCounter("AgentProcessStarted");
            var terminal = context.GetService <ITerminal>();

            // TODO: check that the right supporting tools are available for this platform
            // (replaces the check for build platform vs runtime platform)

            try
            {
                trace.Info($"Version: {BuildConstants.AgentPackage.Version}");
                trace.Info($"Commit: {BuildConstants.Source.CommitHash}");
                trace.Info($"Culture: {CultureInfo.CurrentCulture.Name}");
                trace.Info($"UI Culture: {CultureInfo.CurrentUICulture.Name}");

                // Validate directory permissions.
                string agentDirectory = context.GetDirectory(WellKnownDirectory.Root);
                trace.Info($"Validating directory permissions for: '{agentDirectory}'");
                try
                {
                    IOUtil.ValidateExecutePermission(agentDirectory);
                }
                catch (Exception e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }

                if (PlatformUtil.UseLegacyHttpHandler)
                {
                    trace.Warning($"You are using the legacy HTTP handler because you set ${AgentKnobs.LegacyHttpVariableName}.");
                    trace.Warning($"This feature will go away with .NET 5.0, and we recommend you don't use it.");
                    trace.Warning($"If you continue using it, you must ensure libcurl is installed on your system.");
                }

                if (PlatformUtil.RunningOnWindows)
                {
                    // Validate PowerShell 3.0 or higher is installed.
                    var powerShellExeUtil = context.GetService <IPowerShellExeUtil>();
                    try
                    {
                        powerShellExeUtil.GetPath();
                    }
                    catch (Exception e)
                    {
                        terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                        trace.Error(e);
                        return(Constants.Agent.ReturnCode.TerminatedError);
                    }

                    // Validate .NET Framework 4.5 or higher is installed.
                    if (!NetFrameworkUtil.Test(new Version(4, 5), trace))
                    {
                        terminal.WriteError(StringUtil.Loc("MinimumNetFramework"));
                        // warn only, like configurationmanager.cs does. this enables windows edition with just .netcore to work
                    }

                    // Upgrade process priority to avoid Listener starvation
                    using (Process p = Process.GetCurrentProcess())
                    {
                        try
                        {
                            p.PriorityClass = ProcessPriorityClass.AboveNormal;
                        }
                        catch (Exception e)
                        {
                            trace.Warning("Unable to change Windows process priority");
                            trace.Warning(e.Message);
                        }
                    }
                }

                // Add environment variables from .env file
                string envFile = Path.Combine(context.GetDirectory(WellKnownDirectory.Root), ".env");
                if (File.Exists(envFile))
                {
                    var envContents = File.ReadAllLines(envFile);
                    foreach (var env in envContents)
                    {
                        if (!string.IsNullOrEmpty(env) && env.IndexOf('=') > 0)
                        {
                            string envKey   = env.Substring(0, env.IndexOf('='));
                            string envValue = env.Substring(env.IndexOf('=') + 1);
                            Environment.SetEnvironmentVariable(envKey, envValue);
                        }
                    }
                }

                // Parse the command line args.
                var command = new CommandSettings(context, args, new SystemEnvironment());
                trace.Info("Arguments parsed");

                // Print any Parse Errros
                if (command.ParseErrors?.Any() == true)
                {
                    List <string> errorStr = new List <string>();

                    foreach (var error in command.ParseErrors)
                    {
                        if (error is TokenError tokenError)
                        {
                            errorStr.Add(tokenError.Token);
                        }
                        else
                        {
                            // Unknown type of error dump to log
                            terminal.WriteError(StringUtil.Loc("ErrorOccurred", error.Tag));
                        }
                    }

                    terminal.WriteError(
                        StringUtil.Loc("UnrecognizedCmdArgs",
                                       string.Join(", ", errorStr)));
                }

                // Defer to the Agent class to execute the command.
                IAgent agent = context.GetService <IAgent>();
                try
                {
                    return(await agent.ExecuteCommand(command));
                }
                catch (OperationCanceledException) when(context.AgentShutdownToken.IsCancellationRequested)
                {
                    trace.Info("Agent execution been cancelled.");
                    return(Constants.Agent.ReturnCode.Success);
                }
                catch (NonRetryableException e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
            }
            catch (Exception e)
            {
                terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                trace.Error(e);
                return(Constants.Agent.ReturnCode.RetryableError);
            }
        }
Exemple #10
0
        // Return code definition: (this will be used by service host to determine whether it will re-launch agent.listener)
        // 0: Agent exit
        // 1: Terminate failure
        // 2: Retriable failure
        // 3: Exit for self update
        public async static Task <int> MainAsync(IHostContext context, string[] args)
        {
            Tracing trace = context.GetTrace("AgentProcess");

            trace.Info($"Agent is built for {Constants.Agent.Platform} - {BuildConstants.AgentPackage.PackageName}.");
            trace.Info($"RuntimeInformation: {RuntimeInformation.OSDescription}.");
            var terminal = context.GetService <ITerminal>();

            // Validate the binaries intended for one OS are not running on a different OS.
            switch (Constants.Agent.Platform)
            {
            case Constants.OSPlatform.Linux:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    terminal.WriteLine(StringUtil.Loc("NotLinux"));
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
                break;

            case Constants.OSPlatform.OSX:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    terminal.WriteLine(StringUtil.Loc("NotOSX"));
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
                break;

            case Constants.OSPlatform.Windows:
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    terminal.WriteLine(StringUtil.Loc("NotWindows"));
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }
                break;

            default:
                terminal.WriteLine(StringUtil.Loc("PlatformNotSupport", RuntimeInformation.OSDescription, Constants.Agent.Platform.ToString()));
                return(Constants.Agent.ReturnCode.TerminatedError);
            }

            try
            {
                trace.Info($"Version: {Constants.Agent.Version}");
                trace.Info($"Commit: {BuildConstants.Source.CommitHash}");
                trace.Info($"Culture: {CultureInfo.CurrentCulture.Name}");
                trace.Info($"UI Culture: {CultureInfo.CurrentUICulture.Name}");

                // Validate directory permissions.
                string agentDirectory = context.GetDirectory(WellKnownDirectory.Root);
                trace.Info($"Validating directory permissions for: '{agentDirectory}'");
                try
                {
                    IOUtil.ValidateExecutePermission(agentDirectory);
                }
                catch (Exception e)
                {
                    terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                    trace.Error(e);
                    return(Constants.Agent.ReturnCode.TerminatedError);
                }

                // Parse the command line args.
                var command = new CommandSettings(context, args);
                trace.Info("Arguments parsed");

                // Defer to the Agent class to execute the command.
                IAgent agent = context.GetService <IAgent>();
                using (agent.TokenSource = new CancellationTokenSource())
                {
                    try
                    {
                        return(await agent.ExecuteCommand(command));
                    }
                    catch (OperationCanceledException) when(agent.TokenSource.IsCancellationRequested)
                    {
                        trace.Info("Agent execution been cancelled.");
                        return(Constants.Agent.ReturnCode.Success);
                    }
                    catch (NonRetryableException e)
                    {
                        terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                        trace.Error(e);
                        return(Constants.Agent.ReturnCode.TerminatedError);
                    }
                }
            }
            catch (Exception e)
            {
                terminal.WriteError(StringUtil.Loc("ErrorOccurred", e.Message));
                trace.Error(e);
                return(Constants.Agent.ReturnCode.RetryableError);
            }
        }