Skip to content

Commit 91e3a68

Browse files
committed
Refactor code to use ConfigureAwait(false) for asynchronous calls and update target framework to net9.0
1 parent 8e2c72b commit 91e3a68

File tree

13 files changed

+113
-112
lines changed

13 files changed

+113
-112
lines changed

examples/Directory.Build.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="..\Directory.Build.props" />
34
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
56
</PropertyGroup>
67
</Project>

examples/Directory.Build.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<Import Project="..\Directory.Build.targets" />
23
<ItemGroup>
34
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\src\KubernetesClient\KubernetesClient.csproj" Condition="'$(PublishAot)' != 'true'" />
45
</ItemGroup>

examples/cp/Cp.cs

Lines changed: 72 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using ICSharpCode.SharpZipLib.Tar;
1+
using ICSharpCode.SharpZipLib.Tar;
22
using k8s;
33
using System;
44
using System.IO;
@@ -7,110 +7,104 @@
77
using System.Threading;
88
using System.Threading.Tasks;
99

10-
namespace cp
11-
{
12-
internal class Cp
13-
{
14-
private static IKubernetes client;
10+
namespace cp;
1511

16-
private static async Task Main(string[] args)
17-
{
18-
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
19-
client = new Kubernetes(config);
12+
internal class Cp
13+
{
14+
private static IKubernetes client;
2015

16+
private static async Task Main(string[] args)
17+
{
18+
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
19+
client = new Kubernetes(config);
2120

22-
var pods = client.CoreV1.ListNamespacedPod("default", null, null, null, $"job-name=upload-demo");
23-
var pod = pods.Items.First();
2421

25-
await CopyFileToPodAsync(pod.Metadata.Name, "default", "upload-demo", args[0], $"home/{args[1]}");
22+
var pods = client.CoreV1.ListNamespacedPod("default", null, null, null, $"job-name=upload-demo");
23+
var pod = pods.Items.First();
2624

27-
}
25+
await CopyFileToPodAsync(pod.Metadata.Name, "default", "upload-demo", args[0], $"home/{args[1]}").ConfigureAwait(false);
26+
}
2827

2928

3029

3130

32-
private static void ValidatePathParameters(string sourcePath, string destinationPath)
31+
private static void ValidatePathParameters(string sourcePath, string destinationPath)
32+
{
33+
if (string.IsNullOrWhiteSpace(sourcePath))
3334
{
34-
if (string.IsNullOrWhiteSpace(sourcePath))
35-
{
36-
throw new ArgumentException($"{nameof(sourcePath)} cannot be null or whitespace");
37-
}
38-
39-
if (string.IsNullOrWhiteSpace(destinationPath))
40-
{
41-
throw new ArgumentException($"{nameof(destinationPath)} cannot be null or whitespace");
42-
}
43-
35+
throw new ArgumentException($"{nameof(sourcePath)} cannot be null or whitespace");
4436
}
4537

46-
public static async Task<int> CopyFileToPodAsync(string name, string @namespace, string container, string sourceFilePath, string destinationFilePath, CancellationToken cancellationToken = default(CancellationToken))
38+
if (string.IsNullOrWhiteSpace(destinationPath))
4739
{
48-
// All other parameters are being validated by MuxedStreamNamespacedPodExecAsync called by NamespacedPodExecAsync
49-
ValidatePathParameters(sourceFilePath, destinationFilePath);
40+
throw new ArgumentException($"{nameof(destinationPath)} cannot be null or whitespace");
41+
}
42+
}
43+
44+
public static async Task<int> CopyFileToPodAsync(string name, string @namespace, string container, string sourceFilePath, string destinationFilePath, CancellationToken cancellationToken = default(CancellationToken))
45+
{
46+
// All other parameters are being validated by MuxedStreamNamespacedPodExecAsync called by NamespacedPodExecAsync
47+
ValidatePathParameters(sourceFilePath, destinationFilePath);
5048

51-
// The callback which processes the standard input, standard output and standard error of exec method
52-
var handler = new ExecAsyncCallback(async (stdIn, stdOut, stdError) =>
49+
// The callback which processes the standard input, standard output and standard error of exec method
50+
var handler = new ExecAsyncCallback(async (stdIn, stdOut, stdError) =>
51+
{
52+
var fileInfo = new FileInfo(destinationFilePath);
53+
try
5354
{
54-
var fileInfo = new FileInfo(destinationFilePath);
55-
try
55+
using (var memoryStream = new MemoryStream())
5656
{
57-
using (var memoryStream = new MemoryStream())
57+
using (var inputFileStream = File.OpenRead(sourceFilePath))
58+
using (var tarOutputStream = new TarOutputStream(memoryStream, Encoding.Default))
5859
{
59-
using (var inputFileStream = File.OpenRead(sourceFilePath))
60-
using (var tarOutputStream = new TarOutputStream(memoryStream, Encoding.Default))
61-
{
62-
tarOutputStream.IsStreamOwner = false;
63-
64-
var fileSize = inputFileStream.Length;
65-
var entry = TarEntry.CreateTarEntry(fileInfo.Name);
66-
67-
entry.Size = fileSize;
60+
tarOutputStream.IsStreamOwner = false;
6861

69-
tarOutputStream.PutNextEntry(entry);
70-
await inputFileStream.CopyToAsync(tarOutputStream);
71-
tarOutputStream.CloseEntry();
72-
}
62+
var fileSize = inputFileStream.Length;
63+
var entry = TarEntry.CreateTarEntry(fileInfo.Name);
7364

74-
memoryStream.Position = 0;
65+
entry.Size = fileSize;
7566

76-
await memoryStream.CopyToAsync(stdIn);
77-
await stdIn.FlushAsync();
67+
tarOutputStream.PutNextEntry(entry);
68+
await inputFileStream.CopyToAsync(tarOutputStream).ConfigureAwait(false);
69+
tarOutputStream.CloseEntry();
7870
}
7971

80-
}
81-
catch (Exception ex)
82-
{
83-
throw new IOException($"Copy command failed: {ex.Message}");
84-
}
72+
memoryStream.Position = 0;
8573

86-
using StreamReader streamReader = new StreamReader(stdError);
87-
while (streamReader.EndOfStream == false)
88-
{
89-
string error = await streamReader.ReadToEndAsync();
90-
throw new IOException($"Copy command failed: {error}");
74+
await memoryStream.CopyToAsync(stdIn).ConfigureAwait(false);
75+
await stdIn.FlushAsync().ConfigureAwait(false);
9176
}
92-
});
93-
94-
string destinationFolder = GetFolderName(destinationFilePath);
95-
96-
return await client.NamespacedPodExecAsync(
97-
name,
98-
@namespace,
99-
container,
100-
new string[] { "sh", "-c", $"tar xmf - -C {destinationFolder}" },
101-
false,
102-
handler,
103-
cancellationToken);
104-
}
105-
77+
}
78+
catch (Exception ex)
79+
{
80+
throw new IOException($"Copy command failed: {ex.Message}");
81+
}
10682

107-
private static string GetFolderName(string filePath)
108-
{
109-
var folderName = Path.GetDirectoryName(filePath);
83+
using StreamReader streamReader = new StreamReader(stdError);
84+
while (streamReader.EndOfStream == false)
85+
{
86+
string error = await streamReader.ReadToEndAsync().ConfigureAwait(false);
87+
throw new IOException($"Copy command failed: {error}");
88+
}
89+
});
90+
91+
string destinationFolder = GetFolderName(destinationFilePath);
92+
93+
return await client.NamespacedPodExecAsync(
94+
name,
95+
@namespace,
96+
container,
97+
new string[] { "sh", "-c", $"tar xmf - -C {destinationFolder}" },
98+
false,
99+
handler,
100+
cancellationToken).ConfigureAwait(false);
101+
}
110102

111-
return string.IsNullOrEmpty(folderName) ? "." : folderName;
112-
}
113103

104+
private static string GetFolderName(string filePath)
105+
{
106+
var folderName = Path.GetDirectoryName(filePath);
114107

108+
return string.IsNullOrEmpty(folderName) ? "." : folderName;
115109
}
116110
}

examples/csrApproval/Program.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Json.Patch;
1+
using Json.Patch;
22
using k8s;
33
using k8s.Models;
44
using System.Net;
@@ -44,34 +44,34 @@ string GenerateCertificate(string name)
4444
Kind = "CertificateSigningRequest",
4545
Metadata = new V1ObjectMeta
4646
{
47-
Name = name
47+
Name = name,
4848
},
4949
Spec = new V1CertificateSigningRequestSpec
5050
{
5151
Request = encodedCsr,
5252
SignerName = "kubernetes.io/kube-apiserver-client",
5353
Usages = new List<string> { "client auth" },
54-
ExpirationSeconds = 600 // minimum should be 10 minutes
55-
}
54+
ExpirationSeconds = 600, // minimum should be 10 minutes
55+
},
5656
};
5757

58-
await client.CertificatesV1.CreateCertificateSigningRequestAsync(request);
58+
await client.CertificatesV1.CreateCertificateSigningRequestAsync(request).ConfigureAwait(false);
5959

6060
var serializeOptions = new JsonSerializerOptions
6161
{
6262
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
63-
WriteIndented = true
63+
WriteIndented = true,
6464
};
65-
var readCert = await client.CertificatesV1.ReadCertificateSigningRequestAsync(name);
65+
var readCert = await client.CertificatesV1.ReadCertificateSigningRequestAsync(name).ConfigureAwait(false);
6666
var old = JsonSerializer.SerializeToDocument(readCert, serializeOptions);
6767

6868
var replace = new List<V1CertificateSigningRequestCondition>
6969
{
70-
new("True", "Approved", DateTime.UtcNow, DateTime.UtcNow, "This certificate was approved by k8s client", "Approve")
70+
new("True", "Approved", DateTime.UtcNow, DateTime.UtcNow, "This certificate was approved by k8s client", "Approve"),
7171
};
7272
readCert.Status.Conditions = replace;
7373

7474
var expected = JsonSerializer.SerializeToDocument(readCert, serializeOptions);
7575

7676
var patch = old.CreatePatch(expected);
77-
await client.CertificatesV1.PatchCertificateSigningRequestApprovalAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name);
77+
await client.CertificatesV1.PatchCertificateSigningRequestApprovalAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name).ConfigureAwait(false);

examples/openTelemetryConsole/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
{
3030
Console.WriteLine(item.Metadata.Name);
3131
}
32+
3233
// Or empty if there are no pods
3334
if (list.Items.Count == 0)
3435
{

examples/patch-aot/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ static void PrintLabels(V1Pod pod)
2828
{
2929
Console.WriteLine($"{k} : {v}");
3030
}
31+
3132
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=");
3233
}

examples/portforward/PortForward.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ private static async Task Main(string[] args)
1818

1919
var list = client.CoreV1.ListNamespacedPod("default");
2020
var pod = list.Items[0];
21-
await Forward(client, pod);
21+
await Forward(client, pod).ConfigureAwait(false);
2222
}
2323

2424
private static async Task Forward(IKubernetes client, V1Pod pod)
2525
{
2626
// Note this is single-threaded, it won't handle concurrent requests well...
27-
var webSocket = await client.WebSocketNamespacedPodPortForwardAsync(pod.Metadata.Name, "default", new int[] { 80 }, "v4.channel.k8s.io");
27+
var webSocket = await client.WebSocketNamespacedPodPortForwardAsync(pod.Metadata.Name, "default", new int[] { 80 }, "v4.channel.k8s.io").ConfigureAwait(false);
2828
var demux = new StreamDemuxer(webSocket, StreamType.PortForward);
2929
demux.Start();
3030

@@ -67,12 +67,13 @@ private static async Task Forward(IKubernetes client, V1Pod pod)
6767
}
6868
});
6969

70-
await accept;
71-
await copy;
70+
await accept.ConfigureAwait(false);
71+
await copy.ConfigureAwait(false);
7272
if (handler != null)
7373
{
7474
handler.Close();
7575
}
76+
7677
listener.Close();
7778
}
7879
}

examples/restart/Program.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,68 @@
1-
using Json.Patch;
1+
using Json.Patch;
22
using k8s;
33
using k8s.Models;
44
using System.Text.Json;
55

66
async Task RestartDaemonSetAsync(string name, string @namespace, IKubernetes client)
77
{
8-
var daemonSet = await client.AppsV1.ReadNamespacedDaemonSetAsync(name, @namespace);
8+
var daemonSet = await client.AppsV1.ReadNamespacedDaemonSetAsync(name, @namespace).ConfigureAwait(false);
99
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true };
1010
var old = JsonSerializer.SerializeToDocument(daemonSet, options);
1111
var now = DateTimeOffset.Now.ToUnixTimeSeconds();
1212
var restart = new Dictionary<string, string>
1313
{
14-
["date"] = now.ToString()
14+
["date"] = now.ToString(),
1515
};
1616

1717
daemonSet.Spec.Template.Metadata.Annotations = restart;
1818

1919
var expected = JsonSerializer.SerializeToDocument(daemonSet);
2020

2121
var patch = old.CreatePatch(expected);
22-
await client.AppsV1.PatchNamespacedDaemonSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace);
22+
await client.AppsV1.PatchNamespacedDaemonSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace).ConfigureAwait(false);
2323
}
2424

2525
async Task RestartDeploymentAsync(string name, string @namespace, IKubernetes client)
2626
{
27-
var deployment = await client.AppsV1.ReadNamespacedDeploymentAsync(name, @namespace);
27+
var deployment = await client.AppsV1.ReadNamespacedDeploymentAsync(name, @namespace).ConfigureAwait(false);
2828
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true };
2929
var old = JsonSerializer.SerializeToDocument(deployment, options);
3030
var now = DateTimeOffset.Now.ToUnixTimeSeconds();
3131
var restart = new Dictionary<string, string>
3232
{
33-
["date"] = now.ToString()
33+
["date"] = now.ToString(),
3434
};
3535

3636
deployment.Spec.Template.Metadata.Annotations = restart;
3737

3838
var expected = JsonSerializer.SerializeToDocument(deployment);
3939

4040
var patch = old.CreatePatch(expected);
41-
await client.AppsV1.PatchNamespacedDeploymentAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace);
41+
await client.AppsV1.PatchNamespacedDeploymentAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace).ConfigureAwait(false);
4242
}
4343

4444
async Task RestartStatefulSetAsync(string name, string @namespace, IKubernetes client)
4545
{
46-
var deployment = await client.AppsV1.ReadNamespacedStatefulSetAsync(name, @namespace);
46+
var deployment = await client.AppsV1.ReadNamespacedStatefulSetAsync(name, @namespace).ConfigureAwait(false);
4747
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true };
4848
var old = JsonSerializer.SerializeToDocument(deployment, options);
4949
var now = DateTimeOffset.Now.ToUnixTimeSeconds();
5050
var restart = new Dictionary<string, string>
5151
{
52-
["date"] = now.ToString()
52+
["date"] = now.ToString(),
5353
};
5454

5555
deployment.Spec.Template.Metadata.Annotations = restart;
5656

5757
var expected = JsonSerializer.SerializeToDocument(deployment);
5858

5959
var patch = old.CreatePatch(expected);
60-
await client.AppsV1.PatchNamespacedStatefulSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace);
60+
await client.AppsV1.PatchNamespacedStatefulSetAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, @namespace).ConfigureAwait(false);
6161
}
6262

6363
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
6464
IKubernetes client = new Kubernetes(config);
6565

66-
await RestartDeploymentAsync("event-exporter", "monitoring", client);
67-
await RestartDaemonSetAsync("prometheus-exporter", "monitoring", client);
68-
await RestartStatefulSetAsync("argocd-application-controlle", "argocd", client);
66+
await RestartDeploymentAsync("event-exporter", "monitoring", client).ConfigureAwait(false);
67+
await RestartDaemonSetAsync("prometheus-exporter", "monitoring", client).ConfigureAwait(false);
68+
await RestartStatefulSetAsync("argocd-application-controlle", "argocd", client).ConfigureAwait(false);

examples/watch/Program.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private static async Task Main(string[] args)
1616

1717
var podlistResp = client.CoreV1.ListNamespacedPodWithHttpMessagesAsync("default", watch: true);
1818
// C# 8 required https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8
19-
await foreach (var (type, item) in podlistResp.WatchAsync<V1Pod, V1PodList>())
19+
await foreach (var (type, item) in podlistResp.WatchAsync<V1Pod, V1PodList>().ConfigureAwait(false))
2020
{
2121
Console.WriteLine("==on watch event==");
2222
Console.WriteLine(type);
@@ -28,7 +28,9 @@ private static async Task Main(string[] args)
2828
// WatchUsingCallback(client);
2929
}
3030

31+
#pragma warning disable IDE0051 // Remove unused private members
3132
private static void WatchUsingCallback(IKubernetes client)
33+
#pragma warning restore IDE0051 // Remove unused private members
3234
{
3335
var podlistResp = client.CoreV1.ListNamespacedPodWithHttpMessagesAsync("default", watch: true);
3436
using (podlistResp.Watch<V1Pod, V1PodList>((type, item) =>

0 commit comments

Comments
 (0)