diff --git a/source/Octopus.Manager.Tentacle/Octopus.Manager.Tentacle.csproj b/source/Octopus.Manager.Tentacle/Octopus.Manager.Tentacle.csproj
index bed230c84..83a5ff374 100644
--- a/source/Octopus.Manager.Tentacle/Octopus.Manager.Tentacle.csproj
+++ b/source/Octopus.Manager.Tentacle/Octopus.Manager.Tentacle.csproj
@@ -124,7 +124,7 @@
-
+
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClientCompatibilityTests.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClientCompatibilityTests.cs
index 96bc605c8..114340bc1 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClientCompatibilityTests.cs
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/KubernetesClientCompatibilityTests.cs
@@ -21,10 +21,10 @@ public class KubernetesClientCompatibilityTests
{
static readonly object[] TestClusterVersions =
[
+ new object[] {new ClusterVersion(1, 34)},
new object[] {new ClusterVersion(1, 33)},
new object[] {new ClusterVersion(1, 32)},
new object[] {new ClusterVersion(1, 31)},
- new object[] {new ClusterVersion(1, 30)},
];
KubernetesTestsGlobalContext? testContext;
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Octopus.Tentacle.Kubernetes.Tests.Integration.csproj b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Octopus.Tentacle.Kubernetes.Tests.Integration.csproj
index 388ea4850..1e89f11e9 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Octopus.Tentacle.Kubernetes.Tests.Integration.csproj
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Octopus.Tentacle.Kubernetes.Tests.Integration.csproj
@@ -57,9 +57,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -69,6 +66,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-30.yaml b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-30.yaml
deleted file mode 100644
index f925dc6df..000000000
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-30.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-kind: Cluster
-apiVersion: kind.x-k8s.io/v1alpha4
-
-nodes:
- - role: control-plane
- image: kindest/node:v1.30.13@sha256:397209b3d947d154f6641f2d0ce8d473732bd91c87d9575ade99049aa33cd648
- - role: worker
- image: kindest/node:v1.30.13@sha256:397209b3d947d154f6641f2d0ce8d473732bd91c87d9575ade99049aa33cd648
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-31.yaml b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-31.yaml
index 386030778..27a298f6e 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-31.yaml
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-31.yaml
@@ -3,6 +3,6 @@ apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- image: kindest/node:v1.31.9@sha256:b94a3a6c06198d17f59cca8c6f486236fa05e2fb359cbd75dabbfc348a10b211
+ image: kindest/node:v1.31.12@sha256:0f5cc49c5e73c0c2bb6e2df56e7df189240d83cf94edfa30946482eb08ec57d2
- role: worker
- image: kindest/node:v1.31.9@sha256:b94a3a6c06198d17f59cca8c6f486236fa05e2fb359cbd75dabbfc348a10b211
+ image: kindest/node:v1.31.12@sha256:0f5cc49c5e73c0c2bb6e2df56e7df189240d83cf94edfa30946482eb08ec57d2
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-32.yaml b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-32.yaml
index 0f66c51ba..a00c3b64b 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-32.yaml
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-32.yaml
@@ -3,6 +3,6 @@ apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- image: kindest/node:v1.32.5@sha256:e3b2327e3a5ab8c76f5ece68936e4cafaa82edf58486b769727ab0b3b97a5b0d
+ image: kindest/node:v1.32.8@sha256:abd489f042d2b644e2d033f5c2d900bc707798d075e8186cb65e3f1367a9d5a1
- role: worker
- image: kindest/node:v1.32.5@sha256:e3b2327e3a5ab8c76f5ece68936e4cafaa82edf58486b769727ab0b3b97a5b0d
+ image: kindest/node:v1.32.8@sha256:abd489f042d2b644e2d033f5c2d900bc707798d075e8186cb65e3f1367a9d5a1
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-33.yaml b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-33.yaml
index 5e8a8f0d3..372cbbc10 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-33.yaml
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-33.yaml
@@ -3,6 +3,6 @@ apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- image: kindest/node:v1.33.1@sha256:050072256b9a903bd914c0b2866828150cb229cea0efe5892e2b644d5dd3b34f
+ image: kindest/node:v1.33.4@sha256:25a6018e48dfcaee478f4a59af81157a437f15e6e140bf103f85a2e7cd0cbbf2
- role: worker
- image: kindest/node:v1.33.1@sha256:050072256b9a903bd914c0b2866828150cb229cea0efe5892e2b644d5dd3b34f
+ image: kindest/node:v1.33.4@sha256:25a6018e48dfcaee478f4a59af81157a437f15e6e140bf103f85a2e7cd0cbbf2
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-34.yaml b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-34.yaml
new file mode 100644
index 000000000..9fef1b1a4
--- /dev/null
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/KindConfiguration/kind-config-v1-34.yaml
@@ -0,0 +1,8 @@
+kind: Cluster
+apiVersion: kind.x-k8s.io/v1alpha4
+
+nodes:
+ - role: control-plane
+ image: kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5a
+ - role: worker
+ image: kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5a
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/HelmDownloader.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/HelmDownloader.cs
index f4d648b59..f28857be9 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/HelmDownloader.cs
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/HelmDownloader.cs
@@ -9,7 +9,7 @@ namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling;
public class HelmDownloader : ToolDownloader
{
- const string LatestVersion = "v3.18.6";
+ const string LatestVersion = "v3.19.2";
public HelmDownloader( ILogger logger)
: base("helm", logger)
{
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KindDownloader.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KindDownloader.cs
index 8bc8a769c..fa903a8c4 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KindDownloader.cs
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KindDownloader.cs
@@ -6,7 +6,7 @@ namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling
{
public class KindDownloader : ToolDownloader
{
- const string LatestKindVersion = "v0.29.0";
+ const string LatestKindVersion = "v0.30.0";
public KindDownloader(ILogger logger)
: base("kind", logger)
diff --git a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlDownloader.cs b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlDownloader.cs
index a2e04adf2..86320b8e5 100644
--- a/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlDownloader.cs
+++ b/source/Octopus.Tentacle.Kubernetes.Tests.Integration/Setup/Tooling/KubeCtlDownloader.cs
@@ -4,7 +4,7 @@ namespace Octopus.Tentacle.Kubernetes.Tests.Integration.Setup.Tooling;
public class KubeCtlDownloader : ToolDownloader
{
- public const string LatestKubeCtlVersion = "v1.33.5";
+ public const string LatestKubeCtlVersion = "v1.34.2";
public KubeCtlDownloader(ILogger logger)
: base("kubectl", logger)
diff --git a/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesEventMonitorFixture.cs b/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesEventMonitorFixture.cs
index a2f366232..d4816ceb6 100644
--- a/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesEventMonitorFixture.cs
+++ b/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesEventMonitorFixture.cs
@@ -58,7 +58,7 @@ public async Task NoEntriesAreSentToMetricsWhenEventListIsEmpty()
var agentMetrics = Substitute.For();
agentMetrics.GetLatestEventTimestamp(Arg.Any()).ReturnsForAnyArgs(testEpoch);
var eventService = Substitute.For();
- var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[]{new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper()}, log);
+ var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[] { new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper() }, log);
await sut.CacheNewEvents(tokenSource.Token);
@@ -72,20 +72,23 @@ public async Task NfsPodKillingEventsAreTrackedInMetrics()
var agentMetrics = new StubbedAgentMetrics(testEpoch);
var eventService = Substitute.For();
eventService.FetchAllEventsAsync(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(
- new Corev1EventList(new List
+ new Corev1EventList
{
- new()
+ Items = new List
{
- Reason = "Killing",
- Metadata = new V1ObjectMeta()
+ new()
{
- Name = "octopus-agent-nfs-123412-1234123",
- },
- FirstTimestamp = testEpoch.DateTime.AddMinutes(1),
- LastTimestamp = testEpoch.DateTime.AddMinutes(1)
+ Reason = "Killing",
+ Metadata = new V1ObjectMeta()
+ {
+ Name = "octopus-agent-nfs-123412-1234123",
+ },
+ FirstTimestamp = testEpoch.DateTime.AddMinutes(1),
+ LastTimestamp = testEpoch.DateTime.AddMinutes(1)
+ }
}
- }));
- var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[]{new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper()}, log);
+ });
+ var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[] { new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper() }, log);
//Act
await sut.CacheNewEvents(tokenSource.Token);
@@ -105,21 +108,24 @@ public async Task NfsWatchDogEventsAreTrackedInMetrics()
var agentMetrics = new StubbedAgentMetrics(testEpoch);
var eventService = Substitute.For();
eventService.FetchAllEventsAsync(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(
- new Corev1EventList(new List
+ new Corev1EventList
{
- new()
+ Items = new List
{
- Reason = "NfsWatchdogTimeout",
- Metadata = new V1ObjectMeta()
+ new()
{
- Name = podName,
- },
- FirstTimestamp = testEpoch.DateTime.AddSeconds(1),
- LastTimestamp = testEpoch.DateTime.AddSeconds(1)
+ Reason = "NfsWatchdogTimeout",
+ Metadata = new V1ObjectMeta()
+ {
+ Name = podName,
+ },
+ FirstTimestamp = testEpoch.DateTime.AddSeconds(1),
+ LastTimestamp = testEpoch.DateTime.AddSeconds(1)
+ }
}
- }));
+ });
- var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[]{new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper()}, log);
+ var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[] { new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper() }, log);
//Act
await sut.CacheNewEvents(tokenSource.Token);
@@ -139,24 +145,27 @@ public async Task EventsOlderThanOrEqualToMetricsTimestampCursorAreNotAddedToMet
var agentMetrics = new StubbedAgentMetrics(testEpoch);
var eventService = Substitute.For();
eventService.FetchAllEventsAsync(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(
- new Corev1EventList(new List
+ new Corev1EventList
{
- new()
+ Items = new List
{
- Reason = "NfsWatchdogTimeout",
- Metadata = new V1ObjectMeta()
+ new()
{
- Name = podName,
- },
- FirstTimestamp = testEpoch.DateTime,
- LastTimestamp = testEpoch.DateTime
+ Reason = "NfsWatchdogTimeout",
+ Metadata = new V1ObjectMeta()
+ {
+ Name = podName,
+ },
+ FirstTimestamp = testEpoch.DateTime,
+ LastTimestamp = testEpoch.DateTime
+ }
}
- }));
-
- var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[]{new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper()}, log);
+ });
+
+ var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[] { new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper() }, log);
//Act
await sut.CacheNewEvents(tokenSource.Token);
-
+
//Assert
agentMetrics.Events.Should().BeEquivalentTo(new Dictionary>>());
}
@@ -169,25 +178,28 @@ public async Task NewestTimeStampInEventIsUsedToDetermineAgeAndAsMetricsValue()
var agentMetrics = new StubbedAgentMetrics(testEpoch);
var eventService = Substitute.For();
eventService.FetchAllEventsAsync(Arg.Any(), Arg.Any()).ReturnsForAnyArgs(
- new Corev1EventList(new List
+ new Corev1EventList
{
- new()
+ Items = new List
{
- Reason = "NfsWatchdogTimeout",
- Metadata = new V1ObjectMeta()
+ new()
{
- Name = podName,
- },
- FirstTimestamp = testEpoch.DateTime.AddMinutes(-2),
- LastTimestamp = testEpoch.DateTime.AddMinutes(-1),
- EventTime = testEpoch.DateTime.AddMinutes(1)
+ Reason = "NfsWatchdogTimeout",
+ Metadata = new V1ObjectMeta()
+ {
+ Name = podName,
+ },
+ FirstTimestamp = testEpoch.DateTime.AddMinutes(-2),
+ LastTimestamp = testEpoch.DateTime.AddMinutes(-1),
+ EventTime = testEpoch.DateTime.AddMinutes(1)
+ }
}
- }));
-
- var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[]{new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper()}, log);
+ });
+
+ var sut = new KubernetesEventMonitor(agentMetrics, eventService, "arbitraryNamespace", new IEventMapper[] { new NfsPodRestarted(), new TentacleKilledEventMapper(), new NfsStaleEventMapper() }, log);
//Act
await sut.CacheNewEvents(tokenSource.Token);
-
+
//Assert
// The event.EventTime is newest event Time stamp, and is larger than the last metric date (TestEpoch) as such
// the event should factored into the metrics, and should report this latest time value.
diff --git a/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesPodMonitorTests.cs b/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesPodMonitorTests.cs
index 4698cf51e..8d6493a0e 100644
--- a/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesPodMonitorTests.cs
+++ b/source/Octopus.Tentacle.Tests/Kubernetes/KubernetesPodMonitorTests.cs
@@ -29,7 +29,7 @@ public void SetUp()
{
podService = Substitute.For();
log = new InMemoryLog();
- clock = new FixedClock(new DateTimeOffset(2023,5,17,13,4,5, TimeSpan.Zero));
+ clock = new FixedClock(new DateTimeOffset(2023, 5, 17, 13, 4, 5, TimeSpan.Zero));
monitor = new KubernetesPodMonitor(podService, log, new TentacleScriptLogProvider(), clock);
scriptTicket = new ScriptTicket(Guid.NewGuid().ToString());
@@ -111,7 +111,7 @@ public async Task ExistingPodIsUpdatedWhenCompleted()
new()
{
Name = scriptTicket.ToKubernetesScriptPodName(),
- State = new V1ContainerState(terminated: new V1ContainerStateTerminated(0, finishedAt: DateTime.UtcNow))
+ State = new V1ContainerState { Terminated = new V1ContainerStateTerminated { ExitCode = 0, FinishedAt = DateTime.UtcNow } }
}
}
};
diff --git a/source/Octopus.Tentacle.Tests/Kubernetes/TrackedScriptPodFixture.cs b/source/Octopus.Tentacle.Tests/Kubernetes/TrackedScriptPodFixture.cs
index 45e114ecf..50463e8d9 100644
--- a/source/Octopus.Tentacle.Tests/Kubernetes/TrackedScriptPodFixture.cs
+++ b/source/Octopus.Tentacle.Tests/Kubernetes/TrackedScriptPodFixture.cs
@@ -20,7 +20,7 @@ public class TrackedScriptPodFixture
public void SetUp()
{
scriptTicket = new ScriptTicket("ScriptTicketId");
- clock = new FixedClock(new DateTimeOffset(2023,5,17,13,4,5, TimeSpan.Zero));
+ clock = new FixedClock(new DateTimeOffset(2023, 5, 17, 13, 4, 5, TimeSpan.Zero));
trackedPod = new TrackedScriptPod(scriptTicket, clock);
}
@@ -29,8 +29,8 @@ public void NullStatus_Pending()
{
//Just changing the tracked Pod to a different state
GetPodInRunningState();
-
- trackedPod.Update(new V1Pod(){ Metadata = new V1ObjectMeta(), Status = null});
+
+ trackedPod.Update(new V1Pod() { Metadata = new V1ObjectMeta(), Status = null });
trackedPod.State.Phase.Should().Be(TrackedScriptPodPhase.Pending);
}
@@ -39,11 +39,11 @@ public void NullContainerStatus_Pending()
{
//Just changing the tracked Pod to a different state
GetPodInRunningState();
-
- trackedPod.Update(new V1Pod(){ Metadata = new V1ObjectMeta(), Status = new V1PodStatus(){ Phase = "Foo", ContainerStatuses = null}});
+
+ trackedPod.Update(new V1Pod() { Metadata = new V1ObjectMeta(), Status = new V1PodStatus() { Phase = "Foo", ContainerStatuses = null } });
trackedPod.State.Phase.Should().Be(TrackedScriptPodPhase.Pending);
}
-
+
[Test]
public void ScriptContainerNotFound_Pending()
{
@@ -58,7 +58,7 @@ public void ScriptContainerNotFound_Pending()
public void CanTransitionFromPendingToRunning()
{
trackedPod.State.Phase.Should().Be(TrackedScriptPodPhase.Pending);
-
+
GetPodInRunningState();
}
@@ -89,7 +89,7 @@ public void UpdateWithCompletedPodButNoFinishedAt(string podPhase, int exitCode,
trackedPod.State.ExitCode.Should().Be(exitCode);
trackedPod.State.FinishedAt.Should().Be(clock.GetUtcTime());
}
-
+
[TestCase(0, TrackedScriptPodPhase.Succeeded)]
[TestCase(123, TrackedScriptPodPhase.Failed)]
public void MarkAsCompleted(int exitCode, TrackedScriptPodPhase expectedPhase)
@@ -130,7 +130,7 @@ public void PodUpdateAfterMarkAsCompleted_UpdatesToNewValue()
trackedPod.State.ExitCode.Should().Be(podStatusExitCode);
trackedPod.State.FinishedAt.Should().Be(podStatusFinishedAt);
}
-
+
void GetPodInRunningState()
{
trackedPod.Update(CreateV1Pod(RunningContainerState()));
@@ -144,7 +144,6 @@ static V1ContainerState RunningContainerState()
{
return new V1ContainerState()
{
-
Running = new V1ContainerStateRunning()
};
}
@@ -153,7 +152,6 @@ static V1ContainerState TerminatedContainerState(DateTime? finishedAt, int exitC
{
return new V1ContainerState()
{
-
Terminated = new V1ContainerStateTerminated()
{
FinishedAt = finishedAt,
@@ -183,7 +181,7 @@ static V1Pod CreateV1Pod(V1ContainerStatus containerStatus)
}
};
- return new V1Pod(status: podStatus, metadata: new V1ObjectMeta());
+ return new V1Pod { Status = podStatus, Metadata = new V1ObjectMeta() };
}
}
}
\ No newline at end of file
diff --git a/source/Octopus.Tentacle/Kubernetes/KubernetesEventMonitor.cs b/source/Octopus.Tentacle/Kubernetes/KubernetesEventMonitor.cs
index 3b164e58a..a7a12d5b4 100644
--- a/source/Octopus.Tentacle/Kubernetes/KubernetesEventMonitor.cs
+++ b/source/Octopus.Tentacle/Kubernetes/KubernetesEventMonitor.cs
@@ -38,7 +38,7 @@ public KubernetesEventMonitor(IKubernetesAgentMetrics agentMetrics, IKubernetesE
public async Task CacheNewEvents(CancellationToken cancellationToken)
{
log.Info($"Parsing kubernetes event list for namespace {kubernetesNamespace}.");
- var allEvents = await eventService.FetchAllEventsAsync(kubernetesNamespace, cancellationToken) ?? new Corev1EventList(new List());
+ var allEvents = await eventService.FetchAllEventsAsync(kubernetesNamespace, cancellationToken) ?? new Corev1EventList();
var lastCachedEventTimeStamp = await agentMetrics.GetLatestEventTimestamp(cancellationToken);
diff --git a/source/Octopus.Tentacle/Kubernetes/KubernetesPodService.cs b/source/Octopus.Tentacle/Kubernetes/KubernetesPodService.cs
index 15488cc73..4d40ccd5a 100644
--- a/source/Octopus.Tentacle/Kubernetes/KubernetesPodService.cs
+++ b/source/Octopus.Tentacle/Kubernetes/KubernetesPodService.cs
@@ -34,14 +34,6 @@ public async Task ListAllPods(CancellationToken cancellationToken)
public async Task WatchAllPods(string initialResourceVersion, Func onChange, Action onError, CancellationToken cancellationToken)
{
- using var response = Client.CoreV1.ListNamespacedPodWithHttpMessagesAsync(
- KubernetesConfig.Namespace,
- labelSelector: OctopusLabels.ScriptTicketId,
- resourceVersion: initialResourceVersion,
- watch: true,
- timeoutSeconds: KubernetesConfig.PodMonitorTimeoutSeconds,
- cancellationToken: cancellationToken);
-
var watchErrorCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
Action internalOnError = ex =>
@@ -55,7 +47,13 @@ public async Task WatchAllPods(string initialResourceVersion, Func(internalOnError, cancellationToken: watchErrorCancellationTokenSource.Token))
+ await foreach (var (type, pod) in Client.CoreV1.WatchListNamespacedPodAsync(
+ KubernetesConfig.Namespace,
+ labelSelector: OctopusLabels.ScriptTicketId,
+ resourceVersion: initialResourceVersion,
+ timeoutSeconds: KubernetesConfig.PodMonitorTimeoutSeconds,
+ onError: internalOnError,
+ cancellationToken: watchErrorCancellationTokenSource.Token))
{
await onChange(type, pod, cancellationToken);
}
@@ -84,10 +82,10 @@ public async Task Create(V1Pod pod, CancellationToken cancellationToken)
public async Task DeleteIfExists(ScriptTicket scriptTicket, CancellationToken cancellationToken)
=> await DeleteIfExistsInternal(scriptTicket, null, cancellationToken);
- public async Task DeleteIfExists(ScriptTicket scriptTicket, TimeSpan gracePeriod, CancellationToken cancellationToken)
+ public async Task DeleteIfExists(ScriptTicket scriptTicket, TimeSpan gracePeriod, CancellationToken cancellationToken)
=> await DeleteIfExistsInternal(scriptTicket, (long)Math.Floor(gracePeriod.TotalSeconds), cancellationToken);
async Task DeleteIfExistsInternal(ScriptTicket scriptTicket, long? gracePeriodSeconds, CancellationToken cancellationToken)
- => await TryExecuteAsync(async () => await Client.DeleteNamespacedPodAsync(scriptTicket.ToKubernetesScriptPodName(), KubernetesConfig.Namespace, new V1DeleteOptions(gracePeriodSeconds: gracePeriodSeconds), cancellationToken: cancellationToken));
+ => await TryExecuteAsync(async () => await Client.DeleteNamespacedPodAsync(scriptTicket.ToKubernetesScriptPodName(), KubernetesConfig.Namespace, new V1DeleteOptions { GracePeriodSeconds = gracePeriodSeconds }, cancellationToken: cancellationToken));
}
}
\ No newline at end of file
diff --git a/source/Octopus.Tentacle/Kubernetes/KubernetesRawScriptPodCreator.cs b/source/Octopus.Tentacle/Kubernetes/KubernetesRawScriptPodCreator.cs
index 5d74e2bd9..aa541b6ce 100644
--- a/source/Octopus.Tentacle/Kubernetes/KubernetesRawScriptPodCreator.cs
+++ b/source/Octopus.Tentacle/Kubernetes/KubernetesRawScriptPodCreator.cs
@@ -50,8 +50,15 @@ protected override async Task> CreateInitContainers(StartKube
container.Image = command.PodImageConfiguration?.Image ?? await containerResolver.GetContainerImageForCluster();
container.ImagePullPolicy = KubernetesConfig.ScriptPodPullPolicy;
container.Command = new List { "sh", "-c", GetInitExecutionScript("/nfs-mount", homeDir, workspacePath) };
- container.VolumeMounts = Merge(container.VolumeMounts, new[] { new V1VolumeMount("/nfs-mount", "init-nfs-volume"), new V1VolumeMount(homeDir, "tentacle-home") });
-
+ container.VolumeMounts = Merge(container.VolumeMounts, new[]
+ {
+ new V1VolumeMount
+ {
+ MountPath = "/nfs-mount", Name = "init-nfs-volume"
+ },
+ new V1VolumeMount { MountPath = homeDir, Name = "tentacle-home" }
+ });
+
return new List { container };
}
diff --git a/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs b/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs
index 9bada0fa1..27bc1c03f 100644
--- a/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs
+++ b/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs
@@ -194,7 +194,7 @@ async Task CreatePod(StartKubernetesScriptCommandV1 command, IScriptWorkspace wo
var imagePullSecretNames = new[] { imagePullSecretName }
.Concat(KubernetesConfig.PodImagePullSecretNames)
.WhereNotNull()
- .Select(secretName => new V1LocalObjectReference(secretName))
+ .Select(secretName => new V1LocalObjectReference { Name = secretName })
.ToList();
var scriptPodTemplate = await podTemplateService.GetScriptPodTemplate(cancellationToken);
@@ -340,25 +340,37 @@ protected async Task CreateScriptContainer(StartKubernetesScriptCom
container.VolumeMounts = Merge(container.VolumeMounts, new[]
{
- new V1VolumeMount(homeDir, "tentacle-home"),
- new V1VolumeMount("/root/agent_upgrade/", "agent-upgrade"),
- new V1VolumeMount("/tmp/agent_upgrade/", "agent-upgrade")
+ new V1VolumeMount
+ {
+ MountPath = homeDir,
+ Name = "tentacle-home"
+ },
+ new V1VolumeMount
+ {
+ MountPath = "/root/agent_upgrade/",
+ Name = "agent-upgrade"
+ },
+ new V1VolumeMount
+ {
+ MountPath = "/tmp/agent_upgrade/",
+ Name = "agent-upgrade"
+ }
});
container.Env = Merge(container.Env, new List
{
- new(KubernetesConfig.NamespaceVariableName, KubernetesConfig.Namespace),
- new(KubernetesConfig.HelmReleaseNameVariableName, KubernetesConfig.HelmReleaseName),
- new(KubernetesConfig.HelmChartVersionVariableName, KubernetesConfig.HelmChartVersion),
- new(KubernetesConfig.KubernetesMonitorEnabledVariableName, KubernetesConfig.KubernetesMonitorEnabled),
- new(KubernetesConfig.ServerCommsAddressesVariableName, string.Join(",", KubernetesConfig.ServerCommsAddresses)),
- new(KubernetesConfig.PersistentVolumeFreeBytesVariableName, spaceInformation?.freeSpaceBytes.ToString()),
- new(KubernetesConfig.PersistentVolumeSizeBytesVariableName, spaceInformation?.totalSpaceBytes.ToString()),
- new(EnvironmentVariables.TentacleHome, homeDir),
- new(EnvironmentVariables.TentacleInstanceName, appInstanceSelector.Current.InstanceName),
- new(EnvironmentVariables.TentacleVersion, Environment.GetEnvironmentVariable(EnvironmentVariables.TentacleVersion)),
- new(EnvironmentVariables.TentacleCertificateSignatureAlgorithm, Environment.GetEnvironmentVariable(EnvironmentVariables.TentacleCertificateSignatureAlgorithm)),
- new("OCTOPUS_RUNNING_IN_CONTAINER", "Y")
+ new() { Name = KubernetesConfig.NamespaceVariableName, Value = KubernetesConfig.Namespace },
+ new() { Name = KubernetesConfig.HelmReleaseNameVariableName, Value = KubernetesConfig.HelmReleaseName },
+ new() { Name = KubernetesConfig.HelmChartVersionVariableName, Value = KubernetesConfig.HelmChartVersion },
+ new() { Name = KubernetesConfig.KubernetesMonitorEnabledVariableName, Value = KubernetesConfig.KubernetesMonitorEnabled },
+ new() { Name = KubernetesConfig.ServerCommsAddressesVariableName, Value = string.Join(",", KubernetesConfig.ServerCommsAddresses) },
+ new() { Name = KubernetesConfig.PersistentVolumeFreeBytesVariableName, Value = spaceInformation?.freeSpaceBytes.ToString() },
+ new() { Name = KubernetesConfig.PersistentVolumeSizeBytesVariableName, Value = spaceInformation?.totalSpaceBytes.ToString() },
+ new() { Name = EnvironmentVariables.TentacleHome, Value = homeDir },
+ new() { Name = EnvironmentVariables.TentacleInstanceName, Value = appInstanceSelector.Current.InstanceName },
+ new() { Name = EnvironmentVariables.TentacleVersion, Value = Environment.GetEnvironmentVariable(EnvironmentVariables.TentacleVersion) },
+ new() { Name = EnvironmentVariables.TentacleCertificateSignatureAlgorithm, Value = Environment.GetEnvironmentVariable(EnvironmentVariables.TentacleCertificateSignatureAlgorithm) },
+ new() { Name = "OCTOPUS_RUNNING_IN_CONTAINER", Value = "Y" }
//We intentionally exclude setting "TentacleJournal" since it doesn't make sense to keep a Deployment Journal for Kubernetes deployments
});
@@ -404,14 +416,36 @@ V1Affinity ParseScriptPodAffinity(InMemoryTentacleScriptLog tentacleScriptLog)
KubernetesConfig.PodAffinityJsonVariableName,
"pod affinity",
//we default to running on linux/arm64 and linux/amd64 nodes
- new V1Affinity(new V1NodeAffinity(requiredDuringSchedulingIgnoredDuringExecution: new V1NodeSelector(new List
+ new V1Affinity()
{
- new(matchExpressions: new List
+ NodeAffinity = new V1NodeAffinity()
{
- new("kubernetes.io/os", "In", new List { "linux" }),
- new("kubernetes.io/arch", "In", new List { "arm64", "amd64" })
- })
- }))))!;
+ RequiredDuringSchedulingIgnoredDuringExecution = new V1NodeSelector
+ {
+ NodeSelectorTerms = new List
+ {
+ new()
+ {
+ MatchExpressions = new List
+ {
+ new()
+ {
+ Key = "kubernetes.io/os",
+ OperatorProperty = "In",
+ Values = new List { "linux" }
+ },
+ new()
+ {
+ Key = "kubernetes.io/arch",
+ OperatorProperty = "In",
+ Values = new List { "arm64", "amd64" }
+ },
+ }
+ }
+ }
+ }
+ }
+ })!;
List? ParseScriptPodTolerations(InMemoryTentacleScriptLog tentacleScriptLog)
=> ParseScriptPodJson>(
@@ -504,7 +538,7 @@ static string HashValue(string value)
{
using var sha1 = SHA1.Create();
var bytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(value));
- return BitConverter.ToString(bytes).Replace("-","");
+ return BitConverter.ToString(bytes).Replace("-", "");
}
[return: NotNullIfNotNull("defaultValue")]
@@ -564,9 +598,9 @@ static string HashValue(string value)
container.Image = KubernetesConfig.NfsWatchdogImage;
container.VolumeMounts = Merge(container.VolumeMounts, new List
{
- new(homeDir, "tentacle-home"),
+ new V1VolumeMount{MountPath = homeDir, Name = "tentacle-home"},
});
- container.Env = Merge(container.Env, new[] { new V1EnvVar(EnvironmentVariables.NfsWatchdogDirectory, homeDir) });
+ container.Env = Merge(container.Env, new[] { new V1EnvVar{Name = EnvironmentVariables.NfsWatchdogDirectory, Value = homeDir} });
return container;
}
diff --git a/source/Octopus.Tentacle/Octopus.Tentacle.csproj b/source/Octopus.Tentacle/Octopus.Tentacle.csproj
index c5a814c15..b57dc55ed 100644
--- a/source/Octopus.Tentacle/Octopus.Tentacle.csproj
+++ b/source/Octopus.Tentacle/Octopus.Tentacle.csproj
@@ -46,13 +46,10 @@
$(DefineConstants);HTTP_CLIENT_SUPPORTS_SSL_OPTIONS;REQUIRES_EXPLICIT_LOG_CONFIG;REQUIRES_CODE_PAGE_PROVIDER;USER_INTERACTIVE_DOES_NOT_WORK;DEFAULT_PROXY_IS_NOT_AVAILABLE;HAS_NULLABLE_REF_TYPES
-
-
-
-
+
-
+
@@ -123,4 +120,10 @@
+
+
+
+
+
+