Skip to content

Commit

Permalink
fix: Exec hangs (#1267)
Browse files Browse the repository at this point in the history
* fix: exec hanging

* fix: exec hang

* chore: increase buffer

* chore: add StandardOutput timeout

* chore: switch to event based

* chore: simplify logic

* chore: fix logic

* fix: remove async

* chore: simplify logic

* fix: revert to non Event based logic

* fix: simplify logic

* fix: switch to GetAwaiter().GetResult()

* feat: externalize exec timeout

* feat: send errors to event

* chore: formatting

* fix: add null check for event handler

* feat: switch to TimeSpan
  • Loading branch information
IvanJosipovic committed May 1, 2023
1 parent 2a37ba8 commit 7508ffe
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ public partial class KubernetesClientConfiguration
// For testing
internal static string KubeConfigEnvironmentVariable { get; set; } = "KUBECONFIG";

/// <summary>
/// Exec process timeout
/// </summary>
public static TimeSpan ExecTimeout { get; set; } = TimeSpan.FromMinutes(2);

/// <summary>
/// Exec process Standard Errors
/// </summary>
public static event EventHandler<DataReceivedEventArgs> ExecStdError;

/// <summary>
/// Initializes a new instance of the <see cref="KubernetesClientConfiguration" /> from default locations
/// If the KUBECONFIG environment variable is set, then that will be used.
Expand Down Expand Up @@ -552,25 +562,25 @@ public static ExecCredentialResponse ExecuteExternalCommand(ExternalExecution co
try
{
process.Start();
if (ExecStdError != null)
{
process.ErrorDataReceived += (s, e) => ExecStdError.Invoke(s, e);
process.BeginErrorReadLine();
}
}
catch (Exception ex)
{
throw new KubeConfigException($"external exec failed due to: {ex.Message}");
}

var stdout = process.StandardOutput.ReadToEnd();
var stderr = process.StandardError.ReadToEnd();
if (string.IsNullOrWhiteSpace(stderr) == false)
{
throw new KubeConfigException($"external exec failed due to: {stderr}");
}

// Wait for a maximum of 5 seconds, if a response takes longer probably something went wrong...
process.WaitForExit(5);

try
{
var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(stdout);
if (!process.WaitForExit((int)(ExecTimeout.TotalMilliseconds)))
{
throw new KubeConfigException("external exec failed due to timeout");
}

var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(process.StandardOutput.ReadToEnd());
if (responseObject == null || responseObject.ApiVersion != config.ApiVersion)
{
throw new KubeConfigException(
Expand Down

0 comments on commit 7508ffe

Please sign in to comment.