feat: share clients — t=type manual mountpoint (existing path without create)
gates / consistency-and-conventions (push) Successful in 22s

User report: smb-client/nfs-client mountpoint step could only auto-suggest
candidates, or create a fresh dir behind a hidden 'n=new' key — no way to
type an arbitrary existing path as the mountpoint, so the manual option
was effectively invisible (candidates from /media etc. always populated
the picker, hiding the typing path entirely). Designer framing: capability
gap + discoverability gap; backend already handled arbitrary paths (CLI
cmd_mount + ensure_mountpoint), only the interactive menu blocked it.

Change (identical in bin/pos-share-smb-client and bin/pos-share-nfs-client):
- pick_mountpoint hint 'n=new' -> 't=type'; key arm n -> t
- ask_new_mountpoint generalized to ask_mountpoint: an existing
  directory is now used AS-IS (no create, no confirm); a non-existent
  path keeps the 'Create mountpoint?' confirm + sudo mkdir flow; existing
  non-directory rejected ('has a file there'); shape checks and system-path
  refusal unchanged; stream contract (display->stderr, path->stdout) kept
- menu_ask_mountpoint empty-candidate fall-through now routes through the
  same ask_mountpoint validator (single source of truth)

Docs: DOC/howto/share.md NFS+SMB mountpoint sections updated from n=new to
t=type and describe existing-path-without-create behavior.

Scoped to the two client files + howto doc; persistence/automount units,
unmount/remove flows, cmd_* CLIs, share_folder_candidates, and
lib/menu-lib.sh untouched.

Verified: 9-scenario smoke matrix x2 files (~19 assertions each: existing
dir as-is, new-dir confirm+create, decline, relative/trailing-slash/system/
empty rejections, non-dir reject, mkdir-fail), make gen idempotent, make
check OK, make lint 0 FAIL/0 WARN, make test 17 files / 299 checks green,
bash -n clean, git diff --check clean. Designer ACCEPT framing+spec;
Reviewer ACCEPT after doc fix.
This commit is contained in:
Your Name
2026-09-07 08:08:02 -04:00
parent 55a911fb37
commit 35eb90a58b
4 changed files with 54 additions and 37 deletions
+12 -9
View File
@@ -155,12 +155,13 @@ up — a down/unreachable NFS server can't break boot (with fstab it could).
(mount / persist / unmount / unpersist / list). Mountpoints are offered from
existing mount-layout candidates with manual entry as fallback — the picker
also accepts the server-side export path as a "(as on server)" pick when it
differs from your local layout, and `n=new` creates a fresh directory in
place (y/N confirmed; a failure just returns to the picker). Unmount lists
the active NFS mounts as `<mountpoint> ← <source>` picks and asks for
confirmation before unmounting (with a typed fallback when nothing is
mounted); unmount and unpersist tolerate already-absent targets instead of
erroring.
differs from your local layout, and `t=type` lets you type an absolute
mountpoint — an existing directory is used as-is, a non-existent path
creates it in place (y/N confirmed; a failure just returns to the picker).
Unmount lists the active NFS mounts as `<mountpoint> ← <source>` picks and
asks for confirmation before unmounting (with a typed fallback when nothing
is mounted); unmount and unpersist tolerate already-absent targets instead
of erroring.
**Troubleshooting:**
- "mount.nfs not found" → `nfs-common` isn't installed; `sudo apt install nfs-common`
@@ -292,9 +293,11 @@ fstab it could). `enable --now` arms the automount immediately.
an empty user tries guest enumeration first (with an auth retry on denial),
then shares and mountpoints are offered as pickers with manual fallback —
the account you authenticated with is reused for the mount. The mountpoint
picker accepts `n=new` to create a fresh directory in place (y/N confirmed;
a failure just returns to the picker); when the server is this machine, its
underlying share directory is offered as a "(as on server)" pick too.
picker accepts `t=type` to type an absolute mountpoint — an existing
directory is used as-is, a non-existent path creates it in place (y/N
confirmed; a failure just returns to the picker); when the server is this
machine, its underlying share directory is offered as a "(as on server)"
pick too.
Unmount lists the active CIFS mounts as `<mountpoint> ← <source>` picks and
asks for confirmation before unmounting (typed fallback when nothing is
mounted).