From 7173f4dc1213cb50b1be7b3719921c0303de06f0 Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Thu, 25 Jun 2026 11:08:28 -0700 Subject: [PATCH] synology: live-verify against cascadesDS, fix services method + pipe handling First live exercise of the skill against the Cascades DS718+ (DSM 7.2.1, VPN up). - Fix `services`: SYNO.Core.Service.list 103s on DSM 7.2.1 -> method is `get`. - Fix `apis | head` BrokenPipeError traceback -> caught, clean exit. - SKILL.md status PLUMBED -> VERIFIED 2026-06-25 with live device facts. - wiki/cascades-tucson: add NAS specs, resolve model/RAM/DSM TODO. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/synology/SKILL.md | 19 +++++++++++++------ .../skills/synology/scripts/syno_client.py | 13 +++++++++++-- wiki/clients/cascades-tucson.md | 3 ++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.claude/skills/synology/SKILL.md b/.claude/skills/synology/SKILL.md index 38397859..91bd5a1d 100644 --- a/.claude/skills/synology/SKILL.md +++ b/.claude/skills/synology/SKILL.md @@ -110,12 +110,19 @@ log via `.claude/scripts/log-skill-error.sh` before surfacing. Handled condition VPN-down connect error surfaced to the user, a method refused for lack of --confirm) are NOT logged. ## Status / verification -- **[PLUMBED]** Built from a 5-agent scan of the DSM 7 help tree + the authoritative API sources - (kwent device-extracted `_full.json`, N4S4/synology-api, Synology's Web API guides) — see - `references/dsm-api.md`. Auth (sid + synotoken CSRF), API discovery, version-by-maxVersion routing, - session-expiry re-login (codes 106/119), the mutating-verb gate, and the generic-error map are all - coded to spec but **not yet live-exercised** against the device (needs the Cascades VPN up). First - live `test` confirms endpoint shapes + fills the model/DSM-version wiki TODO. Mark verified then. +- **[VERIFIED 2026-06-25 — HOWARD-HOME, Cascades VPN up]** First live exercise against the device. + Confirmed working: auth (sid + synotoken CSRF), API discovery (`apis`), version-by-maxVersion + routing, and reads `test` / `storage` / `shares` / `packages` / `services` / `apis`. Device is + **DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, serial 1920PEN537202**; ext4, 2x WD10EZEX 1 TB. + 10 shares (incl. hidden `pacs`, `Activities`, `chat`, `Sandra Fish`); 30 packages running incl. + **Active Backup for Business 3.1.0, Synology Drive Server 3.5.0, Chat, VPN Server, Hybrid Share**. + Session-expiry re-login (106/119), the mutating-verb gate, and the generic-error map are coded to + spec but not yet exercised against a live write (no mutating call made yet — gate verified only by + the read path). Built originally from a 5-agent scan of the DSM 7 help tree + authoritative API + sources (kwent `_full.json`, N4S4/synology-api, Synology Web API guides) — see `references/dsm-api.md`. +- **Live fixes from this run (2026-06-25):** `services` used `SYNO.Core.Service.list` which 103s on + DSM 7.2.1 — corrected to `get` (returns `{"service":[...]}`). `apis | head` raised a + `BrokenPipeError` traceback — now caught and exits cleanly. - **DSM 7.2.x reboot/shutdown 103:** the Web-API `reboot`/`shutdown` can return error 103 on some builds. Fallback is the SSH `reboot|shutdown --confirm` recipe (`synoshutdown -r|-s`). - **Param-schema caveat:** method names + versions in the reference are device-authoritative, but many diff --git a/.claude/skills/synology/scripts/syno_client.py b/.claude/skills/synology/scripts/syno_client.py index b3e6970a..87a5abf4 100644 --- a/.claude/skills/synology/scripts/syno_client.py +++ b/.claude/skills/synology/scripts/syno_client.py @@ -332,7 +332,8 @@ def main(argv): elif args.cmd == "packages": _print(c.call("SYNO.Core.Package", "list", additional='["status","installed_info"]')) elif args.cmd == "services": - _print(c.call("SYNO.Core.Service", "list")) + # DSM 7.2.x: SYNO.Core.Service enumerates via `get` (not `list`); returns {"service":[...]} + _print(c.call("SYNO.Core.Service", "get")) elif args.cmd == "connections": _print(c.call("SYNO.Core.CurrentConnection", "list")) elif args.cmd == "ls": @@ -375,4 +376,12 @@ def main(argv): if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) + try: + sys.exit(main(sys.argv[1:])) + except BrokenPipeError: + # downstream pipe closed (e.g. `apis | head`) -- exit cleanly, no traceback + try: + sys.stdout.close() + except Exception: + pass + os._exit(0) diff --git a/wiki/clients/cascades-tucson.md b/wiki/clients/cascades-tucson.md index 00156b99..5398e7d2 100644 --- a/wiki/clients/cascades-tucson.md +++ b/wiki/clients/cascades-tucson.md @@ -358,6 +358,7 @@ Cascades' line-of-business / reporting SaaS (the systems they pull data OUT of, ### Synology NAS (cascadesDS) / Shared File Access +- **Device specs (confirmed live 2026-06-25 via `synology` skill):** **DS718+**, **DSM 7.2.1-69057 Update 11**, **6 GB RAM**, serial 1920PEN537202. Filesystem **ext4** (NOT Btrfs); 2x WD10EZEX 1 TB (volume1). 10 shares (homes, Public, SalesDept, Server, Management + hidden `pacs`, `Activities`, `chat`, `Sandra Fish`, `web`). 30 packages running incl. **Active Backup for Business 3.1.0** (works on ext4 -- only ABB dedup/self-healing needs Btrfs), **Synology Drive Server 3.5.0**, Chat, VPN Server, Hybrid Share. Reachable only with the Cascades site VPN up. - **Stale Word owner (lock) files on cascadesDS shares:** Word creates a hidden `~$` owner file when a document is opened; orphaned on abrupt session end. **Fix:** delete the `~$` file(s). Confirmed 2026-06-10. - **Accessing cascadesDS from RMM -- always use a user session, not CS-SERVER SYSTEM.** The domain-joined CS-SERVER machine account cannot authenticate to the Synology `Public` share because cascadesDS uses workgroup "CASCADES" (same short name as the AD domain), causing Kerberos auth failures. Run the command in `user_session` context of a machine where the target user is actively logged in. - **Synology Drive sync scope (as of 2026-06-18):** The Drive Client on CS-SERVER syncs only the **Sync DSM user's My Drive** (`/volume1/homes/Sync/Drive/`) into `D:\Shares\Main` -- one-way download. The real department shared folders (`/volume1/Server`, `/volume1/Management`, `/volume1/Public`, `/volume1/SalesDept`, etc.) are **NOT** in this scope. Note: `synopkg status SynologyDrive` falsely returns "stopped" (status 263) even when active -- verify via `systemctl is-active pkgctl-SynologyDrive` and `netstat -tlnp | grep 6690`. @@ -493,7 +494,7 @@ Syncro live pull 2026-06-24: **6 open tickets** -- #32194 (spare machine for new - **[PENDING] Re-enable 3 AM AP auto-upgrade** (left OFF after 2026-06-19 overnight run; re-enable when ready). - **[PENDING] Stand up recurring `dfs-check.sh` radar monitor** on the DFS channels (fold into network-logging plan) -- UniFi auto-vacates one AP on radar hit; the monitor tells us if it ever fires. - **[PENDING - next week] MemCare min-RSSI (floors 5/6)** -- deferred until Howard adds new APs to floors 5/6; rooms 515/210/204 have weak clients that would be orphaned by min-RSSI today. -- **[PLANNED] Network logging / observability (spec written, build later).** Plan: **Synology cascadesDS (DSM Log Center syslog server)** as on-site collector, pfSense + UniFi-controller + AP syslog as sources, `/stat/sta` client snapshotter to fill the controller's history gap. Spec: `docs/network/network-logging-plan.md`. Confirm Synology model/RAM/DSM before build. +- **[PLANNED] Network logging / observability (spec written, build later).** Plan: **Synology cascadesDS (DSM Log Center syslog server)** as on-site collector, pfSense + UniFi-controller + AP syslog as sources, `/stat/sta` client snapshotter to fill the controller's history gap. Spec: `docs/network/network-logging-plan.md`. Synology specs **confirmed 2026-06-25: DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, ext4** (see NAS section above) -- Log Center package not yet confirmed installed; check with `apis logcenter` before build. - **[PENDING] Synology Drive Team Folder migration (department shares -> CS-SERVER).** Current Drive sync covers only the Sync-user's My Drive, not the real shared folders. Pilot on `/volume1/Server` (1.9 G) first. Pending: confirm in-scope share list, get go-ahead to execute. - **[PENDING] Watch for post-outage device stragglers.** Devices that booted during the 2026-06-17 DHCP-down window may have cached a disconnected state. Kitchen thermal printer resolved by power-cycle. Expect additional IoT/printer/POS reports; fix each by power-cycle. - **[PENDING] pfSense OpenVPN `--inactive` timeout fix.** Raise/disable the `--inactive` idle timeout (~300s) on the Cascades OpenVPN server profile. Proposed, not applied.