puter icon indicating copy to clipboard operation
puter copied to clipboard

Local mountpoints

Open KernelDeimos opened this issue 1 year ago • 6 comments

The Concept

This is a feature I've wanted to add for some time. The idea is to be able to mount files from a directory in the host OS on a locally-running Puter instance. Currently self-hosted Puter will store files under UUIDs in a flat directory, and maintain the file hierarchy in the database, but this is not helpful if you want to - for example - access an existing media harddrive from within Puter.

The Hurdle

In Puter there are two ways to make reference to a file or directory:

  • by a path (/username/some/file.txt)
  • by a UUID (0fde43ca-6359-43b7-a48c-ab57e919b74a)

This is the behavior of UUIDs on Puter:

  • If you move a file or directory in Puter, it maintains the same UUID.
  • If you write to a file, it maintains the same UUID.

It is difficult to assign UUIDs to files on the host operating system. An inode number is the first candidate that comes to mind, but I just tried writing to a text file in Linux with vim and the inode number immediately changed.

Other notes:

  • ACL uses UUIDs, so if you move a directory to another location all the permissions are preserved. This is convenient.

Things we could do:

  • A mountpoint has a UUIDv5 namespace and we generate a UUID for each file/directory on the fly based on its... path? inode number?
  • Apply a UUID to a file upon discovery as an extended attribute
  • We could introduce path-based ACL
  • Add a cache to lookup a file by UUID (if it hasn't been discovered yet, this operation is still a full scan)

KernelDeimos avatar Apr 16 '24 01:04 KernelDeimos

@Reky69 I deleted your comment since it was just a blockquote of the explanation I wrote

KernelDeimos avatar Apr 16 '24 05:04 KernelDeimos

An inode number is the first candidate that comes to mind, but I just tried writing to a text file in Linux with vim and the inode number immediately changed.

Vim might not be directly writing to the file. If it writes to a temporary file, then deletes the original and renames the temporary (which I know some software does to avoid losing the original if the write fails) then it'd get a different inode I think. Everything I'm reading suggests inodes don't change because they're how symlinks work.

AtkinsSJ avatar Apr 16 '24 05:04 AtkinsSJ

That's accurate about vim, it writes a new inode from a "swap" file. Unfortunately the issue remains - conceptually (from the user's perspective) it's still the same file.

KernelDeimos avatar Apr 16 '24 06:04 KernelDeimos

Just some ideas, not sure if helpful:

  • may not be able to do better than full scan at first to assign your own id-per-logical-file (conceptual mirror of host inodes)
  • inode reuse on host could make them less than ideal as basis for your uuids (if host file is deleted, a subsequent file could take its inode/uuid)
  • is there a problem with having a directory with (in vim example): file.txt and .file.txt.swp in it (on both host and puter)?
  • what if you add a 3rd way to reference files outside of path and UUID, a special way just for 'host filesystems' - that way you can invent what you need and not worry about it being consistent with existing path/uuid (maybe that sounds too general? haha! :))?

i have no idea about any of this tho, so feel free to delete if not helpful it's ok!

crisdosaygo avatar Apr 16 '24 06:04 crisdosaygo

A big issue I can think about immediately is that puter apps are not necessarily same origin. I'm not sure if filehandles/folderhandles can be sent cross origin but I know they are transferable objects.

this would probably require something like comlink between the app and the main puter instance, if you plan on mixing local and remote files. I faced a similar issue but it was with worker communication instead of cross origin frames

ProgrammerIn-wonderland avatar Jul 28 '24 06:07 ProgrammerIn-wonderland

Moving forward I think the best way to implement this is by using the UUIDv5 of the path of the file or directory. The filesystem interface will provide a way for an implementer to specify its capabilities/nuances (am I case-sensitive? am I read-only? do I make my own UUIDs?), and in this way Puter's UI can respond differently when you move a file in a mounted filesystem that has permissions associated with it.

KernelDeimos avatar Jul 31 '24 00:07 KernelDeimos