using System.Text.Json;
namespace RackPeek.Domain.Discovery;
///
/// The engine host's own account of itself, from GET /info. This is what makes
/// a remote engine discoverable without user intervention: the daemon id gives the
/// services an identity seed that does not depend on which machine ran the command,
/// and the name is the hostname rpk discover system would report on that box.
///
public sealed record DockerEngineInfo {
///
/// The daemon's persisted unique id (kept under /var/lib/docker). Survives
/// reboots; changes only on an engine reinstall — the same failure mode
/// /etc/machine-id has for local discovery.
///
public string? Id { get; init; }
/// The engine host's hostname.
public string? Hostname { get; init; }
}
/// Parses the Docker Engine GET /info response. Pure, so it tests from a fixture.
public static class DockerEngineInfoParser {
public static DockerEngineInfo? Parse(string json) {
try {
using var document = JsonDocument.Parse(json);
if (document.RootElement.ValueKind != JsonValueKind.Object)
return null;
return new DockerEngineInfo {
Id = GetString(document.RootElement, "ID"),
Hostname = GetString(document.RootElement, "Name")
};
}
catch (JsonException) {
return null;
}
}
private static string? GetString(JsonElement element, string property) =>
element.TryGetProperty(property, out JsonElement value)
&& value.ValueKind == JsonValueKind.String
&& !string.IsNullOrWhiteSpace(value.GetString())
? value.GetString()
: null;
}