Browse Source

Add application step and use it

davidfowl/ingress-changes
Ryan Nowak 7 years ago
parent
commit
0159d57205
  1. 18
      src/Microsoft.Tye.Core/ApplicationExecutor.cs
  2. 64
      src/Microsoft.Tye.Core/DeployApplicationKubernetesManifestStep.cs
  3. 31
      src/Microsoft.Tye.Core/GenerateApplicationKubernetesManifestStep.cs
  4. 26
      src/tye/GenerateHost.cs
  5. 58
      src/tye/Program.DeployCommand.cs

18
src/Microsoft.Tye.Core/ApplicationExecutor.cs

@ -19,6 +19,8 @@ namespace Microsoft.Tye
this.output = output; this.output = output;
} }
public List<ApplicationStep> ApplicationSteps = new List<ApplicationStep>();
public List<ServiceStep> ServiceSteps { get; } = new List<ServiceStep>(); public List<ServiceStep> ServiceSteps { get; } = new List<ServiceStep>();
public async Task ExecuteAsync(ApplicationBuilder application) public async Task ExecuteAsync(ApplicationBuilder application)
@ -34,6 +36,22 @@ namespace Microsoft.Tye
} }
tracker.MarkComplete(); tracker.MarkComplete();
} }
{
foreach (var step in ApplicationSteps)
{
using var stepTracker = output.BeginStep(step.DisplayText);
await step.ExecuteAsync(output, application);
stepTracker.MarkComplete();
}
}
}
public abstract class ApplicationStep
{
public abstract string DisplayText { get; }
public abstract Task ExecuteAsync(OutputContext output, ApplicationBuilder application);
} }
public abstract class ServiceStep public abstract class ServiceStep

64
src/Microsoft.Tye.Core/DeployApplicationKubernetesManifestStep.cs

@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.CommandLine.Invocation;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Tye
{
public sealed class DeployApplicationKubernetesManifestStep : ApplicationExecutor.ApplicationStep
{
public override string DisplayText => "Deploying Application Manifests...";
public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application)
{
using var step = output.BeginStep("");
if (!await KubectlDetector.Instance.IsKubectlInstalled.Value)
{
throw new CommandException($"Cannot apply manifests because kubectl is not installed.");
}
if (!await KubectlDetector.Instance.IsKubectlConnectedToCluster.Value)
{
throw new CommandException($"Cannot apply manifests for 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, Encoding.UTF8, 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}'.");
}
}
}

31
src/Microsoft.Tye.Core/GenerateApplicationKubernetesManifestStep.cs

@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Tye
{
public sealed class GenerateApplicationKubernetesManifestStep : ApplicationExecutor.ApplicationStep
{
public override string DisplayText => "Generating Application Manifests...";
public string Environment { get; set; } = "production";
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, Encoding.UTF8, leaveOpen: true);
await ApplicationYamlWriter.WriteAsync(output, writer, application);
}
}
}
}

26
src/tye/GenerateHost.cs

@ -45,28 +45,14 @@ namespace Microsoft.Tye
new BuildDockerImageStep() { Environment = environment, }, // Make an image but don't push it new BuildDockerImageStep() { Environment = environment, }, // Make an image but don't push it
new GenerateKubernetesManifestStep() { Environment = environment, }, new GenerateKubernetesManifestStep() { Environment = environment, },
}, },
};
await executor.ExecuteAsync(application);
await GenerateApplicationManifestAsync(output, application, environment);
}
private static async Task GenerateApplicationManifestAsync(OutputContext output, ApplicationBuilder application, string environment) ApplicationSteps =
{ {
using var step = output.BeginStep("Generating Application Manifests..."); new GenerateApplicationKubernetesManifestStep() { Environment = environment, },
}
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(); await executor.ExecuteAsync(application);
} }
} }
} }

58
src/tye/Program.DeployCommand.cs

@ -83,61 +83,15 @@ namespace Microsoft.Tye
new PushDockerImageStep() { Environment = environment, }, new PushDockerImageStep() { Environment = environment, },
new ValidateSecretStep() { Environment = environment, Interactive = interactive, Force = force, }, new ValidateSecretStep() { Environment = environment, Interactive = interactive, Force = force, },
new GenerateKubernetesManifestStep() { Environment = environment, }, new GenerateKubernetesManifestStep() { Environment = environment, },
},
ApplicationSteps =
{
new DeployApplicationKubernetesManifestStep(),
} }
}; };
await executor.ExecuteAsync(application);
await DeployApplicationManifestAsync(output, application, application.Source.Directory.Name);
}
private static async Task DeployApplicationManifestAsync(OutputContext output, ApplicationBuilder application, string applicationName)
{
using var step = output.BeginStep("Deploying Application Manifests...");
if (!await KubectlDetector.Instance.IsKubectlInstalled.Value) await executor.ExecuteAsync(application);
{
throw new CommandException($"Cannot apply manifests because kubectl is not installed.");
}
if (!await KubectlDetector.Instance.IsKubectlConnectedToCluster.Value)
{
throw new CommandException($"Cannot apply manifests for 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, Encoding.UTF8, leaveOpen: true);
await ApplicationYamlWriter.WriteAsync(output, writer, application);
}
string 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 '{applicationName}'.");
step.MarkComplete();
} }
internal static void ApplyRegistry(OutputContext output, ApplicationBuilder application, bool interactive, bool requireRegistry) internal static void ApplyRegistry(OutputContext output, ApplicationBuilder application, bool interactive, bool requireRegistry)

Loading…
Cancel
Save