agent: unify listening and dialing with directed mutual measurements
Replace Probe with Agent across node runtime, Fleet contracts, backend state, API and storage. Report incoming sessions and outgoing link health through each Agent uplink, and retain directed link controls and retry. Update protocol fixtures and end-to-end coverage for the unified model; accept requested cancellation during the Fleet timeout test cleanup.
This commit is contained in:
1 parent
d5ebf29e57
commit
ad5efc62ff
206 files changed
+4202
-4964
No files matched your search
@@ -21,7 +21,7 @@ public interface IDatabaseBackup
|
||||
public sealed record BackendUpdateView(string Channel, bool Enabled, string State, string? CurrentTag, string? CurrentDigest, ReleaseOffer? Available, string? Error);
|
||||
|
||||
/// <summary>
|
||||
/// Backend 的发布通知和确认,和 Agent、Probe 是同一种更新:面板登记 CI 签名的清单,管理员确认之后 Backend 有序退出,
|
||||
/// Backend 的发布通知和确认,和 Agent 是同一种更新:面板登记 CI 签名的清单,管理员确认之后 Backend 有序退出,
|
||||
/// Quadlet 单元每次启动都先拉最新镜像(<c>Pull=always</c>),所以退出再被拉起就是更新。Backend 自己不下载、不替换任何东西。
|
||||
/// 只有设了环境变量 <c>MOSHIRO_UPDATE=restart</c>(Quadlet 模板里写好了)才启用;别的部署方式退出之后不会重新拉取。
|
||||
/// 只提示不自动重启:Backend 指挥所有节点,重启会让它们全部断一两分钟。
|
||||
|
||||
@@ -5,14 +5,14 @@ using MoShiro.Protocol;
|
||||
namespace MoShiro.Backend.Application;
|
||||
|
||||
/// <summary>
|
||||
/// 定时去镜像仓库取各组件(Agent、Probe、Backend 自己)最新的签名清单:CI 把清单登记给面板那一步是尽力而为的(网络不通只警告),
|
||||
/// 定时去镜像仓库取各组件(Agent、Backend 自己)最新的签名清单:CI 把清单登记给面板那一步是尽力而为的(网络不通只警告),
|
||||
/// 面板自己也去仓库取,Backend 的更新通知和节点的更新建议就不依赖那一步。取回来的清单要用发布公钥验过签才登记。
|
||||
/// </summary>
|
||||
public sealed partial class ReleasePoller : BackgroundService
|
||||
{
|
||||
private static readonly TimeSpan s_startupDelay = TimeSpan.FromSeconds(20);
|
||||
private static readonly TimeSpan s_interval = TimeSpan.FromMinutes(5);
|
||||
private static readonly string[] s_components = [NodeKinds.Agent, NodeKinds.Probe, ReleaseService.BackendComponent];
|
||||
private static readonly string[] s_components = [ReleaseService.AgentComponent, ReleaseService.BackendComponent];
|
||||
|
||||
private readonly ReleaseService _releases;
|
||||
private readonly TimeProvider _time;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace MoShiro.Backend.Application;
|
||||
public sealed record ReleaseOffer(string Component, long Seq, string Tag, string Version, string Digest, string Manifest, string Signature, string Channel = "release");
|
||||
|
||||
/// <summary>
|
||||
/// 发布清单的分发:CI 签名之后推给面板,面板存下来并原样转给在线的 Agent、Probe(节点连上时再补发一次)。
|
||||
/// 发布清单的分发:CI 签名之后推给面板,面板存下来并原样转给在线的节点(节点连上时再补发一次)。
|
||||
/// 登记入口(<c>/api/release/offer</c>)只收带有效 CI 签名的清单;面板<b>不决定拉什么</b>:节点宿主机上的更新器用本机的发布公钥验签,并且只认本机配置的镜像仓库;
|
||||
/// 所以面板即使被攻破,也推不出一个能被装上的假镜像。面板只负责「通知」和「请求更新」,状态由节点随心跳报回来。
|
||||
/// </summary>
|
||||
@@ -20,7 +20,8 @@ public sealed partial class ReleaseService : IDisposable
|
||||
public const int MaxManifestBytes = 4096;
|
||||
public const int MaxSignatureBytes = 512;
|
||||
public const string BackendComponent = "backend";
|
||||
private static readonly string[] s_components = [NodeKinds.Agent, NodeKinds.Probe, BackendComponent];
|
||||
public const string AgentComponent = "agent";
|
||||
private static readonly string[] s_components = [AgentComponent, BackendComponent];
|
||||
|
||||
private readonly ISettingsStore _settings;
|
||||
private readonly IAgentGateway _gateway;
|
||||
@@ -116,7 +117,7 @@ public sealed partial class ReleaseService : IDisposable
|
||||
/// <summary>不再信任某把密钥之后(删除自有发布密钥):已登记的清单里,现在验不过的丢掉,免得继续分发。</summary>
|
||||
public async ValueTask PurgeUnverifiedAsync(CancellationToken ct)
|
||||
{
|
||||
foreach (string key in new[] { NodeKinds.Agent, NodeKinds.Probe, BackendComponent + ".dev", BackendComponent + ".release" })
|
||||
foreach (string key in new[] { AgentComponent, BackendComponent + ".dev", BackendComponent + ".release" })
|
||||
{
|
||||
string? manifest = await _settings.GetAsync(Key(key, "manifest"), ct);
|
||||
string? signature = await _settings.GetAsync(Key(key, "signature"), ct);
|
||||
@@ -188,9 +189,7 @@ public sealed partial class ReleaseService : IDisposable
|
||||
private IEnumerable<NodeId> OnlineOf(string component) => _gateway.OnlineNodes.Where(n => ComponentOf(n) == component);
|
||||
|
||||
internal static string? ComponentOf(NodeId node) =>
|
||||
node.Value.StartsWith(AgentIds.Prefix, StringComparison.Ordinal) ? NodeKinds.Agent
|
||||
: node.Value.StartsWith(ProbeId.Prefix, StringComparison.Ordinal) ? NodeKinds.Probe
|
||||
: null;
|
||||
node.Value.StartsWith(AgentIds.Prefix, StringComparison.Ordinal) ? AgentComponent : null;
|
||||
|
||||
private static string Key(string component, string part) => $"release.{component}.{part}";
|
||||
|
||||
|
||||
Reference in new issue
Block a user