synology: full read-surface sweep + FileStation ls graceful fallback
Exercised every Web API + SSH read command live against cascadesDS. - All reads OK; `ls <folder>` (FileStation list) is 407-denied for the admin account on this box (confirmed on-box as SYSTEM_ADMIN) -> now catches the 400/407 and prints an SSH file-browse hint. `ls` share-roots still works. - SSH backend (info/df/run + privileged synowebapi) verified. - Documented MSYS path-mangling of bare `ls /path` arg on Windows. - SKILL.md: per-command results; flagged write/setter path as not-yet-live. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -110,19 +110,35 @@ 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.
|
VPN-down connect error surfaced to the user, a method refused for lack of --confirm) are NOT logged.
|
||||||
|
|
||||||
## Status / verification
|
## Status / verification
|
||||||
- **[VERIFIED 2026-06-25 — HOWARD-HOME, Cascades VPN up]** First live exercise against the device.
|
- **[VERIFIED 2026-06-25 — HOWARD-HOME, Cascades VPN up]** Full read-surface exercise against the
|
||||||
Confirmed working: auth (sid + synotoken CSRF), API discovery (`apis`), version-by-maxVersion
|
device. Device is **DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, serial 1920PEN537202**; ext4,
|
||||||
routing, and reads `test` / `storage` / `shares` / `packages` / `services` / `apis`. Device is
|
2x WD10EZEX 1 TB (volume1 913G, 43% used). 10 shares (incl. hidden `pacs`, `Activities`, `chat`,
|
||||||
**DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, serial 1920PEN537202**; ext4, 2x WD10EZEX 1 TB.
|
`Sandra Fish`); 30 packages running incl. **Active Backup for Business 3.1.0, Synology Drive
|
||||||
10 shares (incl. hidden `pacs`, `Activities`, `chat`, `Sandra Fish`); 30 packages running incl.
|
Server 3.5.0, Chat, VPN Server, Hybrid Share**. 41 users, 4 groups (administrators, http,
|
||||||
**Active Backup for Business 3.1.0, Synology Drive Server 3.5.0, Chat, VPN Server, Hybrid Share**.
|
MainOffice, users).
|
||||||
Session-expiry re-login (106/119), the mutating-verb gate, and the generic-error map are coded to
|
- **Command-by-command results (Web API):** `test` `apis` `sysinfo` `util` `storage` `shares`
|
||||||
spec but not yet exercised against a live write (no mutating call made yet — gate verified only by
|
`users` `groups` `packages` `services` `connections` `ls` (share roots) `call` — **all OK**.
|
||||||
the read path). Built originally from a 5-agent scan of the DSM 7 help tree + authoritative API
|
Auth (sid + synotoken CSRF), API discovery, version-by-maxVersion routing, and the generic `call`
|
||||||
sources (kwent `_full.json`, N4S4/synology-api, Synology Web API guides) — see `references/dsm-api.md`.
|
power-tool all confirmed live.
|
||||||
|
- **SSH backend (`syno-ssh.sh`):** `info` `df` `run` confirmed OK (incl. privileged `sudo -S` and
|
||||||
|
on-box `synowebapi --exec` at `/usr/syno/bin/synowebapi`). This is the path for real file browsing.
|
||||||
|
- **`ls <folder>` (FileStation `list`) is DENIED for the admin account on this box** — returns 407
|
||||||
|
on-box (SYSTEM_ADMIN) / 400 via Web API even for valid subfolders; the built-in admin lacks
|
||||||
|
FileStation file privileges. `ls` (no path / share roots via `list_share`) works fine. For actual
|
||||||
|
file/folder browsing use the SSH backend: `syno-ssh.sh run "ls -la /volume1/<share>/<subpath>"
|
||||||
|
--confirm`. (`ls <folder>` now catches this and prints the SSH hint.) Windows note: a bare
|
||||||
|
`ls /Public` arg is also rewritten by MSYS path-conversion — prefer `MSYS_NO_PATHCONV=1` or the
|
||||||
|
`call ... folder_path=/x` form, but the 407 denial blocks it regardless.
|
||||||
|
- **WRITE/SETTER PATH NOT YET EXERCISED LIVE.** Session-expiry re-login (106/119), the mutating-verb
|
||||||
|
gate, and read-modify-write setters are coded to spec but no mutating call has been made against
|
||||||
|
the device yet. Gate is verified only on the read path. First real change will confirm CSRF on a
|
||||||
|
write end-to-end.
|
||||||
|
- 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
|
- **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
|
DSM 7.2.1 — corrected to `get` (returns `{"service":[...]}`). `apis | head` raised a
|
||||||
`BrokenPipeError` traceback — now caught and exits cleanly.
|
`BrokenPipeError` traceback — now caught and exits cleanly. `ls <folder>` now degrades to an SSH
|
||||||
|
hint on the FileStation 400/407 denial.
|
||||||
- **DSM 7.2.x reboot/shutdown 103:** the Web-API `reboot`/`shutdown` can return error 103 on some
|
- **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`).
|
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
|
- **Param-schema caveat:** method names + versions in the reference are device-authoritative, but many
|
||||||
|
|||||||
@@ -338,8 +338,21 @@ def main(argv):
|
|||||||
_print(c.call("SYNO.Core.CurrentConnection", "list"))
|
_print(c.call("SYNO.Core.CurrentConnection", "list"))
|
||||||
elif args.cmd == "ls":
|
elif args.cmd == "ls":
|
||||||
if args.path:
|
if args.path:
|
||||||
_print(c.call("SYNO.FileStation.List", "list", folder_path=args.path,
|
try:
|
||||||
additional='["size","owner","time","perm"]'))
|
_print(c.call("SYNO.FileStation.List", "list", folder_path=args.path,
|
||||||
|
additional='["size","owner","time","perm"]'))
|
||||||
|
except SynoError as e:
|
||||||
|
# FileStation file-browsing (`list`) is denied for an account without
|
||||||
|
# FileStation file privileges -- on-box it is 407, surfaced here as 400.
|
||||||
|
# `list_share` (share roots) still works; for actual files use the SSH backend.
|
||||||
|
if " 400" in str(e) or " 407" in str(e):
|
||||||
|
raise SynoError(
|
||||||
|
f"{e}\n [HINT] FileStation file-listing is not permitted for this "
|
||||||
|
f"account (built-in admin lacks FileStation file privileges on this "
|
||||||
|
f"device). Use the SSH backend for real file browsing:\n"
|
||||||
|
f" bash .claude/skills/synology/scripts/syno-ssh.sh run "
|
||||||
|
f"\"ls -la /volume1/<share>/<subpath>\" --confirm")
|
||||||
|
raise
|
||||||
else:
|
else:
|
||||||
_print(c.call("SYNO.FileStation.List", "list_share",
|
_print(c.call("SYNO.FileStation.List", "list_share",
|
||||||
additional='["size","owner","perm"]'))
|
additional='["size","owner","perm"]'))
|
||||||
|
|||||||
44
errorlog.md
44
errorlog.md
@@ -17,6 +17,50 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure ·
|
|||||||
|
|
||||||
<!-- Append entries below this line -->
|
<!-- Append entries below this line -->
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology/ls | [friction] ls <path> arg mangled by MSYS path-conversion (/Public -> C:/Program Files/Git/Public) before Python sees it; FileStation list also 407-denied for admin anyway. Fix: use call folder_path=/x (= form not converted) or MSYS_NO_PATHCONV=1; real file browsing via SSH backend. [ctx: ref=feedback_tmp_path_windows os=windows]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology/ssh | syno-ssh recipe 'run' failed (rc=2) [ctx: host=192.168.0.120]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 401) [ctx: err={"code": 401}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.CheckExist.check failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.CheckExist.check failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list failed (code 103) [ctx: err={"code": 103}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.query failed (code 103) [ctx: err={"code": 103}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.get_service failed (code 103) [ctx: err={"code": 103}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list_service failed (code 103) [ctx: err={"code": 103}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.enum failed (code 103) [ctx: err={"code": 103}]
|
||||||
|
|
||||||
|
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list failed (code 103) [ctx: err={"code": 103}]
|
||||||
|
|
||||||
2026-06-25 | Howard-Home | bash/reachability-probe | [friction] /dev/tcp TCP probe falsely reported host DOWN on Windows MSYS while device was UP; wasted a cycle. Fix: don't trust /dev/tcp on Git-bash Windows for reachability — use the actual client (python urllib) or curl --max-time.
|
2026-06-25 | Howard-Home | bash/reachability-probe | [friction] /dev/tcp TCP probe falsely reported host DOWN on Windows MSYS while device was UP; wasted a cycle. Fix: don't trust /dev/tcp on Git-bash Windows for reachability — use the actual client (python urllib) or curl --max-time.
|
||||||
|
|
||||||
2026-06-25 | Howard-Home | synology | SYNO.Core.QuickConnect.get failed (code 103) [ctx: err={"code": 103}]
|
2026-06-25 | Howard-Home | synology | SYNO.Core.QuickConnect.get failed (code 103) [ctx: err={"code": 103}]
|
||||||
|
|||||||
Reference in New Issue
Block a user