private static async Task DeployApplicationManifestAsync(OutputContext output, ApplicationBuilder 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);

                await ApplicationYamlWriter.WriteAsync(output, writer, application);
            }

            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 override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application, ServiceBuilder service)
        {
            if (SkipWithoutDotnetProject(output, service, out var project))
            {
                return;
            }

            if (SkipWithoutContainerInfo(output, service, out var container))
            {
                return;
            }

            if (container.UseMultiphaseDockerfile != false)
            {
                return;
            }

            // NOTE: we're intentionally not cleaning up here. It's the responsibility of whomever consumes
            // the publish output to do cleanup.
            var outputDirectory = TempDirectory.Create();

            output.WriteDebugLine("Running 'dotnet publish'.");
            var dotnetPublishArguments = project.BuildProperties.TryGetValue("TargetFramework", out var framework)
                ? $"publish \"{project.ProjectFile.FullName}\" -c Release -f {framework} -o \"{outputDirectory.DirectoryPath}\" /nologo"
                : $"publish \"{project.ProjectFile.FullName}\" -c Release -o \"{outputDirectory.DirectoryPath}\" /nologo";

            output.WriteCommandLine("dotnet", dotnetPublishArguments);

            var publishResult = await ProcessUtil.RunAsync(
                $"dotnet",
                dotnetPublishArguments,
                project.ProjectFile.DirectoryName,
                throwOnError : false);

            output.WriteDebugLine($"Done running 'dotnet publish' exit code: {publishResult.ExitCode}");
            if (publishResult.ExitCode != 0)
            {
                outputDirectory.Dispose();
                output.WriteInfoLine($"'dotnet publish' failed. Error:");

                foreach (var line in publishResult.StandardOutput.Split(Environment.NewLine))
                {
                    output.WriteInfoLine(line);
                }

                foreach (var line in publishResult.StandardError.Split(Environment.NewLine))
                {
                    output.WriteInfoLine(line);
                }

                throw new CommandException("'dotnet publish' failed.");
            }

            output.WriteDebugLine($"Created Publish Output: '{outputDirectory.DirectoryPath}'");
            service.Outputs.Add(new ProjectPublishOutput(outputDirectory.DirectoryInfo));
        }
Exemple #3
0
        public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application)
        {
            using var step = output.BeginStep("");

            if (!await KubectlDetector.IsKubectlInstalledAsync(output))
            {
                throw new CommandException($"Cannot apply manifests because kubectl is not installed.");
            }

            if (!await KubectlDetector.IsKubectlConnectedToClusterAsync(output))
            {
                throw new CommandException($"Cannot apply manifests because kubectl is not connected to a cluster.");
            }

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

            {
                await using var stream = File.OpenWrite(tempFile.FilePath);
                await using var writer = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), leaveOpen: true);

                await ApplicationYamlWriter.WriteAsync(output, writer, application);
            }

            var ns = $"namespace ${application.Namespace}";

            if (string.IsNullOrEmpty(application.Namespace))
            {
                ns = "current namespace";
            }
            output.WriteDebugLine($"Running 'kubectl apply' in ${ns}");
            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 '{application.Name}'.");
        }
Exemple #4
0
        public static Command CreateUndeployCommand()
        {
            var command = new Command("undeploy", "delete deployed application")
            {
                CommonArguments.Path_Required,
                StandardOptions.Namespace,
                StandardOptions.Interactive,
                StandardOptions.Verbosity,
                StandardOptions.Tags,

                new Option(new[] { "--what-if", }, "print what would be deleted without making changes")
                {
                    Argument = new Argument <bool>(),
                },
            };

            command.Handler = CommandHandler.Create <UndeployCommandArguments>(args =>
            {
                // Workaround for https://github.com/dotnet/command-line-api/issues/723#issuecomment-593062654
                if (args.Path is null)
                {
                    throw new CommandException("No project or solution file was found.");
                }

                var output = new OutputContext(args.Console, args.Verbosity);
                output.WriteInfoLine("Loading Application Details...");

                var filter = ApplicationFactoryFilter.GetApplicationFactoryFilter(args.Tags);

                return(UndeployHost.UndeployAsync(output, args.Path, args.Namespace, args.Interactive, args.WhatIf, filter));
            });

            return(command);
        }
Exemple #5
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();
            }
        }
Exemple #6
0
        public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application, ServiceBuilder service)
        {
            if (SkipWithoutProject(output, service, out var project))
            {
                return;
            }

            if (SkipWithoutContainerInfo(output, service, out var container))
            {
                return;
            }

            if (container.UseMultiphaseDockerfile == false)
            {
                throw new CommandException("Generated Dockerfile workflow does not support single-phase Dockerfiles.");
            }

            container.UseMultiphaseDockerfile ??= true;

            var dockerFilePath = Path.Combine(project.ProjectFile.DirectoryName, "Dockerfile");

            if (File.Exists(dockerFilePath) && !Force)
            {
                throw new CommandException("'Dockerfile' already exists for project. use '--force' to overwrite.");
            }

            File.Delete(dockerFilePath);

            await DockerfileGenerator.WriteDockerfileAsync(output, application, project, container, dockerFilePath);

            output.WriteInfoLine($"Generated Dockerfile at '{dockerFilePath}'.");
        }
        public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application, ServiceBuilder service)
        {
            if (SkipWithoutProject(output, service, out var project))
            {
                return;
            }

            if (SkipWithoutContainerInfo(output, service, out var container))
            {
                return;
            }

            var chartDirectory = Path.Combine(project.ProjectFile.DirectoryName, "charts");

            if (Directory.Exists(chartDirectory) && !Force)
            {
                throw new CommandException("'charts' directory already exists for project. use '--force' to overwrite.");
            }
            else if (Directory.Exists(chartDirectory))
            {
                Directory.Delete(chartDirectory, recursive: true);
            }

            var chart = new HelmChartStep();
            await HelmChartGenerator.GenerateAsync(
                output,
                application,
                project,
                container,
                chart,
                new DirectoryInfo(chartDirectory));

            output.WriteInfoLine($"Generated Helm Chart at '{Path.Combine(chartDirectory, chart.ChartName)}'.");
        }
Exemple #8
0
        public static Command CreateGenerateCommand()
        {
            var command = new Command("generate", "generate kubernetes manifests")
            {
                CommonArguments.Path_Required,
                StandardOptions.Interactive,
                StandardOptions.Verbosity,
                StandardOptions.Namespace,
                StandardOptions.Tags,
                StandardOptions.Framework,
            };

            // This is a super-secret VIP-only command! It's useful for testing, but we're
            // not documenting it right now.
            command.IsHidden = true;

            command.Handler = CommandHandler.Create <GenerateCommandArguments>(args =>
            {
                // Workaround for https://github.com/dotnet/command-line-api/issues/723#issuecomment-593062654
                if (args.Path is null)
                {
                    throw new CommandException("No project or solution file was found.");
                }

                var output = new OutputContext(args.Console, args.Verbosity);
                output.WriteInfoLine("Loading Application Details...");

                var filter = ApplicationFactoryFilter.GetApplicationFactoryFilter(args.Tags);

                return(GenerateHost.GenerateAsync(output, args.Path, args.Interactive, args.Namespace, args.Framework, filter));
            });

            return(command);
        }
        public static Command CreateBuildCommand()
        {
            var command = new Command("build", "build containers for the application")
            {
                CommonArguments.Path_Required,
                StandardOptions.Interactive,
                StandardOptions.Tags,
                StandardOptions.Verbosity,
                StandardOptions.Framework,
            };

            command.Handler = CommandHandler.Create <BuildCommandArguments>(args =>
            {
                // Workaround for https://github.com/dotnet/command-line-api/issues/723#issuecomment-593062654
                if (args.Path is null)
                {
                    throw new CommandException("No project or solution file was found.");
                }

                var output = new OutputContext(args.Console, args.Verbosity);
                output.WriteInfoLine("Loading Application Details...");

                var filter = ApplicationFactoryFilter.GetApplicationFactoryFilter(args.Tags);

                return(BuildHost.BuildAsync(output, args.Path, args.Interactive, args.Framework, filter));
            });

            return(command);
        }
Exemple #10
0
        public static Task ReadProjectDetailsAsync(OutputContext output, ProjectServiceBuilder project)
        {
            if (output is null)
            {
                throw new ArgumentNullException(nameof(output));
            }

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

            EnsureMSBuildRegistered(output, project.ProjectFile);

            EvaluateProject(output, project);

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

            return(Task.CompletedTask);
        }
Exemple #11
0
        public static void ReadProjectDetails(OutputContext output, DotnetProjectServiceBuilder project, string metadataFile)
        {
            if (output is null)
            {
                throw new ArgumentNullException(nameof(output));
            }

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

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

            EvaluateProject(output, project, metadataFile);

            if (!SemVersion.TryParse(project.Version, out var version))
            {
                output.WriteInfoLine($"No version or invalid version '{project.Version}' found, using default.");
                version         = new SemVersion(0, 1, 0);
                project.Version = version.ToString();
            }
        }
Exemple #12
0
        public override Task ExecuteAsync(OutputContext output, Application application, ServiceEntry service)
        {
            var yaml = service.Outputs.OfType <IYamlManifestOutput>().ToArray();

            if (yaml.Length == 0)
            {
                output.WriteDebugLine($"No yaml manifests found for service '{service.FriendlyName}'. Skipping.");
                return(Task.CompletedTask);
            }

            var outputFilePath = Path.Combine(OutputDirectory.FullName, $"{service.Service.Name}.yaml");

            output.WriteInfoLine($"Writing output to '{outputFilePath}'.");
            if (File.Exists(outputFilePath) && !Force)
            {
                throw new CommandException($"'{service.Service.Name}.yaml' already exists for project. use '--force' to overwrite.");
            }

            File.Delete(outputFilePath);

            using var stream = File.OpenWrite(outputFilePath);
            using var writer = new StreamWriter(stream, Encoding.UTF8, bufferSize: -1, leaveOpen: true);
            var yamlStream = new YamlStream(yaml.Select(y => y.Yaml));

            yamlStream.Save(writer, assignAnchors: false);

            return(Task.CompletedTask);
        }
Exemple #13
0
 public static Task <bool> IsKubectlConnectedToClusterAsync(OutputContext output)
 {
     if (!_kubectlConnectedToCluster.IsValueCreated)
     {
         output.WriteInfoLine("Verifying kubectl connection to cluster...");
     }
     return(_kubectlConnectedToCluster.Value);
 }
Exemple #14
0
 public static Task <Version?> GetKubernetesServerVersion(OutputContext output)
 {
     if (!_kubectlInstalled.IsValueCreated)
     {
         output.WriteInfoLine("Verifying kubectl installation...");
     }
     return(_kubectlInstalled.Value);
 }
Exemple #15
0
 public static Task <bool> IsKubectlInstalledAsync(OutputContext output)
 {
     if (!_kubectlInstalled.IsValueCreated)
     {
         output.WriteInfoLine("Verifying kubectl installation...");
     }
     return(_kubectlInstalled.Value);
 }
Exemple #16
0
        public static async Task UndeployAsync(IConsole console, FileInfo path, Verbosity verbosity, bool interactive, bool whatIf)
        {
            var output = new OutputContext(console, verbosity);

            output.WriteInfoLine("Loading Application Details...");

            // We don't need to know anything about the services, just the application name.
            var application = ConfigFactory.FromFile(path);

            await ExecuteUndeployAsync(output, application, interactive, whatIf);
        }
Exemple #17
0
        public override async Task ExecuteAsync(OutputContext output, Application application, ServiceEntry service)
        {
            var yaml = service.Outputs.OfType <IYamlManifestOutput>().ToArray();

            if (yaml.Length == 0)
            {
                output.WriteDebugLine($"No yaml manifests found for service '{service.FriendlyName}'. Skipping.");
                return;
            }

            if (!await KubectlDetector.Instance.IsKubectlInstalled.Value)
            {
                throw new CommandException($"Cannot apply manifests for '{service.Service.Name}' because kubectl is not installed.");
            }

            if (!await KubectlDetector.Instance.IsKubectlConnectedToCluster.Value)
            {
                throw new CommandException($"Cannot apply manifests for '{service.Service.Name}' because kubectl is not connected to a cluster.");
            }

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

            {
                using var stream = File.OpenWrite(tempFile.FilePath);
                using var writer = new StreamWriter(stream, Encoding.UTF8, bufferSize: -1, leaveOpen: true);
                var yamlStream = new YamlStream(yaml.Select(y => y.Yaml));
                yamlStream.Save(writer, assignAnchors: false);
            }

            // kubectl apply logic is implemented in the client in older versions of k8s. The capability
            // to get the same behavior in the server isn't present in every version that's relevant.
            //
            // https://kubernetes.io/docs/reference/using-api/api-concepts/#server-side-apply
            //
            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 service '{service.FriendlyName}'.");
        }
        private static Command CreateInitCommand()
        {
            var command = new Command("init", "create a yaml manifest")
            {
                CommonArguments.Path_Optional,
                StandardOptions.CreateForce("Overrides the tye.yaml file if already present for project.")
            };

            command.Handler = CommandHandler.Create <InitCommandArguments>(args =>
            {
                var watch = System.Diagnostics.Stopwatch.StartNew();

                var output         = new OutputContext(args.Console, args.Verbosity);
                var outputFilePath = InitHost.CreateTyeFile(args.Path, args.Force);
                output.WriteInfoLine($"Created '{outputFilePath}'.");

                watch.Stop();
                var elapsedTime = watch.Elapsed;
                output.WriteInfoLine($"Time Elapsed: {elapsedTime.Hours:00}:{elapsedTime.Minutes:00}:{elapsedTime.Seconds:00}:{elapsedTime.Milliseconds / 10:00}");
            });

            return(command);
        }
        public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application)
        {
            var outputFilePath = Path.GetFullPath(Path.Combine(application.Source.DirectoryName, $"{application.Name}-generate-{Environment}.yaml"));

            output.WriteInfoLine($"Writing output to '{outputFilePath}'.");
            {
                File.Delete(outputFilePath);

                await using var stream = File.OpenWrite(outputFilePath);
                await using var writer = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), leaveOpen: true);

                await ApplicationYamlWriter.WriteAsync(output, writer, application);
            }
        }
Exemple #20
0
        public static async Task GenerateAsync(IConsole console, FileInfo path, Verbosity verbosity, bool interactive)
        {
            var output = new OutputContext(console, verbosity);

            output.WriteInfoLine("Loading Application Details...");
            var application = await ApplicationFactory.CreateAsync(output, path);

            if (application.Services.Count == 0)
            {
                throw new CommandException($"No services found in \"{application.Source.Name}\"");
            }

            await ExecuteGenerateAsync(output, application, environment : "production", interactive);
        }
Exemple #21
0
        public static async Task BuildContainerImageFromDockerFileAsync(OutputContext output, ApplicationBuilder application, DockerFileServiceBuilder containerService, ContainerInfo container)
        {
            if (output is null)
            {
                throw new ArgumentNullException(nameof(output));
            }

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

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

            if (containerService.DockerFile is null)
            {
                throw new ArgumentNullException(nameof(containerService.DockerFile));
            }

            var dockerFileInfo   = new FileInfo(containerService.DockerFile);
            var contextDirectory = containerService.DockerFileContext ?? dockerFileInfo.DirectoryName;
            var dockerFilePath   = Path.Combine(dockerFileInfo.DirectoryName, "Dockerfile");

            output.WriteDebugLine($"Using existing Dockerfile '{dockerFilePath}'.");

            output.WriteDebugLine("Running 'docker build'.");
            output.WriteCommandLine("docker", $"build \"{contextDirectory}\" -t {container.ImageName}:{container.ImageTag} -f \"{dockerFilePath}\"");
            var capture  = output.Capture();
            var exitCode = await Process.ExecuteAsync(
                $"docker",
                $"build \"{contextDirectory}\" -t {container.ImageName}:{container.ImageTag} -f \"{dockerFilePath}\"",
                new FileInfo(containerService.DockerFile).DirectoryName,
                stdOut : capture.StdOut,
                stdErr : capture.StdErr);

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

            output.WriteInfoLine($"Created Docker Image: '{container.ImageName}:{container.ImageTag}'");
            containerService.Outputs.Add(new DockerImageOutput(container.ImageName !, container.ImageTag !));
        }
Exemple #22
0
        public static Command CreateDeployCommand()
        {
            var command = new Command("deploy", "deploy the application")
            {
                CommonArguments.Path_Required,
                StandardOptions.Interactive,
                StandardOptions.Verbosity,
                StandardOptions.Namespace,
                StandardOptions.Tags,
            };

            command.AddOption(new Option(new[] { "-f", "--force" })
            {
                Description = "Override validation and force deployment.",
                Required    = false
            });

            command.Handler = CommandHandler.Create <IConsole, FileInfo, Verbosity, bool, bool, string, string[]>(async(console, path, verbosity, interactive, force, @namespace, tags) =>
            {
                // Workaround for https://github.com/dotnet/command-line-api/issues/723#issuecomment-593062654
                if (path is null)
                {
                    throw new CommandException("No project or solution file was found.");
                }

                var output = new OutputContext(console, verbosity);

                output.WriteInfoLine("Loading Application Details...");

                var filter = ApplicationFactoryFilter.GetApplicationFactoryFilter(tags);

                var application = await ApplicationFactory.CreateAsync(output, path, filter);
                if (application.Services.Count == 0)
                {
                    throw new CommandException($"No services found in \"{application.Source.Name}\"");
                }
                if (!string.IsNullOrEmpty(@namespace))
                {
                    application.Namespace = @namespace;
                }
                await ExecuteDeployAsync(new OutputContext(console, verbosity), application, environment: "production", interactive, force);
            });

            return(command);
        }
Exemple #23
0
        private static async Task GenerateApplicationManifestAsync(OutputContext output, ApplicationBuilder application, string environment)
        {
            using var step = output.BeginStep("Generating Application Manifests...");

            var outputFilePath = Path.GetFullPath(Path.Combine(application.Source.DirectoryName, $"{application.Name}-generate-{environment}.yaml"));

            output.WriteInfoLine($"Writing output to '{outputFilePath}'.");
            {
                File.Delete(outputFilePath);

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

                await ApplicationYamlWriter.WriteAsync(output, writer, application);
            }

            step.MarkComplete();
        }
Exemple #24
0
        public static async Task GenerateAsync(IConsole console, FileInfo path, Verbosity verbosity, bool interactive, string ns, string[] tags)
        {
            var output = new OutputContext(console, verbosity);

            output.WriteInfoLine("Loading Application Details...");
            var filter      = ApplicationFactoryFilter.GetApplicationFactoryFilter(tags);
            var application = await ApplicationFactory.CreateAsync(output, path, filter);

            if (application.Services.Count == 0)
            {
                throw new CommandException($"No services found in \"{application.Source.Name}\"");
            }
            if (!String.IsNullOrEmpty(ns))
            {
                application.Namespace = ns;
            }
            await ExecuteGenerateAsync(output, application, environment : "production", interactive);
        }
Exemple #25
0
        public static Command CreateDeployCommand()
        {
            var command = new Command("deploy", "deploy the application")
            {
                CommonArguments.Path_Required,
                StandardOptions.Interactive,
                StandardOptions.Verbosity,
                StandardOptions.Namespace,
                StandardOptions.Framework,
                StandardOptions.Tags,
                StandardOptions.CreateForce("Override validation and force deployment.")
            };

            command.Handler = CommandHandler.Create <DeployCommandArguments>(async args =>
            {
                // Workaround for https://github.com/dotnet/command-line-api/issues/723#issuecomment-593062654
                if (args.Path is null)
                {
                    throw new CommandException("No project or solution file was found.");
                }

                var output = new OutputContext(args.Console, args.Verbosity);
                output.WriteInfoLine("Loading Application Details...");

                var filter = ApplicationFactoryFilter.GetApplicationFactoryFilter(args.Tags);

                var application = await ApplicationFactory.CreateAsync(output, args.Path, args.Framework, filter);
                if (application.Services.Count == 0)
                {
                    throw new CommandException($"No services found in \"{application.Source.Name}\"");
                }

                if (!string.IsNullOrEmpty(args.Namespace))
                {
                    application.Namespace = args.Namespace;
                }

                var executeOutput = new OutputContext(args.Console, args.Verbosity);
                await ExecuteDeployAsync(executeOutput, application, environment: "production", args.Interactive, args.Force);
            });

            return(command);
        }
Exemple #26
0
        public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application, ServiceBuilder service)
        {
            if (SkipWithoutProject(output, service, out var _))
            {
                return;
            }

            if (SkipWithoutContainerInfo(output, service, out var _))
            {
                return;
            }

            foreach (var image in service.Outputs.OfType <DockerImageOutput>())
            {
                await DockerPush.ExecuteAsync(output, image.ImageName, image.ImageTag);

                output.WriteInfoLine($"Pushed docker image: '{image.ImageName}:{image.ImageTag}'");
            }
        }
Exemple #27
0
            protected bool SkipWithoutProject(OutputContext output, ServiceBuilder service, [MaybeNullWhen(returnValue: true)] out ProjectServiceBuilder project)
            {
                if (output is null)
                {
                    throw new ArgumentNullException(nameof(output));
                }

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

                if (service is ProjectServiceBuilder p)
                {
                    project = p;
                    return(false);
                }

                output.WriteInfoLine($"Service '{service.Name}' does not have a project associated. Skipping.");
                project = default !;
Exemple #28
0
        public override async Task ExecuteAsync(OutputContext output, Application application, ServiceEntry service)
        {
            if (SkipWithoutProject(output, service, out var project))
            {
                return;
            }

            if (SkipWithoutContainerInfo(output, service, out var container))
            {
                return;
            }

            if (container.UseMultiphaseDockerfile != false)
            {
                return;
            }

            var projectFilePath = Path.Combine(application.RootDirectory, project.RelativeFilePath);
            var outputDirectory = Path.Combine(Path.GetDirectoryName(projectFilePath) !, "bin", "Release", project.TargetFramework, "publish");

            output.WriteDebugLine("Running 'dotnet publish'.");
            output.WriteCommandLine("dotnet", $"publish \"{projectFilePath}\" -c Release -o \"{outputDirectory}\"");
            var capture  = output.Capture();
            var exitCode = await Process.ExecuteAsync(
                $"dotnet",
                $"publish \"{projectFilePath}\" -c Release -o \"{outputDirectory}\"",
                application.GetProjectDirectory(project),
                stdOut : capture.StdOut,
                stdErr : capture.StdErr);

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

            output.WriteInfoLine($"Created Publish Output: '{outputDirectory}'");
            service.Outputs.Add(new ProjectPublishOutput(new DirectoryInfo(outputDirectory)));
        }
Exemple #29
0
        public static Command CreatePushCommand()
        {
            var command = new Command("push", "build and push application containers to registry")
            {
                CommonArguments.Path_Required,
                StandardOptions.Interactive,
                StandardOptions.Verbosity,
            };

            command.AddOption(new Option(new[] { "-f", "--force" })
            {
                Description = "Override validation and force push.",
                Required    = false
            });

            command.Handler = CommandHandler.Create <IConsole, FileInfo, Verbosity, bool, bool>(async(console, path, verbosity, interactive, force) =>
            {
                // Workaround for https://github.com/dotnet/command-line-api/issues/723#issuecomment-593062654
                if (path is null)
                {
                    throw new CommandException("No project or solution file was found.");
                }

                var output = new OutputContext(console, verbosity);

                output.WriteInfoLine("Loading Application Details...");
                var application = await ApplicationFactory.CreateAsync(output, path);
                if (application.Services.Count == 0)
                {
                    throw new CommandException($"No services found in \"{application.Source.Name}\"");
                }

                await ExecutePushAsync(new OutputContext(console, verbosity), application, environment: "production", interactive, force);
            });

            return(command);
        }