예제 #1
0
        protected async Task RunTestAsync(
            string language,
            string languageVersion,
            string samplePath,
            int containerPort        = 8000,
            bool specifyBindPortFlag = true,
            string buildImageName    = Settings.BuildImageName)
        {
            var volume           = DockerVolume.CreateMirror(samplePath);
            var appDir           = volume.ContainerDir;
            var entrypointScript = "./run.sh";
            var bindPortFlag     = specifyBindPortFlag ? $"-bindPort {containerPort}" : string.Empty;
            var scriptBuilder    = new ShellScriptBuilder()
                                   .AddCommand($"cd {appDir}");

            if (string.Equals("python", language, StringComparison.OrdinalIgnoreCase) ||
                string.Equals("nodejs", language, StringComparison.OrdinalIgnoreCase))
            {
                scriptBuilder = scriptBuilder.AddCommand($"oryx create-script -appPath {appDir} {bindPortFlag}");
            }
            else
            {
                scriptBuilder = scriptBuilder.AddCommand($"oryx -appPath {appDir} {bindPortFlag}");
            }

            var script = scriptBuilder.AddCommand(entrypointScript)
                         .ToString();

            var runtimeImageName = _imageHelper.GetTestRuntimeImage(language, languageVersion);

            if (string.Equals(language, "nodejs", StringComparison.OrdinalIgnoreCase))
            {
                runtimeImageName = _imageHelper.GetTestRuntimeImage("node", languageVersion);
            }

            string link = $"{_dbFixture.DbServerContainerName}:{Constants.InternalDbLinkName}";

            await EndToEndTestHelper.BuildRunAndAssertAppAsync(
                _output,
                new List <DockerVolume> {
                volume
            },
                buildImageName,
                "oryx", new[] { "build", appDir, "-l", language, "--language-version", languageVersion },
                runtimeImageName,
                _dbFixture.GetCredentialsAsEnvVars(),
                containerPort,
                link,
                "/bin/sh", new[] { "-c", script },
                async (hostPort) =>
            {
                var data = await _httpClient.GetStringAsync($"http://localhost:{hostPort}/");
                Assert.Equal(
                    DbContainerFixtureBase.GetSampleDataAsJson(),
                    data.Trim(),
                    ignoreLineEndingDifferences: true,
                    ignoreWhiteSpaceDifferences: true);
            });
        }
        public void GeneratesScript_AndBuilds_DjangoApp_RunningCollectStatic(string disableCollectStatic)
        {
            // Arrange
            var appName       = "django-app";
            var volume        = CreateSampleAppVolume(appName);
            var appDir        = volume.ContainerDir;
            var appOutputDir  = "/tmp/app-output";
            var scriptBuilder = new ShellScriptBuilder();

            if (string.IsNullOrEmpty(disableCollectStatic))
            {
                scriptBuilder.AddCommand(
                    $"export {EnvironmentSettingsKeys.DisableCollectStatic}={disableCollectStatic}");
            }
            var script = scriptBuilder
                         .AddBuildCommand(
                $"{appDir} -o {appOutputDir} --platform {PythonConstants.PlatformName}")
                         // These css files should be available since 'collectstatic' is run in the script
                         .AddFileExistsCheck($"{appOutputDir}/staticfiles/css/boards.css")
                         .AddFileExistsCheck($"{appOutputDir}/staticfiles/css/uservoice.css")
                         .ToString();

            // Act
            var result = _dockerCli.Run(new DockerRunArguments
            {
                ImageId = Settings.BuildImageName,
                EnvironmentVariables = new List <EnvironmentVariable> {
                    CreateAppNameEnvVar(appName)
                },
                Volumes = new List <DockerVolume> {
                    volume
                },
                CommandToExecuteOnRun = "/bin/bash",
                CommandArguments      = new[] { "-c", script }
            });

            // Assert
            RunAsserts(
                () =>
            {
                Assert.True(result.IsSuccess);
            },
                result.GetDebugInfo());
        }
예제 #3
0
        public void GeneratesScript_AndBuilds_DjangoApp_RunningCollectStatic(string disableCollectStatic)
        {
            // Arrange
            var volume        = CreateSampleAppVolume("django-app");
            var appDir        = volume.ContainerDir;
            var appOutputDir  = "/tmp/app-output";
            var scriptBuilder = new ShellScriptBuilder();

            if (string.IsNullOrEmpty(disableCollectStatic))
            {
                scriptBuilder.AddCommand(
                    $"export {EnvironmentSettingsKeys.DisableCollectStatic}={disableCollectStatic}");
            }
            var script = scriptBuilder
                         .AddBuildCommand($"{appDir} -o {appOutputDir} -l python --language-version {PythonVersions.Python37Version}")
                         .AddDirectoryExistsCheck($"{appOutputDir}/{PackagesDirectory}/django")
                         // These css files should be available since 'collectstatic' is run in the script
                         .AddFileExistsCheck($"{appOutputDir}/staticfiles/css/boards.css")
                         .AddFileExistsCheck($"{appOutputDir}/staticfiles/css/uservoice.css")
                         .ToString();

            // Act
            var result = _dockerCli.Run(
                Settings.BuildImageName,
                CreateAppNameEnvVar("django-app"),
                volume,
                commandToExecuteOnRun: "/bin/bash",
                commandArguments:
                new[]
            {
                "-c",
                script
            });

            // Assert
            RunAsserts(
                () =>
            {
                Assert.True(result.IsSuccess);
            },
                result.GetDebugInfo());
        }
예제 #4
0
        internal override int Execute(IServiceProvider serviceProvider, IConsole console)
        {
            var logger = serviceProvider.GetRequiredService <ILogger <ExecCommand> >();
            var env    = serviceProvider.GetRequiredService <IEnvironment>();
            var opts   = serviceProvider.GetRequiredService <IOptions <BuildScriptGeneratorOptions> >().Value;

            var beginningOutputLog = GetBeginningCommandOutputLog();

            console.WriteLine(beginningOutputLog);

            if (string.IsNullOrWhiteSpace(Command))
            {
                logger.LogDebug("Command is empty; exiting");
                return(ProcessConstants.ExitSuccess);
            }

            var shellPath         = env.GetEnvironmentVariable("BASH") ?? FilePaths.Bash;
            var context           = BuildScriptGenerator.CreateContext(serviceProvider, operationId: null);
            var detector          = serviceProvider.GetRequiredService <DefaultPlatformDetector>();
            var detectedPlatforms = detector.DetectPlatforms(context);

            if (!detectedPlatforms.Any())
            {
                return(ProcessConstants.ExitFailure);
            }

            int exitCode;

            using (var timedEvent = logger.LogTimedEvent("ExecCommand"))
            {
                // Build envelope script
                var scriptBuilder = new ShellScriptBuilder("\n")
                                    .AddShebang(shellPath)
                                    .AddCommand("set -e");

                var envSetupProvider   = serviceProvider.GetRequiredService <PlatformsInstallationScriptProvider>();
                var installationScript = envSetupProvider.GetBashScriptSnippet(
                    context,
                    detectedPlatforms);
                if (!string.IsNullOrEmpty(installationScript))
                {
                    scriptBuilder.AddCommand(installationScript);
                }

                scriptBuilder.Source(
                    $"{FilePaths.Benv} " +
                    $"{string.Join(" ", detectedPlatforms.Select(p => $"{p.Platform}={p.PlatformVersion}"))}");

                scriptBuilder
                .AddCommand("echo Executing supplied command...")
                .AddCommand(Command);

                // Create temporary file to store script
                // Get the path where the generated script should be written into.
                var tempDirectoryProvider = serviceProvider.GetRequiredService <ITempDirectoryProvider>();
                var tempScriptPath        = Path.Combine(tempDirectoryProvider.GetTempDirectory(), "execCommand.sh");
                var script = scriptBuilder.ToString();
                File.WriteAllText(tempScriptPath, script);
                console.WriteLine("Finished generating script.");

                timedEvent.AddProperty(nameof(tempScriptPath), tempScriptPath);

                if (DebugMode)
                {
                    console.WriteLine($"Temporary script @ {tempScriptPath}:");
                    console.WriteLine("---");
                    console.WriteLine(script);
                    console.WriteLine("---");
                }

                console.WriteLine();
                console.WriteLine("Executing generated script...");
                console.WriteLine();

                exitCode = ProcessHelper.RunProcess(
                    shellPath,
                    new[] { tempScriptPath },
                    opts.SourceDir,
                    (sender, args) =>
                {
                    if (args.Data != null)
                    {
                        console.WriteLine(args.Data);
                    }
                },
                    (sender, args) =>
                {
                    if (args.Data != null)
                    {
                        console.Error.WriteLine(args.Data);
                    }
                },
                    waitTimeForExit: null);
                timedEvent.AddProperty("exitCode", exitCode.ToString());
            }

            return(exitCode);
        }
예제 #5
0
파일: ExecCommand.cs 프로젝트: yazici/Oryx
        internal override int Execute(IServiceProvider serviceProvider, IConsole console)
        {
            var logger    = serviceProvider.GetRequiredService <ILogger <ExecCommand> >();
            var env       = serviceProvider.GetRequiredService <IEnvironment>();
            var generator = serviceProvider.GetRequiredService <IBuildScriptGenerator>();
            var opts      = serviceProvider.GetRequiredService <IOptions <BuildScriptGeneratorOptions> >().Value;

            if (string.IsNullOrWhiteSpace(Command))
            {
                logger.LogDebug("Command is empty; exiting");
                return(ProcessConstants.ExitSuccess);
            }

            var shellPath = env.GetEnvironmentVariable("BASH") ?? FilePaths.Bash;
            var ctx       = BuildScriptGenerator.CreateContext(serviceProvider, operationId: null);

            ctx.DisableMultiPlatformBuild = false;
            var tools = generator.GetRequiredToolVersions(ctx);

            int exitCode;

            using (var timedEvent = logger.LogTimedEvent("ExecCommand"))
            {
                // Build envelope script
                var scriptBuilder = new ShellScriptBuilder("\n")
                                    .AddShebang(shellPath)
                                    .AddCommand("set -e");

                if (tools.Count > 0)
                {
                    scriptBuilder.Source($"{FilePaths.Benv} {StringExtensions.JoinKeyValuePairs(tools)}");
                }

                var script = scriptBuilder.AddCommand(Command).ToString();

                // Create temporary file to store script
                var tempScriptPath = Path.GetTempFileName();
                File.WriteAllText(tempScriptPath, script);
                timedEvent.AddProperty(nameof(tempScriptPath), tempScriptPath);

                if (DebugMode)
                {
                    console.WriteLine($"Temporary script @ {tempScriptPath}:");
                    console.WriteLine("---");
                    console.WriteLine(script);
                    console.WriteLine("---");
                }

                exitCode = ProcessHelper.RunProcess(
                    shellPath,
                    new[] { tempScriptPath },
                    opts.SourceDir,
                    (sender, args) => { if (args.Data != null)
                                        {
                                            console.WriteLine(args.Data);
                                        }
                    },
                    (sender, args) => { if (args.Data != null)
                                        {
                                            console.Error.WriteLine(args.Data);
                                        }
                    },
                    waitTimeForExit: null);
                timedEvent.AddProperty("exitCode", exitCode.ToString());
            }

            return(exitCode);
        }