Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Helm V2 #1382

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion source/Calamari.Common/FeatureToggles/FeatureToggle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public enum FeatureToggle {
AsynchronousAzureZipDeployFeatureToggle,
FSharpDeprecationFeatureToggle,
AzureRMDeprecationFeatureToggle,
PreventHelmV2DeploymentsFeatureToggle,
KubernetesLiveObjectStatusFeatureToggle,
KubernetesAuthAwsCliWithExecFeatureToggle
}
Expand Down
60 changes: 0 additions & 60 deletions source/Calamari.Tests/KubernetesFixtures/Helm2UpgradeFixture.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ public async Task CustomHelmExeInPackage_RelativePath()
await TestCustomHelmExeInPackage_RelativePath("3.0.1");
}

protected override string ExplicitExeVersion => "3.0.2";
protected override string ExplicitExeVersion => "3.16.2";
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Calamari.Testing.Helpers;
using Calamari.Testing.Requirements;
using Calamari.Tests.Fixtures;
using Calamari.Tests.Helpers;
using NUnit.Framework;

namespace Calamari.Tests.KubernetesFixtures
Expand Down
79 changes: 12 additions & 67 deletions source/Calamari.Tests/KubernetesFixtures/HelmUpgradeFixture.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
Expand All @@ -18,7 +17,6 @@
using Calamari.Testing;
using Calamari.Testing.Helpers;
using Calamari.Testing.Requirements;
using Calamari.Tests.Fixtures;
using Calamari.Tests.Helpers;
using Calamari.Util;
using FluentAssertions;
Expand All @@ -44,9 +42,8 @@ public abstract class HelmUpgradeFixture : CalamariFixture

static string HelmOsPlatform => CalamariEnvironment.IsRunningOnWindows ? "windows-amd64" : "linux-amd64";

HelmVersion? helmVersion;
TemporaryDirectory explicitVersionTempDirectory;

static readonly CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
readonly CancellationToken cancellationToken = CancellationTokenSource.Token;

Expand All @@ -55,15 +52,10 @@ public async Task OneTimeSetUp()
{
ServerUrl = await ExternalVariables.Get(ExternalVariable.KubernetesClusterUrl, cancellationToken);
ClusterToken = await ExternalVariables.Get(ExternalVariable.KubernetesClusterToken, cancellationToken);

if (ExplicitExeVersion != null)
{
await DownloadExplicitHelmExecutable();
helmVersion = new SemanticVersion(ExplicitExeVersion).Major == 2 ? HelmVersion.V2 : HelmVersion.V3;
}
else
{
helmVersion = GetVersion();
}

async Task DownloadExplicitHelmExecutable()
Expand Down Expand Up @@ -101,7 +93,7 @@ public virtual void SetUp()
FileSystem.PurgeDirectory(packageExtractionDirectory, FailureOptions.ThrowOnFailure);

Environment.SetEnvironmentVariable("TentacleJournal",
Path.Combine(StagingDirectory, "DeploymentJournal.xml"));
Path.Combine(StagingDirectory, "DeploymentJournal.xml"));

Variables = new VariablesFactory(FileSystem).Create(new CommonOptions("test"));
Variables.Set(TentacleVariables.Agent.ApplicationDirectoryPath, StagingDirectory);
Expand All @@ -112,7 +104,6 @@ public virtual void SetUp()

//Helm Options
Variables.Set(Kubernetes.SpecialVariables.Helm.ReleaseName, ReleaseName);
Variables.Set(Kubernetes.SpecialVariables.Helm.ClientVersion, helmVersion.ToString());

//K8S Auth
Variables.Set(Kubernetes.SpecialVariables.ClusterUrl, ServerUrl);
Expand Down Expand Up @@ -195,7 +186,6 @@ public void ValuesFromPackage_NewValuesUsed()
Assert.AreEqual("Hello Variable Replaced In Package", result.CapturedOutput.OutputVariables["Message"]);
}


[Test]
[RequiresNonFreeBSDPlatform]
[RequiresNon32BitWindows]
Expand Down Expand Up @@ -255,7 +245,7 @@ public void ValuesFromPackageAndExplicit_ExplicitTakesPrecedence()
Variables.Set(PackageVariables.IndexedPackageId("Pack-1"), "CustomValues");
Variables.Set(PackageVariables.IndexedPackageVersion("Pack-1"), "2.0.0");
Variables.Set(PackageVariables.IndexedOriginalPath("Pack-1"),
GetFixtureResource("Charts", "CustomValues.2.0.0.zip"));
GetFixtureResource("Charts", "CustomValues.2.0.0.zip"));
Variables.Set(Kubernetes.SpecialVariables.Helm.Packages.ValuesFilePath("Pack-1"), "values.yaml");

//Variable that will replace packaged value in package
Expand Down Expand Up @@ -361,7 +351,7 @@ public void WhenTheChartDirectoryVariableIsSet_AndTheChartDoesNotExist_AnErrorIs
result.AssertFailure();
result.AssertOutputContains("Chart was not found in 'specific/location/for/my/chart'");
}

[Test]
[RequiresNonFreeBSDPlatform]
[RequiresNon32BitWindows]
Expand Down Expand Up @@ -402,18 +392,8 @@ void AddPostDeployMessageCheckAndCleanup(string explicitNamespace = null, bool d
Variables.Set(KnownVariables.Package.EnabledFeatures, KnownVariables.Features.CustomScripts);
}

string DeleteCommand(string @namespace, string releaseName)
{
switch (helmVersion)
{
case HelmVersion.V2:
return $"delete {releaseName} --purge";
case HelmVersion.V3:
return $"uninstall {releaseName} --namespace {@namespace}";
default:
throw new ArgumentOutOfRangeException(nameof(helmVersion), helmVersion, "Unrecognized Helm version");
}
}
static string DeleteCommand(string @namespace, string releaseName)
=> $"uninstall {releaseName} --namespace {@namespace}";

protected CalamariResult DeployPackage(string packageName = null)
{
Expand All @@ -423,14 +403,15 @@ protected CalamariResult DeployPackage(string packageName = null)
{
packageName = $"{Variables.Get(PackageVariables.PackageId)}-{Variables.Get(PackageVariables.PackageVersion)}.tgz";
}

Log.VerboseFormat("Deploying test chart from package: {0}", packageName);
var pkg = GetFixtureResource("Charts", packageName);
Variables.Save(variablesFile.FilePath);

return InvokeInProcess(Calamari()
.Action("helm-upgrade")
.Argument("package", pkg)
.Argument("variables", variablesFile.FilePath));
.Action("helm-upgrade")
.Argument("package", pkg)
.Argument("variables", variablesFile.FilePath));
}
}

Expand All @@ -445,41 +426,5 @@ static async Task DownloadHelmPackage(string version, string fileName)
}
}
}

static HelmVersion GetVersion()
{
StringBuilder stdout = new StringBuilder();
var result = SilentProcessRunner.ExecuteCommand("helm", "version --client --short", Environment.CurrentDirectory, output => stdout.AppendLine(output), error => { });

result.ExitCode.Should().Be(0, $"Failed to retrieve version from Helm (Exit code {result.ExitCode}). Error output: \r\n{result.ErrorOutput}");

return ParseVersion(stdout.ToString());
}

//versionString from "helm version --client --short"
static HelmVersion ParseVersion(string versionString)
{
//eg of output for helm 2: Client: v2.16.1+gbbdfe5e
//eg of output for helm 3: v3.0.1+g7c22ef9

var indexOfVersionIdentifier = versionString.IndexOf('v');
if (indexOfVersionIdentifier == -1)
throw new FormatException($"Failed to find version identifier from '{versionString}'.");

var indexOfVersionNumber = indexOfVersionIdentifier + 1;
if (indexOfVersionNumber >= versionString.Length)
throw new FormatException($"Failed to find version number from '{versionString}'.");

var version = versionString[indexOfVersionNumber];
switch (version)
{
case '3':
return HelmVersion.V3;
case '2':
return HelmVersion.V2;
default:
throw new InvalidOperationException($"Unsupported helm version '{version}'");
}
}
}
}
}
75 changes: 16 additions & 59 deletions source/Calamari/Kubernetes/Conventions/HelmUpgradeConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,33 +68,15 @@ string BuildHelmCommand(RunningDeployment deployment, ScriptSyntax syntax)
var packagePath = GetChartLocation(deployment);

var customHelmExecutable = CustomHelmExecutableFullPath(deployment.Variables, deployment.CurrentDirectory);
var helmVersion = GetVersion(deployment.Variables);
CheckHelmToolVersion(customHelmExecutable, helmVersion);

if (helmVersion == HelmVersion.V2)
{
if (FeatureToggle.PreventHelmV2DeploymentsFeatureToggle.IsEnabled(deployment.Variables))
{
throw new CommandException("Helm V2 is no longer supported. Please migrate to Helm V3.");
}
else
{
log.Warn("This step is currently configured to use Helm V2. Support for Helm V2 will be completely removed in Octopus Server 2025.1. Please migrate to Helm V3 as soon as possible.");
}
}
AssertHelmV3(customHelmExecutable);

var sb = new StringBuilder();

SetExecutable(sb, syntax, customHelmExecutable);
sb.Append($" upgrade --install");
SetNamespaceParameter(deployment, sb);
SetResetValuesParameter(deployment, sb);
if (helmVersion == HelmVersion.V2)
{
SetTillerTimeoutParameter(deployment, sb);
SetTillerNamespaceParameter(deployment, sb);
}

SetTimeoutParameter(deployment, sb);
SetValuesParameters(deployment, sb);
SetAdditionalArguments(deployment, sb);
Expand All @@ -104,16 +86,6 @@ string BuildHelmCommand(RunningDeployment deployment, ScriptSyntax syntax)
return sb.ToString();
}

HelmVersion GetVersion(IVariables variables)
{
var clientVersionText = variables.Get(SpecialVariables.Helm.ClientVersion);

if (Enum.TryParse(clientVersionText, out HelmVersion version))
return version;

throw new CommandException($"Unrecognized Helm version: '{clientVersionText}'");
}

void SetExecutable(StringBuilder sb, ScriptSyntax syntax, string customHelmExecutable)
{
if (customHelmExecutable != null)
Expand Down Expand Up @@ -211,14 +183,6 @@ void SetAdditionalArguments(RunningDeployment deployment, StringBuilder sb)
}
}

static void SetTillerNamespaceParameter(RunningDeployment deployment, StringBuilder sb)
{
if (deployment.Variables.IsSet(SpecialVariables.Helm.TillerNamespace))
{
sb.Append($" --tiller-namespace \"{deployment.Variables.Get(SpecialVariables.Helm.TillerNamespace)}\"");
}
}

static void SetTimeoutParameter(RunningDeployment deployment, StringBuilder sb)
{
if (!deployment.Variables.IsSet(SpecialVariables.Helm.Timeout)) return;
Expand All @@ -233,20 +197,7 @@ static void SetTimeoutParameter(RunningDeployment deployment, StringBuilder sb)
sb.Append($" --timeout \"{timeout}\"");
}

static void SetTillerTimeoutParameter(RunningDeployment deployment, StringBuilder sb)
{
if (!deployment.Variables.IsSet(SpecialVariables.Helm.TillerTimeout)) return;

var tillerTimeout = deployment.Variables.Get(SpecialVariables.Helm.TillerTimeout);
if (!int.TryParse(tillerTimeout, out _))
{
throw new CommandException($"Tiller timeout period is not a valid integer: {tillerTimeout}");
}

sb.Append($" --tiller-connection-timeout \"{tillerTimeout}\"");
}

string SyntaxSpecificFileName(RunningDeployment deployment, ScriptSyntax syntax)
static string SyntaxSpecificFileName(RunningDeployment deployment, ScriptSyntax syntax)
{
return Path.Combine(deployment.CurrentDirectory, syntax == ScriptSyntax.PowerShell ? "Calamari.HelmUpgrade.ps1" : "Calamari.HelmUpgrade.sh");
}
Expand Down Expand Up @@ -399,27 +350,33 @@ bool TryGenerateVariablesFile(RunningDeployment deployment, out string fileName)

return fileName != null;
}

void CheckHelmToolVersion(string customHelmExecutable, HelmVersion selectedVersion)
void AssertHelmV3(string customHelmExecutable)
{
log.Verbose($"Helm version selected: {selectedVersion}");

StringBuilder stdout = new StringBuilder();
var stdout = new StringBuilder();
var result = SilentProcessRunner.ExecuteCommand(customHelmExecutable ?? "helm",
"version --client --short",
Environment.CurrentDirectory,
output => stdout.Append(output),
error => { });

if (result.ExitCode != 0)
{
log.Warn("Unable to retrieve the Helm tool version");

return;
}

var toolVersion = HelmVersionParser.ParseVersion(stdout.ToString());
if (!toolVersion.HasValue)
{
log.Warn("Unable to parse the Helm tool version text: " + stdout);
return;
}

if (toolVersion.Value != selectedVersion)
log.Warn($"The Helm tool version '{toolVersion.Value}' ('{stdout}') doesn't match the Helm version selected '{selectedVersion}'");
if (toolVersion.Value != HelmVersion.V3)
{
throw new CommandException("Helm V2 is no longer supported. Please migrate to Helm V3.");
}
}
}
}
3 changes: 0 additions & 3 deletions source/Calamari/Kubernetes/SpecialVariables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ public static class Helm
public const string TemplateValuesSources = "Octopus.Action.Helm.TemplateValuesSources";
public const string AdditionalArguments = "Octopus.Action.Helm.AdditionalArgs";
public const string CustomHelmExecutable = "Octopus.Action.Helm.CustomHelmExecutable";
public const string ClientVersion = "Octopus.Action.Helm.ClientVersion";
public const string Timeout = "Octopus.Action.Helm.Timeout";
public const string TillerNamespace = "Octopus.Action.Helm.TillerNamespace";
public const string TillerTimeout = "Octopus.Action.Helm.TillerTimeout";
public const string ChartDirectory = "Octopus.Action.Helm.ChartDirectory";

public static class Packages
Expand Down