Browse Source
It turns out we were deploying twice! We were deploying each service independently, and then deploying everything in a batch afterwards (noop). I chose to get rid of the per-service version because: - it's less chatty this way - it's more similar to generate where we produce one file - we're about to add non-per-service things (ingress)davidfowl/ingress-changes
2 changed files with 10 additions and 74 deletions
@ -1,73 +0,0 @@ |
|||||
// 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.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using YamlDotNet.RepresentationModel; |
|
||||
|
|
||||
namespace Microsoft.Tye |
|
||||
{ |
|
||||
public sealed class DeployServiceYamlStep : ApplicationExecutor.ServiceStep |
|
||||
{ |
|
||||
public override string DisplayText => "Deploying Manifests..."; |
|
||||
|
|
||||
public string Environment { get; set; } = "production"; |
|
||||
|
|
||||
public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application, ServiceBuilder service) |
|
||||
{ |
|
||||
var yaml = service.Outputs.OfType<IYamlManifestOutput>().ToArray(); |
|
||||
if (yaml.Length == 0) |
|
||||
{ |
|
||||
output.WriteDebugLine($"No yaml manifests found for service '{service.Name}'. Skipping."); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (!await KubectlDetector.Instance.IsKubectlInstalled.Value) |
|
||||
{ |
|
||||
throw new CommandException($"Cannot apply manifests for '{service.Name}' because kubectl is not installed."); |
|
||||
} |
|
||||
|
|
||||
if (!await KubectlDetector.Instance.IsKubectlConnectedToCluster.Value) |
|
||||
{ |
|
||||
throw new CommandException($"Cannot apply manifests for '{service.Name}' because kubectl is not connected to a cluster."); |
|
||||
} |
|
||||
|
|
||||
using var tempFile = TempFile.Create(); |
|
||||
output.WriteDebugLine($"Writing output to '{tempFile.FilePath}'."); |
|
||||
|
|
||||
{ |
|
||||
await using var stream = File.OpenWrite(tempFile.FilePath); |
|
||||
await 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.Name}'."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue