Example #1
0
        public static async Task ReadProjectDetailsAsync(OutputContext output, FileInfo projectFile, Project project)
        {
            if (output is null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (projectFile is null)
            {
                throw new ArgumentNullException(nameof(projectFile));
            }

            if (project is null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            using (var step = output.BeginStep("Reading Project Details..."))
            {
                await EvaluateMSBuildAsync(output, projectFile, project);

                if (!SemVersion.TryParse(project.Version, out var version))
                {
                    output.WriteInfoLine($"No version or invalid version 'application.Version' found, using default.");
                    version         = new SemVersion(0, 1, 0);
                    project.Version = version.ToString();
                }

                step.MarkComplete();
            }
        }
Example #2
0
        private static async Task PackageApplicationAsync(OutputContext output, Application application, DirectoryInfo outputDirectory, string applicationName, string environment)
        {
            using var step = output.BeginStep("Writing Application Manifests...");
            var outputFile = Path.Combine(outputDirectory.FullName, $"{applicationName}-{environment}.yaml");

            output.WriteInfoLine($"Writing output to '{outputFile}'.");

            File.Delete(outputFile);
            using var stream = File.OpenWrite(outputFile);
            using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true);

            if (application.Globals.DeploymentKind == DeploymentKind.None)
            {
                // No extra steps
            }
            else if (application.Globals.DeploymentKind == DeploymentKind.Kubernetes)
            {
                await ApplicationYamlWriter.WriteAsync(output, writer, application);
            }
            else if (application.Globals.DeploymentKind == DeploymentKind.Oam)
            {
                await OamApplicationGenerator.WriteOamApplicationAsync(writer, output, application, applicationName, environment);
            }
            else
            {
                throw new InvalidOperationException($"Unknown DeploymentKind: " + application.Globals.DeploymentKind);
            }

            step.MarkComplete();
        }
Example #3
0
        private static async Task PackageApplicationAsync(OutputContext output, Application application, string applicationName, string environment)
        {
            using var step = output.BeginStep("Deploying Application Manifests...");

            using var tempFile = TempFile.Create();
            output.WriteInfoLine($"Writing output to '{tempFile.FilePath}'.");

            {
                using var stream = File.OpenWrite(tempFile.FilePath);
                using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true);

                if (application.Globals.DeploymentKind == DeploymentKind.None)
                {
                    // No extra steps
                }
                else if (application.Globals.DeploymentKind == DeploymentKind.Kubernetes)
                {
                    await ApplicationYamlWriter.WriteAsync(output, writer, application);
                }
                else if (application.Globals.DeploymentKind == DeploymentKind.Oam)
                {
                    await OamApplicationGenerator.WriteOamApplicationAsync(writer, output, application, applicationName, environment);
                }
                else
                {
                    throw new InvalidOperationException($"Unknown DeploymentKind: " + application.Globals.DeploymentKind);
                }
            }

            output.WriteDebugLine("Running 'kubectl apply'.");
            output.WriteCommandLine("kubectl", $"apply -f \"{tempFile.FilePath}\"");
            var capture  = output.Capture();
            var exitCode = await Process.ExecuteAsync(
                $"kubectl",
                $"apply -f \"{tempFile.FilePath}\"",
                System.Environment.CurrentDirectory,
                stdOut : capture.StdOut,
                stdErr : capture.StdErr);

            output.WriteDebugLine($"Done running 'kubectl apply' exit code: {exitCode}");
            if (exitCode != 0)
            {
                throw new CommandException("'kubectl apply' failed.");
            }

            output.WriteInfoLine($"Deployed application '{applicationName}'.");

            step.MarkComplete();
        }
Example #4
0
        public static async Task <ApplicationWrapper?> RunCustomizationScriptAsync(OutputContext output, FileInfo solutionFile, SolutionFile solution)
        {
            if (output is null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (solutionFile is null)
            {
                throw new ArgumentNullException(nameof(solutionFile));
            }

            if (solution is null)
            {
                throw new ArgumentNullException(nameof(solution));
            }

            using (var step = output.BeginStep("Applying Application Customizations..."))
            {
                var scriptFilePath = Path.Combine(solutionFile.DirectoryName, "Opulence.csx");
                output.WriteDebugLine($"Looking for customization script at '{scriptFilePath}'.");
                if (!File.Exists(scriptFilePath))
                {
                    output.WriteDebugLine($"No customization script found.");
                    step.MarkComplete("Skipping...");
                    return(null);
                }

                output.WriteInfoLine($"Configuring application using '{Path.GetFileName(scriptFilePath)}'.");

                var code   = File.ReadAllText(scriptFilePath);
                var script = CSharpScript.Create <object>(
                    code,
                    options: ScriptOptions.Default.WithImports(new [] { "System", "System.Collections.Generic", }),
                    globalsType: typeof(PipelineHolder),
                    assemblyLoader: null);
                script = script.ContinueWith <object>(@"return await Pipeline.ExecuteAsync(__Pipeline);", options: ScriptOptions.Default);

                output.WriteDebugLine($"Compiling {Path.GetFileName(scriptFilePath)}'.");
                script.Compile();
                var diagnostics = script.Compile();
                if (diagnostics.Length > 0)
                {
                    var builder = new StringBuilder();
                    output.WriteDebugLine($"Script '{scriptFilePath}' had compilation errors.");
                    builder.AppendLine($"Script '{scriptFilePath}' had compilation errors.");
                    foreach (var diagnostic in diagnostics)
                    {
                        output.WriteDebugLine(CSharpDiagnosticFormatter.Instance.Format(diagnostic));
                        builder.AppendLine(CSharpDiagnosticFormatter.Instance.Format(diagnostic));
                    }

                    throw new CommandException(builder.ToString());
                }
                output.WriteDebugLine($"Done compiling {Path.GetFileName(scriptFilePath)}'.");

                var pipeline = new CustomizationPipeline(
                    output,
                    rootDirectory: Path.GetDirectoryName(scriptFilePath) !,
                    name: Names.NormalizeToDns(Path.GetFileNameWithoutExtension(solutionFile.Name)),
                    solution,
                    projectFile: null);
                var holder = new PipelineHolder(pipeline);

                output.WriteDebugLine($"Running {Path.GetFileName(scriptFilePath)}'.");
                object obj;
                try
                {
                    var result = await script.RunAsync(holder);

                    obj = result.ReturnValue;
                }
                catch (Exception ex)
                {
                    throw new CommandException($"Failed executing {Path.GetFileName(scriptFilePath)}'.", ex);
                }

                step.MarkComplete();
                return(new ApplicationWrapper(obj, Path.GetDirectoryName(scriptFilePath) !));
            }
        }
Example #5
0
        private static async Task ExecuteAsync(OutputContext output, DirectoryInfo directory)
        {
            output.WriteBanner();

            string?solutionFilePath = null;
            string?opulenceFilePath = null;

            using (var step = output.BeginStep("Looking For Existing Config..."))
            {
                opulenceFilePath = DirectorySearch.AscendingSearch(directory.FullName, "Opulence.csx");
                if (opulenceFilePath != null)
                {
                    output.WriteInfoLine($"Found 'Opulence.csx' at '{opulenceFilePath}'");
                    step.MarkComplete();
                    return;
                }
                else
                {
                    output.WriteInfoLine("Not Found");
                    step.MarkComplete();
                }
            }

            using (var step = output.BeginStep("Looking For .sln File..."))
            {
                solutionFilePath = DirectorySearch.AscendingWildcardSearch(directory.FullName, "*.sln").FirstOrDefault()?.FullName;
                if (opulenceFilePath == null &&
                    solutionFilePath != null &&
                    output.Confirm($"Use '{Path.GetDirectoryName(solutionFilePath)}' as Root?"))
                {
                    opulenceFilePath = Path.Combine(Path.GetDirectoryName(solutionFilePath) !, "Opulence.csx");
                    step.MarkComplete();
                }
                else
                {
                    output.WriteInfoLine("Not Found.");
                    step.MarkComplete();
                }
            }

            if (opulenceFilePath == null &&
                Path.GetFullPath(directory.FullName) != Path.GetFullPath(Environment.CurrentDirectory))
            {
                // User specified a directory other than the current one
                using (var step = output.BeginStep("Trying Project Directory..."))
                {
                    if (output.Confirm("Use Project Directory as Root?"))
                    {
                        opulenceFilePath = Path.Combine(directory.FullName, "Opulence.csx");
                    }

                    step.MarkComplete();
                }
            }

            if (opulenceFilePath == null)
            {
                using (var step = output.BeginStep("Trying Current Directory..."))
                {
                    if (output.Confirm("Use Current Directory as Root?"))
                    {
                        opulenceFilePath = Path.Combine(directory.FullName, "Opulence.csx");
                    }

                    step.MarkComplete();
                }
            }

            if (opulenceFilePath == null)
            {
                throw new CommandException("Cannot Determine Root Directory.");
            }

            using (var step = output.BeginStep("Writing Opulence.csx ..."))
            {
                var hostname = output.Prompt("Enter the Container Registry (ex: 'example.azurecr.io' for Azure or 'example' for dockerhub)");

                var services = new List <(string, string)>();
                if (solutionFilePath != null && output.Confirm($"Use solution file '{solutionFilePath}' to initialize services?"))
                {
                    services.AddRange(ReadServicesFromSolution(solutionFilePath));
                    services.Sort((a, b) => a.Item1.CompareTo(b.Item1));
                }

                using var stream = File.OpenWrite(opulenceFilePath);
                using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true);

                await WriteOpulenceConfigAsync(writer, hostname, services);

                output.WriteInfoLine($"Initialized Opulence Config at '{opulenceFilePath}'.");
                step.MarkComplete();
            }
        }