Skip to content

Commit

Permalink
更新端口转发功能
Browse files Browse the repository at this point in the history
  • Loading branch information
weibaohui committed May 28, 2024
1 parent 091bfc0 commit e84da4e
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 45 deletions.
9 changes: 6 additions & 3 deletions BlazorApp/Pages/PortForwarding/PortForwardIndex.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@page "/PortForward"
@using BlazorApp.Pages.Common
@using BlazorApp.Pages.Common.Metadata
@using BlazorApp.Utils
@using Entity
@using k8s.Models
@inherits BlazorApp.Pages.Common.TableBase<Entity.PortForward>
Expand Down Expand Up @@ -32,9 +33,11 @@
<AntDesign.Column Field="@context.Name()" Title=@L["Name"]>
<Button OnClick="@(() => OnItemNameClick(context))" Type="@ButtonType.Link">@context.Name()</Button>
</AntDesign.Column>
<AntDesign.Column Field="@context.Namespace()" Title=@L["Namespace"] Width="110px"/>
<AntDesign.Column Field="@context.Type" Title=@L["KubeType"]/>
<AntDesign.Column Field="@context.KubeName" Title=@L["KubeName"]/>
<AntDesign.Column Field="@context.LocalPort" Title=@L["KubeName"]>
<RefView FullView="true"
Ref="@KubeHelper.GetObjectRef(context.Type.ToString(), context.Namespace(), context.KubeName)">
</RefView>
</AntDesign.Column>
<AntDesign.Column Field="@context.KubePort" Title=@L["KubePort"]/>
<AntDesign.Column Field="@context.LocalPort" Title=@L["LocalPort"]>
<div>
Expand Down
56 changes: 23 additions & 33 deletions BlazorApp/Utils/PortForwarding/PortForwardExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,53 @@
using System;
using System.Threading.Tasks;
using BlazorApp.Utils.Terminal;
using CliWrap;
using CliWrap.Buffered;
using Entity;
using k8s.Models;
using Microsoft.Extensions.Logging;

namespace BlazorApp.Utils.PortForwarding;

public class PortForwardExecutor
public class PortForwardExecutor(PortForward pf)
{
private static readonly ILogger<PortForwardExecutor> Logger = LoggingHelper<PortForwardExecutor>.Logger();

public PortForwardExecutor(PortForward portForward)
public PortForward GetPortForward()
{
PortForward = portForward;
return pf;
}

public PortForward PortForward { get; set; }

private string Command()
private string Args()
{
var command =
$"kubectl port-forward -n {PortForward.KubeNamespace} --address 0.0.0.0 {PortForward.Type.ToString().ToLower()}/{PortForward.KubeName} {PortForward.LocalPort}:{PortForward.KubePort} \r";
return command;
var args =
$" port-forward -n {pf.KubeNamespace} --address 0.0.0.0 {pf.Type.ToString().ToLower()}/{pf.KubeName} {pf.LocalPort}:{pf.KubePort}";
return args;
}

public async Task Start()
public void Start()
{
if (PortForward == null)
if (pf == null)
{
return;
}

var command = Command();
// Logger.LogError("PTY: {Command}",command);
var service = TerminalHelper.Instance.GetOrCreate(command);
if (!service.IsRunning)
{
await service.Start();
}

await service.Write(command);
ProcessManager.Instance.StartService(pf.Name(), "kubectl", Args());
}

private string GetNcProbeCommand()
{
return $"nc -v -w 1 -z 127.0.0.1 {PortForward.LocalPort} \r";
return $"nc -v -w 1 -z 127.0.0.1 {pf.LocalPort} \r";
}

private string GetNcProbeParameters()
private string GetNcProbeArgs()
{
return $"-v -w 1 -z 127.0.0.1 {PortForward.LocalPort} \r";
return $"-v -w 1 -z 127.0.0.1 {pf.LocalPort} \r";
}

public async Task StartProbe()
{
if (PortForward == null)
if (pf == null)
{
return;
}
Expand All @@ -65,32 +56,31 @@ public async Task StartProbe()
{
var cmd = Cli.Wrap("nc")
.WithValidation(CommandResultValidation.None)
.WithArguments(GetNcProbeParameters());
.WithArguments(GetNcProbeArgs());
// 执行命令并捕获输出
var result = await cmd.ExecuteBufferedAsync();
var all = result.StandardOutput + result.StandardError;
if (all.Contains("failed"))
PortForward.Status = "failed";
else if (all.Contains("succeeded")) PortForward.Status = "succeeded";
pf.Status = "failed";
else if (all.Contains("succeeded")) pf.Status = "succeeded";
}
catch (Exception ex)
{
Logger.LogError(ex, "PortForwardExecutor Probe Error: {Command}", GetNcProbeCommand());
PortForward.Status = "failed";
Logger.LogError(ex, " Probe Error: {Command}", GetNcProbeCommand());
pf.Status = "failed";
return;
}

PortForward.StatusTimestamp = DateTime.Now;
pf.StatusTimestamp = DateTime.Now;
}

public void Dispose()
{
if (PortForward == null)
if (pf == null)
{
return;
}

//释放探测终端、转发命令执行终端
TerminalHelper.Instance.GetOrCreate(Command()).Dispose();
ProcessManager.Instance.StopService(pf.Name());
}
}
18 changes: 9 additions & 9 deletions BlazorApp/Utils/PortForwarding/PortForwardExecutorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ private void NcProbe()
return;
}

Logger.LogInformation("开始探测{Count}端口是否存活", Map.Count);
Logger.LogInformation("开始探测端口是否存活,数量:{Count}", Map.Count);
lock (_lockObj)
{
foreach (var (_, pfe) in Map)
{
var pf = pfe.PortForward;
var pf = pfe.GetPortForward();
if (pf.StatusTimestamp != null && pf.StatusTimestamp.FromNowSeconds() < 10)
{
continue;
Expand Down Expand Up @@ -82,7 +82,7 @@ private void RemoveFailedPort()
{
foreach (var (_, pfe) in Map)
{
var pf = pfe.PortForward;
var pf = pfe.GetPortForward();
if (pf.StatusTimestamp != null && pf.Status.IsNullOrEmpty())
{
DisposeByItem(pf);
Expand Down Expand Up @@ -117,13 +117,13 @@ public async Task ForwardPort(PortForwardType type, string ns, string kubeName,
}
};

PortForwardExecutor pfe = new PortForwardExecutor(pf);
var pfe = new PortForwardExecutor(pf);
lock (_lockObj)
{
Map.TryAdd(pfe.PortForward.Metadata.Name, pfe);
Map.TryAdd(pf.Name(), pfe);
}

await pfe.Start();
pfe.Start();
await WatchUpdate(WatchEventType.Added, pf);
}

Expand All @@ -134,10 +134,10 @@ public async Task ForwardPort(PortForwardType type, string ns, string kubeName,
/// <param name="pf">PortForward</param>
public void DisposeByItem(PortForward pf)
{
string name = pf.Metadata.Name;
var name = pf.Metadata.Name;
lock (_lockObj)
{
Map.TryGetValue(name, out PortForwardExecutor? executor);
Map.TryGetValue(name, out var executor);
if (executor != null)
{
executor.Dispose();
Expand All @@ -146,7 +146,7 @@ public void DisposeByItem(PortForward pf)
Map.Remove(name);
}

WatchUpdate(WatchEventType.Deleted, executor.PortForward);
WatchUpdate(WatchEventType.Deleted, executor.GetPortForward());
}
}

Expand Down
75 changes: 75 additions & 0 deletions BlazorApp/Utils/ProcessManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Extensions.Logging;

namespace BlazorApp.Utils;

public class ProcessManager
{
private static readonly ILogger<ProcessManager> Logger = LoggingHelper<ProcessManager>.Logger();
private readonly Dictionary<string, Process> _services = new Dictionary<string, Process>();


public static ProcessManager Instance => Nested.Instance;

public void StartService(string name, string binPath, string args)
{
if (_services.ContainsKey(name))
{
Logger.LogInformation("服务 {Name} 已经在运行", name);
return;
}


var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = binPath,
Arguments = args,

RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
}
};

process.OutputDataReceived += (sender, arg) => Logger.LogInformation("[{Name}] 输出: {ArgData}", name, arg.Data);
process.ErrorDataReceived += (sender, arg) => Logger.LogInformation("[{Name}] 错误: {ArgData}", name, arg.Data);

process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();

_services[name] = process;

Logger.LogInformation("服务 {Name} 已启动", name);
}

public void StopService(string name)
{
if (_services.ContainsKey(name))
{
_services[name].Kill();
_services[name].Dispose();
_services.Remove(name);
Logger.LogInformation("服务 {Name} 已停止", name);
}
else
{
Logger.LogInformation("未找到运行中的服务 {Name}", name);
}
}

private class Nested
{
internal static readonly ProcessManager Instance = new ProcessManager();

// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
}
}

0 comments on commit e84da4e

Please sign in to comment.