puter
puter copied to clipboard
Local mountpoints
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)
@Reky69 I deleted your comment since it was just a blockquote of the explanation I wrote
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.
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.
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.txtand.file.txt.swpin 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!
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
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.