Skip to content

feat: surface every NextExplorer drive as external storage; 34.0.4:3 → 34.0.4:4 - #152

Merged
MattDHill merged 2 commits into
masterfrom
feat/nextexplorer-drives
Sep 19, 2026
Merged

MattDHill merged 2 commits into
masterfrom
feat/nextexplorer-drives

Conversation

@stupleb

@stupleb stupleb commented Sep 19, 2026

Copy link
Copy Markdown
Member

Summary

  • NextExplorer's volume root is a list of drives, and feat: surface NextExplorer as external storage; 34.0.4:1 → 34.0.4:3 #151 surfaces only Files. Its own Import Files from File Browser lands in a FileBrowser drive, and a service can be given a drive of its own (YTPTube does; qBittorrent lets you pick), so files a user was told would show up in Nextcloud never did.
  • Each top-level directory except _users and hidden ones now gets its own files_external entry: Files as /NextExplorer, the rest as /NextExplorer (<drive>). The rule mirrors upstream's getAllVolumes.
  • Only a drive that exists and that www-data can open gets an entry — Files included. NextExplorer creates Files on first start and the dependency is only exists, so feat: surface NextExplorer as external storage; 34.0.4:1 → 34.0.4:3 #151 surfaces an installed-but-never-started NextExplorer as a broken folder. That's the state of my test box, where a critical first-run task blocks the start.
  • Entries are matched by the directory they point at, so a folder renamed in Nextcloud's settings is kept, and one hand-pointed at _users is never treated as ours. An unreadable volume is never read as "no drives".
  • Mounts are created with files_external:import, so a restricted mount is born restricted instead of open to all users until a second command narrows it. Existing restrictions are changed as a diff rather than by opening the mount to everyone first; applicable groups are removed, and failed access or option updates retry on the next start. A failed files_external:list is a failure, not an empty list — that used to mean a twin of every entry.
  • Caps the NextExplorer range at >=2.2.7:0 && <4.0.0:0; documents that Nextcloud's scoping is the only access control on these files.

Verification

  • Docker, nextcloud:34.0.4-apache, driving the real reconcileExternalStorage through docker exec, 21 cases: never-started NextExplorer, Files appearing later, a feat: surface NextExplorer as external storage; 34.0.4:1 → 34.0.4:3 #151-era broken entry removed, a healthy feat: surface NextExplorer as external storage; 34.0.4:1 → 34.0.4:3 #151 install adopted with zero create/delete/--remove-all, drive renamed, admin-renamed entries, restricted users, unreadable volume, failed listing, foreign-uid drive, both sources, source cleared, hand-made _users entry untouched, File Browser-only signature unchanged.
  • StartOS 0.4.0.2, never-started NextExplorer with one service-made drive: only that drive surfaced, files_external:verify ok, a file written as www-data landed on disk as uid 1000, a plain restart ran no occ, restricting to one user kept the mount id, File Browser still mounts, clearing both removed every entry and no files.
  • Review follow-up: npm ci, npm run check, tsc --noEmit --noUnusedLocals, npm run build, Prettier, full make (x86_64 + aarch64), and Nextcloud 34.0.4 Docker checks of imported mount/user/group semantics.
  • Not verified on hardware: Files appearing after a first start.

Known limits

  • Drives are picked up at start, not live; a restart is needed after adding one.
  • A NextExplorer install reconciles once on upgrade (changes nothing when its mount is already right); File Browser-only installs keep their signature.
  • Release notes describe only :4, since :3 is on the production registry — say if you'd rather they accumulate.
  • Companion docs change: docs: tell Nextcloud users where imported files appear nextexplorer-startos#2.

stupleb and others added 2 commits September 19, 2026 15:36
…→ 34.0.4:4

NextExplorer's volume root is a list of drives, and #151 surfaced one of
them. Its own File Browser import lands in a `FileBrowser` drive, and a
service can be pointed at a drive of its own, so files a user was told
would show up in Nextcloud never did.

Each top-level directory other than `_users` and the hidden ones now gets
a `files_external` entry: `Files` as `/NextExplorer`, the rest as
`/NextExplorer (<drive>)`. The rule mirrors NextExplorer's own drive
listing. Only a drive that exists, and that www-data can open, gets one —
`Files` included. NextExplorer makes `Files` on its first start and the
dependency is only `exists`, so #151 surfaced a never-started NextExplorer
as a broken folder; that entry is now removed until the drive is there.

Drives are read with one `find` per start. The signature gains a `drives`
key only while a multi-drive source is selected, so every other install
keeps the signature it has; a NextExplorer install reconciles once on
upgrade and changes nothing when its mount is already right.

An entry is matched by the directory it points at, so a folder an admin
renamed in Nextcloud's settings is kept, and one pointed by hand at
`_users` is never taken for ours. An unreadable volume is never read as
"no drives": every entry is left alone and the signature unrecorded.

Mounts are now imported rather than created, so a restricted one is born
restricted instead of open to everyone until a second command narrows it,
and applicable users are left alone when already right, since re-applying
goes through `--remove-all`. A failed `files_external:list` is a failure,
not an empty list, which used to mean a twin of every entry.

Also caps the NextExplorer range below 4, and documents that Nextcloud's
scoping is the only access control on the mounted files.

Verified against nextcloud:34.0.4-apache in Docker by driving the real
reconcile through `docker exec`, 21 cases, then on StartOS 0.4.0.2 with a
NextExplorer that had never been started (no `Files`, one service-made
drive): only that drive surfaced, `files_external:verify` ok, a file
written as www-data landed on disk as uid 1000, a plain restart ran no
occ, restricting to one user kept the mount id, the File Browser source
still mounts, and clearing both removed every entry and no files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Track applicable groups as well as users, update restrictions without opening the mount globally, and leave the applied signature stale whenever an access or option command fails so the next start retries it. Only adopt local-storage entries that point at the expected drive.

Helix-Harness: pi
Helix-Model: openai-codex/gpt-5.6-sol

@helix-nine helix-nine left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The per-drive strategy matches NextExplorer’s volume model and preserves renamed Nextcloud mounts by identifying them from their backing directory. I pushed e3f6019 to make applicability exact: reconcile groups as well as users, change restrictions without a globally-open interval, retry failed access/option updates, and adopt only matching local-storage entries.

Verified with npm ci, TypeScript (including noUnusedLocals), ncc, Prettier, full x86_64/aarch64 package builds, and Nextcloud 34.0.4 Docker checks of import/list/applicable user/group semantics. CI is green for both architectures.

@MattDHill
MattDHill merged commit 4c62ed1 into master Sep 19, 2026
3 checks passed
@MattDHill
MattDHill deleted the feat/nextexplorer-drives branch September 19, 2026 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants