diff --git a/README.md b/README.md index 35177bf..49df3f0 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ this is a hand-written **read-API client** (now) + an **SSH-runner** for mutatio ```bash dotnet build && dotnet test export SYNOLOGY_BASE_URL=https://nas:5001 SYNOLOGY_USER=… SYNOLOGY_PASSWORD=… SYNOLOGY_VERIFY_TLS=false -synosharp discover # JSON snapshot: DSM version, shares, users +synosharp discover # JSON snapshot: model, serial, DSM version, shares, users ``` Packages publish to GitHub Packages (chrison-dev) like the siblings: prerelease @@ -35,8 +35,8 @@ on push to `main`, stable on `v*` tag. ## Status -**Read/discover scaffold — UNVERIFIED.** The Virtual DSM test container needs -KVM/x86 so it can't run on Apple Silicon; the discover path is wired but must be -verified against a DSM target (a Linux-hosted Virtual DSM, or the live NAS -read-only). The `SYNO.Core.*` reads are defensive (degrade to empty on shape -mismatch). **Next:** verify discover, then the SSH-runner for the write path. +**Read/discover — verified against the live NAS (2026-05-31, DS1813+ / DSM +7.1.1-42962).** `discover` returns model, serial, DSM version, share names and +user names (`SYNO.Core.System` / `Share` / `User`). The `SYNO.Core.*` reads are +defensive (degrade to empty on shape mismatch). **Next:** the SSH-runner for the +write path (shares/NFS/users via on-box `syno*` + `synowebapi`). diff --git a/src/SynoSharp/SynologyDiscovery.cs b/src/SynoSharp/SynologyDiscovery.cs index 4862612..85428a1 100644 --- a/src/SynoSharp/SynologyDiscovery.cs +++ b/src/SynoSharp/SynologyDiscovery.cs @@ -28,20 +28,18 @@ public async Task DiscoverAsync(CancellationToken cancellation var users = await SafeListNamesAsync("SYNO.Core.User", 1, "list", "users", cancellationToken).ConfigureAwait(false); string? version = null; - string? hostname = null; + string? model = null; + string? serial = null; try { + // SYNO.Core.System info exposes firmware_ver / model / serial (verified + // against DSM 7.1.1 — there is no hostname field here). var info = await _client.GetAsync("SYNO.Core.System", 1, "info", cancellationToken: cancellationToken).ConfigureAwait(false); if (info.ValueKind == JsonValueKind.Object) { - if (info.TryGetProperty("firmware_ver", out var fv)) - { - version = fv.GetString(); - } - if (info.TryGetProperty("hostname", out var hn)) - { - hostname = hn.GetString(); - } + version = GetString(info, "firmware_ver"); + model = GetString(info, "model"); + serial = GetString(info, "serial"); } } catch @@ -51,13 +49,17 @@ public async Task DiscoverAsync(CancellationToken cancellation return new SynologySnapshot { + Model = model, + Serial = serial, DsmVersion = version, - Hostname = hostname, Shares = shares, Users = users, }; } + private static string? GetString(JsonElement obj, string name) + => obj.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.String ? v.GetString() : null; + private async Task> SafeListNamesAsync( string api, int version, string method, string arrayProperty, CancellationToken cancellationToken) { diff --git a/src/SynoSharp/SynologySnapshot.cs b/src/SynoSharp/SynologySnapshot.cs index 41668c5..0ebdb10 100644 --- a/src/SynoSharp/SynologySnapshot.cs +++ b/src/SynoSharp/SynologySnapshot.cs @@ -3,8 +3,9 @@ namespace SynoSharp; /// A read-only snapshot of DSM state (discover output). public sealed record SynologySnapshot { + public string? Model { get; init; } + public string? Serial { get; init; } public string? DsmVersion { get; init; } - public string? Hostname { get; init; } public IReadOnlyList Shares { get; init; } = []; public IReadOnlyList Users { get; init; } = []; }