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(); } }
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(); }
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(); }
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) !)); } }
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(); } }