コード例 #1
0
        public override DeploymentResult Deploy()
        {
            // Start timer
            StartTimer();

            // For now we always auto-publish. Otherwise we'll have to write our own local web.config for the HttpPlatformHandler
            DeploymentParameters.PublishApplicationBeforeDeployment = true;
            if (DeploymentParameters.PublishApplicationBeforeDeployment)
            {
                DotnetPublish();
            }

            var contentRoot = DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath;

            var uri = TestUriHelper.BuildTestUri(DeploymentParameters.ApplicationBaseUriHint);
            // Launch the host process.
            var hostExitToken = StartIISExpress(uri, contentRoot);

            return(new DeploymentResult
            {
                ContentRoot = contentRoot,
                DeploymentParameters = DeploymentParameters,
                // Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath.
                ApplicationBaseUri = uri.ToString(),
                HostShutdownToken = hostExitToken
            });
        }
コード例 #2
0
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("SelfHost.Deploy"))
            {
                // Start timer
                StartTimer();

                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                }

                var hintUrl = TestUriHelper.BuildTestUri(
                    DeploymentParameters.ServerType,
                    DeploymentParameters.Scheme,
                    DeploymentParameters.ApplicationBaseUriHint,
                    DeploymentParameters.StatusMessagesEnabled);

                // Launch the host process.
                var(actualUrl, hostExitToken) = await StartSelfHostAsync(hintUrl);

                Logger.LogInformation("Application ready at URL: {appUrl}", actualUrl);

                return(new DeploymentResult(
                           LoggerFactory,
                           DeploymentParameters,
                           applicationBaseUri: actualUrl.ToString(),
                           contentRoot: DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath,
                           hostShutdownToken: hostExitToken));
            }
        }
コード例 #3
0
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("Deployment"))
            {
                StartTimer();

                var contentRoot = string.Empty;
                if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent))
                {
                    DeploymentParameters.ServerConfigTemplateContent = File.ReadAllText("IIS.config");
                }

                _application = new IISApplication(IISDeploymentParameters, Logger);

                // For now, only support using published output
                DeploymentParameters.PublishApplicationBeforeDeployment = true;

                if (DeploymentParameters.ApplicationType == ApplicationType.Portable)
                {
                    DefaultWebConfigActions.Add(
                        WebConfigHelpers.AddOrModifyAspNetCoreSection(
                            "processPath",
                            DotNetCommands.GetDotNetExecutable(DeploymentParameters.RuntimeArchitecture)));
                }

                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                    contentRoot = DeploymentParameters.PublishedApplicationRootPath;
                    // Do not override settings set on parameters
                    if (!IISDeploymentParameters.HandlerSettings.ContainsKey("debugLevel") &&
                        !IISDeploymentParameters.HandlerSettings.ContainsKey("debugFile"))
                    {
                        var logFile = Path.Combine(contentRoot, $"{_application.WebSiteName}.txt");
                        IISDeploymentParameters.HandlerSettings["debugLevel"] = "4";
                        IISDeploymentParameters.HandlerSettings["debugFile"]  = logFile;
                    }

                    DefaultWebConfigActions.Add(WebConfigHelpers.AddOrModifyHandlerSection(
                                                    key: "modules",
                                                    value: DeploymentParameters.AncmVersion.ToString()));
                    RunWebConfigActions(contentRoot);
                }

                var uri = TestUriHelper.BuildTestUri(ServerType.IIS, DeploymentParameters.ApplicationBaseUriHint);
                // To prevent modifying the IIS setup concurrently.
                await _application.StartIIS(uri, contentRoot);

                // Warm up time for IIS setup.
                Logger.LogInformation("Successfully finished IIS application directory setup.");
                return(new IISDeploymentResult(
                           LoggerFactory,
                           IISDeploymentParameters,
                           applicationBaseUri: uri.ToString(),
                           contentRoot: contentRoot,
                           hostShutdownToken: _hostShutdownToken.Token,
                           hostProcess: _application.HostProcess
                           ));
            }
        }
コード例 #4
0
        public override DeploymentResult Deploy()
        {
            _configFile = Path.GetTempFileName();
            var uri = new Uri(DeploymentParameters.ApplicationBaseUriHint);

            var redirectUri = $"http://localhost:{TestUriHelper.FindFreePort()}";

            var exitToken = StartSelfHost(new Uri(redirectUri));

            SetupNginx(redirectUri, uri);

            // Wait for App to be loaded since Nginx returns 502 instead of 503 when App isn't loaded
            // Target actual address to avoid going through Nginx proxy
            using (var httpClient = new HttpClient())
            {
                var response = RetryHelper.RetryRequest(() =>
                {
                    return(httpClient.GetAsync(redirectUri));
                }, Logger).Result;

                if (!response.IsSuccessStatusCode)
                {
                    throw new InvalidOperationException("Deploy failed");
                }
            }

            return(new DeploymentResult
            {
                WebRootLocation = DeploymentParameters.ApplicationPath,
                DeploymentParameters = DeploymentParameters,
                ApplicationBaseUri = uri.ToString(),
                HostShutdownToken = exitToken
            });
        }
コード例 #5
0
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("Deployment"))
            {
                // Start timer
                StartTimer();

                // For now we always auto-publish. Otherwise we'll have to write our own local web.config for the HttpPlatformHandler
                DeploymentParameters.PublishApplicationBeforeDeployment = true;
                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                }

                var contentRoot = DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath;

                var testUri = TestUriHelper.BuildTestUri(DeploymentParameters.ApplicationBaseUriHint);

                // Launch the host process.
                var(actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot);

                Logger.LogInformation("Application ready at URL: {appUrl}", actualUri);

                // Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath.
                return(new DeploymentResult(
                           LoggerFactory,
                           DeploymentParameters,
                           applicationBaseUri: actualUri.ToString(),
                           contentRoot: contentRoot,
                           hostShutdownToken: hostExitToken));
            }
        }
コード例 #6
0
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("SelfHost.Deploy"))
            {
                // Start timer
                StartTimer();

                if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr &&
                    DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86)
                {
                    // Publish is required to rebuild for the right bitness
                    DeploymentParameters.PublishApplicationBeforeDeployment = true;
                }

                if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr &&
                    DeploymentParameters.ApplicationType == ApplicationType.Standalone)
                {
                    // Publish is required to get the correct files in the output directory
                    DeploymentParameters.PublishApplicationBeforeDeployment = true;
                }

                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                }

                // Launch the host process.
                for (var i = 0; i < RetryCount; i++)
                {
                    var hintUrl = TestUriHelper.BuildTestUri(
                        DeploymentParameters.ServerType,
                        DeploymentParameters.Scheme,
                        DeploymentParameters.ApplicationBaseUriHint,
                        DeploymentParameters.StatusMessagesEnabled);
                    var(actualUrl, hostExitToken) = await StartSelfHostAsync(hintUrl);

                    if (DeploymentParameters.ServerType == ServerType.HttpSys && hostExitToken.IsCancellationRequested)
                    {
                        // Retry HttpSys deployments due to port conflicts.
                        continue;
                    }

                    Logger.LogInformation("Application ready at URL: {appUrl}", actualUrl);

                    return(new DeploymentResult(
                               LoggerFactory,
                               DeploymentParameters,
                               applicationBaseUri: actualUrl.ToString(),
                               contentRoot: DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath,
                               hostShutdownToken: hostExitToken));
                }

                throw new Exception($"Failed to start Self hosted application after {RetryCount} retries.");
            }
        }
コード例 #7
0
    public override Task <DeploymentResult> DeployAsync()
    {
        using (Logger.BeginScope("Deployment"))
        {
            StartTimer();

            Logger.LogInformation(Environment.OSVersion.ToString());

            if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent))
            {
                DeploymentParameters.ServerConfigTemplateContent = File.ReadAllText("IIS.config");
            }

            // For now, only support using published output
            DeploymentParameters.PublishApplicationBeforeDeployment = true;
            // Move ASPNETCORE_DETAILEDERRORS to web config env variables
            if (IISDeploymentParameters.EnvironmentVariables.ContainsKey(DetailedErrorsEnvironmentVariable))
            {
                IISDeploymentParameters.WebConfigBasedEnvironmentVariables[DetailedErrorsEnvironmentVariable] =
                    IISDeploymentParameters.EnvironmentVariables[DetailedErrorsEnvironmentVariable];

                IISDeploymentParameters.EnvironmentVariables.Remove(DetailedErrorsEnvironmentVariable);
            }
            // Do not override settings set on parameters
            if (!IISDeploymentParameters.HandlerSettings.ContainsKey("debugLevel") &&
                !IISDeploymentParameters.HandlerSettings.ContainsKey("debugFile"))
            {
                _debugLogFile = Path.GetTempFileName();
                IISDeploymentParameters.HandlerSettings["debugLevel"] = "file";
                IISDeploymentParameters.HandlerSettings["debugFile"]  = _debugLogFile;
            }

            DotnetPublish();
            var contentRoot = DeploymentParameters.PublishedApplicationRootPath;

            RunWebConfigActions(contentRoot);

            var uri = TestUriHelper.BuildTestUri(ServerType.IIS, DeploymentParameters.ApplicationBaseUriHint);
            StartIIS(uri, contentRoot);

            // Warm up time for IIS setup.
            Logger.LogInformation("Successfully finished IIS application directory setup.");
            return(Task.FromResult <DeploymentResult>(new IISDeploymentResult(
                                                          LoggerFactory,
                                                          IISDeploymentParameters,
                                                          applicationBaseUri: uri.ToString(),
                                                          contentRoot: contentRoot,
                                                          hostShutdownToken: _hostShutdownToken.Token,
                                                          hostProcess: HostProcess
                                                          )));
        }
    }
コード例 #8
0
ファイル: NginxDeployer.cs プロジェクト: rewrrtf/Hosting
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("Deploy"))
            {
                _configFile = Path.GetTempFileName();
                var uri = string.IsNullOrEmpty(DeploymentParameters.ApplicationBaseUriHint) ?
                          TestUriHelper.BuildTestUri(ServerType.Nginx) :
                          new Uri(DeploymentParameters.ApplicationBaseUriHint);

                var redirectUri = TestUriHelper.BuildTestUri(ServerType.Nginx);

                if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr &&
                    DeploymentParameters.ApplicationType == ApplicationType.Standalone)
                {
                    // Publish is required to get the correct files in the output directory
                    DeploymentParameters.PublishApplicationBeforeDeployment = true;
                }

                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                }

                var(appUri, exitToken) = await StartSelfHostAsync(redirectUri);

                SetupNginx(appUri.ToString(), uri);

                Logger.LogInformation("Application ready at URL: {appUrl}", uri);

                // Wait for App to be loaded since Nginx returns 502 instead of 503 when App isn't loaded
                // Target actual address to avoid going through Nginx proxy
                using (var httpClient = new HttpClient())
                {
                    var response = await RetryHelper.RetryRequest(() =>
                    {
                        return(httpClient.GetAsync(redirectUri));
                    }, Logger, exitToken);

                    if (!response.IsSuccessStatusCode)
                    {
                        throw new InvalidOperationException("Deploy failed");
                    }
                }

                return(new DeploymentResult(
                           LoggerFactory,
                           DeploymentParameters,
                           applicationBaseUri: uri.ToString(),
                           contentRoot: DeploymentParameters.ApplicationPath,
                           hostShutdownToken: exitToken));
            }
        }
コード例 #9
0
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("SelfHost.Deploy"))
            {
                // Start timer
                StartTimer();

                if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.Clr &&
                    DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86)
                {
                    // Publish is required to rebuild for the right bitness
                    DeploymentParameters.PublishApplicationBeforeDeployment = true;
                }

                if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr &&
                    DeploymentParameters.ApplicationType == ApplicationType.Standalone)
                {
                    // Publish is required to get the correct files in the output directory
                    DeploymentParameters.PublishApplicationBeforeDeployment = true;
                }

                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                }

                var hintUrl = TestUriHelper.BuildTestUri(
                    DeploymentParameters.ServerType,
                    DeploymentParameters.Scheme,
                    DeploymentParameters.ApplicationBaseUriHint,
                    DeploymentParameters.StatusMessagesEnabled);

                // Launch the host process.
                var(actualUrl, hostExitToken) = await StartSelfHostAsync(hintUrl);

                Logger.LogInformation("Application ready at URL: {appUrl}", actualUrl);

                return(new DeploymentResult(
                           LoggerFactory,
                           DeploymentParameters,
                           applicationBaseUri: actualUrl.ToString(),
                           contentRoot: DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath,
                           hostShutdownToken: hostExitToken));
            }
        }
コード例 #10
0
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("Deployment"))
            {
                StartTimer();

                var contentRoot = string.Empty;
                if (string.IsNullOrEmpty(DeploymentParameters.ServerConfigTemplateContent))
                {
                    DeploymentParameters.ServerConfigTemplateContent = File.ReadAllText("IIS.config");
                }

                _application = new IISApplication(DeploymentParameters, Logger);

                // For now, only support using published output
                DeploymentParameters.PublishApplicationBeforeDeployment = true;
                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                    contentRoot = DeploymentParameters.PublishedApplicationRootPath;
                }

                WebConfigHelpers.AddDebugLogToWebConfig(contentRoot, Path.Combine(contentRoot, $"{_application.WebSiteName}.txt"));

                var uri = TestUriHelper.BuildTestUri(ServerType.IIS, DeploymentParameters.ApplicationBaseUriHint);
                // To prevent modifying the IIS setup concurrently.
                await _application.StartIIS(uri, contentRoot);

                // Warm up time for IIS setup.
                Logger.LogInformation("Successfully finished IIS application directory setup.");

                return(new DeploymentResult(
                           LoggerFactory,
                           DeploymentParameters,
                           applicationBaseUri: uri.ToString(),
                           contentRoot: contentRoot,
                           hostShutdownToken: _hostShutdownToken.Token
                           ));
            }
        }
コード例 #11
0
ファイル: SelfHostDeployer.cs プロジェクト: mrahhal/Hosting
        public override DeploymentResult Deploy()
        {
            // Start timer
            StartTimer();

            if (DeploymentParameters.PublishApplicationBeforeDeployment)
            {
                DotnetPublish();
            }

            var uri = TestUriHelper.BuildTestUri(DeploymentParameters.ApplicationBaseUriHint);
            // Launch the host process.
            var hostExitToken = StartSelfHost(uri);

            return(new DeploymentResult
            {
                WebRootLocation = DeploymentParameters.ApplicationPath,
                DeploymentParameters = DeploymentParameters,
                ApplicationBaseUri = uri.ToString(),
                HostShutdownToken = hostExitToken
            });
        }
コード例 #12
0
ファイル: IISDeployer.cs プロジェクト: lodejard/AllNetCore
        public override DeploymentResult Deploy()
        {
            // Start timer
            StartTimer();

            // Only supports publish and run on IIS.
            DeploymentParameters.PublishApplicationBeforeDeployment = true;

            _application = new IISApplication(DeploymentParameters, Logger);

            // Publish to IIS root\application folder.
            DotnetPublish(publishRoot: _application.WebSiteRootFolder);

            // Drop a json file instead of setting environment variable.
            SetAspEnvironmentWithJson();

            var uri = TestUriHelper.BuildTestUri();

            lock (_syncObject)
            {
                // To prevent modifying the IIS setup concurrently.
                _application.Deploy(uri);
            }

            // Warm up time for IIS setup.
            Thread.Sleep(1 * 1000);
            Logger.LogInformation("Successfully finished IIS application directory setup.");

            return(new DeploymentResult
            {
                WebRootLocation = DeploymentParameters.ApplicationPath,
                DeploymentParameters = DeploymentParameters,
                // Accomodate the vdir name.
                ApplicationBaseUri = uri.ToString(),
                HostShutdownToken = _hostShutdownToken.Token
            });
        }
コード例 #13
0
        public override async Task <DeploymentResult> DeployAsync()
        {
            using (Logger.BeginScope("Deployment"))
            {
                // Start timer
                StartTimer();

                // For an unpublished application the dllroot points pre-built dlls like projectdir/bin/debug/netcoreapp3.0/
                // and contentRoot points to the project directory so you get things like static assets.
                // For a published app both point to the publish directory.
                var dllRoot     = CheckIfPublishIsRequired();
                var contentRoot = string.Empty;
                if (DeploymentParameters.PublishApplicationBeforeDeployment)
                {
                    DotnetPublish();
                    contentRoot = DeploymentParameters.PublishedApplicationRootPath;
                }
                else
                {
                    // Core+Standalone always publishes. This must be Clr+Standalone or Core+Portable.
                    // Update processPath and arguments for our current scenario
                    contentRoot = DeploymentParameters.ApplicationPath;

                    var executableExtension = DeploymentParameters.ApplicationType == ApplicationType.Portable ? ".dll" : ".exe";
                    var entryPoint          = Path.Combine(dllRoot, DeploymentParameters.ApplicationName + executableExtension);

                    var executableName = string.Empty;
                    var executableArgs = string.Empty;

                    if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr && DeploymentParameters.ApplicationType == ApplicationType.Portable)
                    {
                        executableName = GetDotNetExeForArchitecture();
                        executableArgs = entryPoint;
                    }
                    else
                    {
                        executableName = entryPoint;
                    }

                    Logger.LogInformation("Executing: {exe} {args}", executableName, executableArgs);
                    DeploymentParameters.EnvironmentVariables["LAUNCHER_PATH"] = executableName;
                    DeploymentParameters.EnvironmentVariables["LAUNCHER_ARGS"] = executableArgs;

                    // CurrentDirectory will point to bin/{config}/{tfm}, but the config and static files aren't copied, point to the app base instead.
                    Logger.LogInformation("ContentRoot: {path}", DeploymentParameters.ApplicationPath);
                    DeploymentParameters.EnvironmentVariables["ASPNETCORE_CONTENTROOT"] = DeploymentParameters.ApplicationPath;
                }

                RunWebConfigActions(contentRoot);

                var testUri = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint);

                // Launch the host process.
                var(actualUri, hostExitToken) = await StartIISExpressAsync(testUri, contentRoot);

                Logger.LogInformation("Application ready at URL: {appUrl}", actualUri);

                // Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath.

                return(new IISDeploymentResult(
                           LoggerFactory,
                           IISDeploymentParameters,
                           applicationBaseUri: actualUri.ToString(),
                           contentRoot: contentRoot,
                           hostShutdownToken: hostExitToken,
                           hostProcess: _hostProcess));
            }
        }
コード例 #14
0
    private async Task <(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(string contentRoot)
    {
        using (Logger.BeginScope("StartIISExpress"))
        {
            var iisExpressPath = GetIISExpressPath();

            for (var attempt = 0; attempt < MaximumAttempts; attempt++)
            {
                var uri  = TestUriHelper.BuildTestUri(ServerType.IISExpress, DeploymentParameters.ApplicationBaseUriHint);
                var port = uri.Port;
                if (port == 0)
                {
                    port = (uri.Scheme == "https") ? TestPortHelper.GetNextSSLPort() : TestPortHelper.GetNextPort();
                }

                Logger.LogInformation("Attempting to start IIS Express on port: {port}", port);
                PrepareConfig(contentRoot, port);

                var parameters = string.IsNullOrEmpty(DeploymentParameters.ServerConfigLocation) ?
                                 string.Format(CultureInfo.InvariantCulture, "/port:{0} /path:\"{1}\" /trace:error /systray:false", uri.Port, contentRoot) :
                                 string.Format(CultureInfo.InvariantCulture, "/site:{0} /config:{1} /trace:error /systray:false", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation);

                Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters);

                var startInfo = new ProcessStartInfo
                {
                    FileName               = iisExpressPath,
                    Arguments              = parameters,
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    // VS sets current directory to C:\Program Files\IIS Express
                    WorkingDirectory = Path.GetDirectoryName(iisExpressPath)
                };

                AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables);

                Uri url     = null;
                var started = new TaskCompletionSource <bool>();

                var process = new Process()
                {
                    StartInfo = startInfo
                };
                process.OutputDataReceived += (sender, dataArgs) =>
                {
                    if (string.Equals(dataArgs.Data, UnableToStartIISExpressMessage, StringComparison.Ordinal))
                    {
                        // We completely failed to start and we don't really know why
                        started.TrySetException(new InvalidOperationException("Failed to start IIS Express"));
                    }
                    else if (string.Equals(dataArgs.Data, FailedToInitializeBindingsMessage, StringComparison.Ordinal))
                    {
                        started.TrySetResult(false);
                    }
                    else if (string.Equals(dataArgs.Data, IISExpressRunningMessage, StringComparison.Ordinal))
                    {
                        started.TrySetResult(true);
                    }
                    else if (!string.IsNullOrEmpty(dataArgs.Data))
                    {
                        var m = UrlDetectorRegex.Match(dataArgs.Data);
                        if (m.Success)
                        {
                            url = new Uri(m.Groups["url"].Value);
                        }
                    }
                };

                process.EnableRaisingEvents = true;
                var hostExitTokenSource = new CancellationTokenSource();
                process.Exited += (sender, e) =>
                {
                    Logger.LogInformation("iisexpress Process {pid} shut down", process.Id);

                    // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want
                    started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {process.ExitCode}"));

                    TriggerHostShutdown(hostExitTokenSource);
                };
                process.StartAndCaptureOutAndErrToLogger("iisexpress", Logger);
                Logger.LogInformation("iisexpress Process {pid} started", process.Id);

                if (process.HasExited)
                {
                    Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, process.Id, process.ExitCode);
                    throw new Exception("Failed to start host");
                }

                // Wait for the app to start
                // The timeout here is large, because we don't know how long the test could need
                // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build
                // just in case we missed one -anurse
                if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10)))
                {
                    Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", process.Id, port);

                    // Wait for the process to exit and try again
                    process.WaitForExit(30 * 1000);
                    await Task.Delay(1000); // Wait a second to make sure the socket is completely cleaned up
                }
                else
                {
                    _hostProcess = process;

                    // Ensure iisexpress.exe is killed if test process termination is non-graceful.
                    // Prevents locked files when stop debugging unit test.
                    ProcessTracker.Add(_hostProcess);

                    // cache the process start time for verifying log file name.
                    var _ = _hostProcess.StartTime;

                    Logger.LogInformation("Started iisexpress successfully. Process Id : {processId}, Port: {port}", _hostProcess.Id, port);
                    return(url : url, hostExitToken : hostExitTokenSource.Token);
                }
            }

            var message = $"Failed to initialize IIS Express after {MaximumAttempts} attempts to select a port";
            Logger.LogError(message);
            throw new TimeoutException(message);
        }
    }
コード例 #15
0
        private async Task <(Uri url, CancellationToken hostExitToken)> StartIISExpressAsync(Uri uri, string contentRoot)
        {
            using (Logger.BeginScope("StartIISExpress"))
            {
                var port = uri.Port;
                if (port == 0)
                {
                    port = TestUriHelper.GetNextPort();
                }

                for (var attempt = 0; attempt < MaximumAttempts; attempt++)
                {
                    Logger.LogInformation("Attempting to start IIS Express on port: {port}", port);

                    if (!string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigTemplateContent))
                    {
                        var serverConfig = DeploymentParameters.ServerConfigTemplateContent;

                        // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config
                        // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo.

                        if (serverConfig.Contains("[ANCMPath]"))
                        {
                            string ancmPath;
                            if (!IsWin8OrLater)
                            {
                                // The nupkg build of ANCM does not support Win7. https://github.com/aspnet/AspNetCoreModule/issues/40.
                                ancmPath = @"%ProgramFiles%\IIS Express\aspnetcore.dll";
                            }
                            else
                            {
                                // We need to pick the bitness based the OS / IIS Express, not the application.
                                // We'll eventually add support for choosing which IIS Express bitness to run: https://github.com/aspnet/Hosting/issues/880
                                var ancmFile = Is64BitHost ? "aspnetcore_x64.dll" : "aspnetcore_x86.dll";
                                // Bin deployed by Microsoft.AspNetCore.AspNetCoreModule.nupkg
                                if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr &&
                                    DeploymentParameters.ApplicationType == ApplicationType.Portable)
                                {
                                    ancmPath = Path.Combine(contentRoot, @"runtimes\win7\native\", ancmFile);
                                }
                                else
                                {
                                    ancmPath = Path.Combine(contentRoot, ancmFile);
                                }
                            }

                            if (!File.Exists(Environment.ExpandEnvironmentVariables(ancmPath)))
                            {
                                throw new FileNotFoundException("AspNetCoreModule could not be found.", ancmPath);
                            }

                            Logger.LogDebug("Writing ANCMPath '{ancmPath}' to config", ancmPath);
                            serverConfig =
                                serverConfig.Replace("[ANCMPath]", ancmPath);
                        }

                        Logger.LogDebug("Writing ApplicationPhysicalPath '{applicationPhysicalPath}' to config", contentRoot);
                        Logger.LogDebug("Writing Port '{port}' to config", port);
                        serverConfig =
                            serverConfig
                            .Replace("[ApplicationPhysicalPath]", contentRoot)
                            .Replace("[PORT]", port.ToString());

                        DeploymentParameters.ServerConfigLocation = Path.GetTempFileName();

                        Logger.LogDebug("Saving Config to {configPath}", DeploymentParameters.ServerConfigLocation);

                        if (Logger.IsEnabled(LogLevel.Trace))
                        {
                            Logger.LogTrace($"Config File Content:{Environment.NewLine}===START CONFIG==={Environment.NewLine}{{configContent}}{Environment.NewLine}===END CONFIG===", serverConfig);
                        }

                        File.WriteAllText(DeploymentParameters.ServerConfigLocation, serverConfig);
                    }

                    var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ServerConfigLocation) ?
                                     string.Format("/port:{0} /path:\"{1}\" /trace:error", uri.Port, contentRoot) :
                                     string.Format("/site:{0} /config:{1} /trace:error", DeploymentParameters.SiteName, DeploymentParameters.ServerConfigLocation);

                    var iisExpressPath = GetIISExpressPath();

                    Logger.LogInformation("Executing command : {iisExpress} {parameters}", iisExpressPath, parameters);

                    var startInfo = new ProcessStartInfo
                    {
                        FileName               = iisExpressPath,
                        Arguments              = parameters,
                        UseShellExecute        = false,
                        CreateNoWindow         = true,
                        RedirectStandardError  = true,
                        RedirectStandardOutput = true
                    };

                    AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables);

                    Uri url     = null;
                    var started = new TaskCompletionSource <bool>();

                    var process = new Process()
                    {
                        StartInfo = startInfo
                    };
                    process.OutputDataReceived += (sender, dataArgs) =>
                    {
                        if (string.Equals(dataArgs.Data, UnableToStartIISExpressMessage))
                        {
                            // We completely failed to start and we don't really know why
                            started.TrySetException(new InvalidOperationException("Failed to start IIS Express"));
                        }
                        else if (string.Equals(dataArgs.Data, FailedToInitializeBindingsMessage))
                        {
                            started.TrySetResult(false);
                        }
                        else if (string.Equals(dataArgs.Data, IISExpressRunningMessage))
                        {
                            started.TrySetResult(true);
                        }
                        else if (!string.IsNullOrEmpty(dataArgs.Data))
                        {
                            var m = UrlDetectorRegex.Match(dataArgs.Data);
                            if (m.Success)
                            {
                                url = new Uri(m.Groups["url"].Value);
                            }
                        }
                    };
                    process.EnableRaisingEvents = true;
                    var hostExitTokenSource = new CancellationTokenSource();
                    process.Exited += (sender, e) =>
                    {
                        Logger.LogInformation("iisexpress Process {pid} shut down", process.Id);

                        // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want
                        started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {process.ExitCode}"));

                        TriggerHostShutdown(hostExitTokenSource);
                    };
                    process.StartAndCaptureOutAndErrToLogger("iisexpress", Logger);
                    Logger.LogInformation("iisexpress Process {pid} started", process.Id);

                    if (process.HasExited)
                    {
                        Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, process.Id, process.ExitCode);
                        throw new Exception("Failed to start host");
                    }

                    // Wait for the app to start
                    // The timeout here is large, because we don't know how long the test could need
                    // We cover a lot of error cases above, but I want to make sure we eventually give up and don't hang the build
                    // just in case we missed one -anurse
                    if (!await started.Task.TimeoutAfter(TimeSpan.FromMinutes(10)))
                    {
                        Logger.LogInformation("iisexpress Process {pid} failed to bind to port {port}, trying again", _hostProcess.Id, port);

                        // Wait for the process to exit and try again
                        process.WaitForExit(30 * 1000);
                        await Task.Delay(1000); // Wait a second to make sure the socket is completely cleaned up
                    }
                    else
                    {
                        _hostProcess = process;
                        Logger.LogInformation("Started iisexpress successfully. Process Id : {processId}, Port: {port}", _hostProcess.Id, port);
                        return(url : url, hostExitToken : hostExitTokenSource.Token);
                    }
                }

                var message = $"Failed to initialize IIS Express after {MaximumAttempts} attempts to select a port";
                Logger.LogError(message);
                throw new TimeoutException(message);
            }
        }
コード例 #16
0
ファイル: NginxDeployer.cs プロジェクト: MKJ001/aspnetcore
    public override async Task <DeploymentResult> DeployAsync()
    {
        using (Logger.BeginScope("Deploy"))
        {
            _configFile = Path.GetTempFileName();

            var uri = string.IsNullOrEmpty(DeploymentParameters.ApplicationBaseUriHint) ?
                      new Uri("http://localhost:0") :
                      new Uri(DeploymentParameters.ApplicationBaseUriHint);

            if (uri.Port == 0)
            {
                var builder = new UriBuilder(uri);
                if (OperatingSystem.IsLinux())
                {
                    // This works with nginx 1.9.1 and later using the reuseport flag, available on Ubuntu 16.04.
                    // Keep it open so nobody else claims the port
                    _portSelector = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    _portSelector.Bind(new IPEndPoint(IPAddress.Loopback, 0));
                    builder.Port = ((IPEndPoint)_portSelector.LocalEndPoint).Port;
                }
                else
                {
                    builder.Port = TestPortHelper.GetNextPort();
                }
                uri = builder.Uri;
            }

            var redirectUri = TestUriHelper.BuildTestUri(ServerType.Nginx);

            if (DeploymentParameters.RuntimeFlavor == RuntimeFlavor.CoreClr &&
                DeploymentParameters.ApplicationType == ApplicationType.Standalone)
            {
                // Publish is required to get the correct files in the output directory
                DeploymentParameters.PublishApplicationBeforeDeployment = true;
            }

            if (DeploymentParameters.PublishApplicationBeforeDeployment)
            {
                DotnetPublish();
            }

            var(appUri, exitToken) = await StartSelfHostAsync(redirectUri);

            SetupNginx(appUri.ToString(), uri);

            Logger.LogInformation("Application ready at URL: {appUrl}", uri);

            // Wait for App to be loaded since Nginx returns 502 instead of 503 when App isn't loaded
            // Target actual address to avoid going through Nginx proxy
            using (var httpClient = new HttpClient())
            {
                var response = await RetryHelper.RetryRequest(() =>
                {
                    return(httpClient.GetAsync(redirectUri));
                }, Logger, exitToken);

                if (!response.IsSuccessStatusCode)
                {
                    throw new InvalidOperationException("Deploy failed");
                }
            }

            return(new DeploymentResult(
                       LoggerFactory,
                       DeploymentParameters,
                       applicationBaseUri: uri.ToString(),
                       contentRoot: DeploymentParameters.ApplicationPath,
                       hostShutdownToken: exitToken));
        }
    }
コード例 #17
0
ファイル: TestUrlHelper.cs プロジェクト: wserr/AspNetCore
 public static string GetTestUrl(ServerType serverType)
 {
     return(TestUriHelper.BuildTestUri(serverType).ToString());
 }