in src/common/PortForward/KubernetesPortForwardManager.cs [43:116]
public void StartContainerPortForward(
string namespaceName,
string podName,
int localPort,
int remotePort,
Action<PortPair> onSuccessfulPortForward = null,
CancellationToken cancellationToken = default(CancellationToken))
{
Task.Run(async () =>
{
using (var portListener = _portListenerFactory(localPort, cancellationToken))
{
try
{
_log.Verbose("Starting listening {0} : {1}", localPort, remotePort);
// Define how to get a webSocket on the pod Remote port
Func<Task<WebSocket>> createWebSocketAsync = async () =>
{
_log.Verbose("Creating web socket for {0} {1}", new PII(podName), remotePort);
Exception exception = null;
WebSocket ws = null;
for (int retry = 0; retry < 3; retry++)
{
try
{
ws = await this._kubernetesClient.WebSocketPodPortForwardAsync(
namespaceName,
podName,
new int[] { remotePort },
webSocketSubProtocol);
_log.Verbose("Web socket for {0} {1} created.", new PII(podName), remotePort);
return ws;
}
catch (WebSocketException ex)
{
exception = ex;
await Task.Delay(100);
}
}
_log.Verbose("Creating web socket for {0} {1} failed with {2}", new PII(podName), remotePort, exception.Message);
throw exception;
};
onSuccessfulPortForward?.Invoke(new PortPair(localPort, remotePort)); // This should probably not be invoked here. Since we just defined the function and haven't invoked it yet.
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
var localConnection = await portListener.Listener.AcceptTcpClientAsync();
_log.Verbose("Accept {0} to {1}", localPort, remotePort);
_streamManager.Start(
localConnection: localConnection,
remoteConnectionFactory: createWebSocketAsync,
remotePort: remotePort,
logMessagePrefixFormat: "Port forward {0} {1}:{2} {3}",
logMessagePrefixArgs: new object[] { new PII(podName), localPort, remotePort, ((IPEndPoint)localConnection.Client.RemoteEndPoint).Port },
log: _log,
cancellationToken: cancellationToken);
}
}
catch (ObjectDisposedException)
{
// Port forwarding has been canceled (e.g. Ctrl+C)
}
catch (Exception e)
{
_log.Exception(e);
_log.Error($"Port forwarding {namespaceName}/{podName} {localPort}:{remotePort} failed with exception : {e.Message}");
throw;
}
}
}).Forget();
}