feat: detect an agent's public IPv4 and IPv6 addresses automatically, manual values still win [CI]
ci/woodpecker/push/main-amd64-build Pipeline was successful
ci/woodpecker/push/main-amd64-build Pipeline was successful
This commit is contained in:
1 parent
9966ea5d63
commit
f03988d68b
26 files changed
+517
-33
No files matched your search
@@ -14,7 +14,7 @@ public sealed class SqliteAgentStore : IAgentStore, IFleetStore
|
||||
{
|
||||
private const string AgentColumns =
|
||||
"id, name, status, pubkey, tls_spki, public_host, probe_tcp_port, probe_udp_ports, labels, public_visible, kinds, agent_version, local_limits, " +
|
||||
"task_version, applied_task_version, rejected, created_at, last_seen_at, row_version, ipv6_host, ipv6_supported, ipv6_diagnostics";
|
||||
"task_version, applied_task_version, rejected, created_at, last_seen_at, row_version, ipv6_host, ipv6_supported, ipv6_diagnostics, public_host_manual, ipv6_host_manual, reported_addresses";
|
||||
|
||||
private readonly SqliteDatabase _db;
|
||||
|
||||
@@ -60,11 +60,18 @@ public sealed class SqliteAgentStore : IAgentStore, IFleetStore
|
||||
return Result<AgentRecord>.Fail(MoShiroErrors.NameConflict, "another agent already uses this name");
|
||||
}
|
||||
|
||||
// 手填就标记为 manual(自动识别不再覆盖);撤销手填回到自动,值留到下一次识别
|
||||
bool hostAuto = patch.PublicHostAuto == true;
|
||||
bool v6Auto = patch.Ipv6HostAuto == true;
|
||||
c.Exec(
|
||||
"UPDATE agents SET name = @name, labels = @labels, public_host = @host, ipv6_host = @v6, public_visible = @visible, row_version = row_version + 1 WHERE id = @id",
|
||||
"UPDATE agents SET name = @name, labels = @labels, public_host = @host, ipv6_host = @v6, public_host_manual = @hostManual, ipv6_host_manual = @v6Manual, " +
|
||||
"public_visible = @visible, row_version = row_version + 1 WHERE id = @id",
|
||||
("@id", id.Value), ("@name", patch.Name ?? current.Name),
|
||||
("@labels", StorageJson.ToJson(patch.Labels ?? current.Labels)),
|
||||
("@host", patch.PublicHost ?? current.PublicHost), ("@v6", patch.Ipv6Host ?? current.Ipv6Host), ("@visible", (patch.PublicVisible ?? current.PublicVisible) ? 1 : 0));
|
||||
("@host", hostAuto ? current.PublicHost : patch.PublicHost ?? current.PublicHost), ("@v6", v6Auto ? current.Ipv6Host : patch.Ipv6Host ?? current.Ipv6Host),
|
||||
("@hostManual", hostAuto ? 0 : patch.PublicHost is not null || current.PublicHostManual ? 1 : 0),
|
||||
("@v6Manual", v6Auto ? 0 : patch.Ipv6Host is not null || current.Ipv6HostManual ? 1 : 0),
|
||||
("@visible", (patch.PublicVisible ?? current.PublicVisible) ? 1 : 0));
|
||||
return Result<AgentRecord>.Ok(GetInternal(c, id)!);
|
||||
}, ct);
|
||||
|
||||
@@ -117,9 +124,21 @@ public sealed class SqliteAgentStore : IAgentStore, IFleetStore
|
||||
{
|
||||
c.Exec(
|
||||
"UPDATE agents SET kinds = @kinds, agent_version = @version, local_limits = COALESCE(@limits, local_limits), tls_spki = COALESCE(@spki, tls_spki), " +
|
||||
"probe_tcp_port = COALESCE(@tcp, probe_tcp_port), probe_udp_ports = COALESCE(@udp, probe_udp_ports), ipv6_supported = @v6, ipv6_diagnostics = @diag, row_version = row_version + 1 WHERE id = @id",
|
||||
"probe_tcp_port = COALESCE(@tcp, probe_tcp_port), probe_udp_ports = COALESCE(@udp, probe_udp_ports), ipv6_supported = @v6, ipv6_diagnostics = @diag, " +
|
||||
"reported_addresses = COALESCE(@addr, reported_addresses), row_version = row_version + 1 WHERE id = @id",
|
||||
("@id", id.Value), ("@kinds", StorageJson.ToJson(hello.Kinds)), ("@version", hello.AgentVersion), ("@limits", hello.LocalLimitsJson),
|
||||
("@spki", hello.TlsSpki), ("@tcp", hello.ProbeTcpPort), ("@udp", hello.ProbeUdpPorts is null ? null : StorageJson.ToJson(hello.ProbeUdpPorts)), ("@v6", hello.Ipv6Supported ? 1 : 0), ("@diag", hello.Ipv6DiagnosticsJson));
|
||||
("@spki", hello.TlsSpki), ("@tcp", hello.ProbeTcpPort), ("@udp", hello.ProbeUdpPorts is null ? null : StorageJson.ToJson(hello.ProbeUdpPorts)), ("@v6", hello.Ipv6Supported ? 1 : 0), ("@diag", hello.Ipv6DiagnosticsJson),
|
||||
("@addr", hello.Addresses is null ? null : StorageJson.ToJson(hello.Addresses)));
|
||||
}, ct);
|
||||
|
||||
public ValueTask ApplyAutoAddressesAsync(NodeId id, string? publicHost, string? ipv6Host, CancellationToken ct) =>
|
||||
_db.ExecuteAsync(c =>
|
||||
{
|
||||
c.Exec(
|
||||
"UPDATE agents SET public_host = CASE WHEN public_host_manual = 0 AND @host IS NOT NULL THEN @host ELSE public_host END, " +
|
||||
"ipv6_host = CASE WHEN ipv6_host_manual = 0 AND @v6 IS NOT NULL THEN @v6 ELSE ipv6_host END, row_version = row_version + 1 " +
|
||||
"WHERE id = @id AND ((public_host_manual = 0 AND @host IS NOT NULL AND public_host <> @host) OR (ipv6_host_manual = 0 AND @v6 IS NOT NULL AND ipv6_host <> @v6))",
|
||||
("@id", id.Value), ("@host", publicHost), ("@v6", ipv6Host));
|
||||
}, ct);
|
||||
|
||||
public ValueTask SetTaskVersionAsync(NodeId id, long version, string taskHash, CancellationToken ct) =>
|
||||
@@ -244,7 +263,10 @@ public sealed class SqliteAgentStore : IAgentStore, IFleetStore
|
||||
r.GetInt64(18),
|
||||
r.GetString(19),
|
||||
r.GetInt64(20) != 0,
|
||||
r.NullableString(21));
|
||||
r.NullableString(21),
|
||||
r.GetInt64(22) != 0,
|
||||
r.GetInt64(23) != 0,
|
||||
StorageJson.Strings(r.GetString(24)));
|
||||
|
||||
private static NodeRecord ToNode(AgentRecord a, string? metaJson) =>
|
||||
new(a.Id, a.Name, a.Status, a.PublicKey, a.TlsSpki, a.Labels, metaJson, a.AgentVersion, a.CreatedAtMs, a.LastSeenAtMs);
|
||||
|
||||
Reference in new issue
Block a user