mpartel / bindfs

Mount a directory elsewhere with changed permissions.
https://bindfs.org/
GNU General Public License v2.0
449 stars 64 forks source link

[Feature] Bind files? #112

Closed DUOLabs333 closed 2 years ago

DUOLabs333 commented 2 years ago

Maybe it should be possible to bind files, like with mount --bind?

DUOLabs333 commented 2 years ago

It seems that it is not possible, as FUSE is for file systems.

AGI-chandler commented 10 months ago

Although it's rare, I have run into a couple situations now where bind-mounting a file has been a good solution.  Now, being able to do that without root has become needed.  I guess "mount can do it so why not?" really abstracts and simplifies the problem a bit too much, but I'm no expert on file systems or the inner workings of FUSE either...

Although, I'm not clear on what you mean by "FUSE is for file systems" because when I bind-mount a file, it appears as any other file system in the mount listing (including bind mounts on directories).  Would it really be impossible then to bind-mount a file with bindfs?

If so, do you happen to know of other solutions?  udevil also returned errors when I attempted.  The particular use case in this instance is a user needing to gather various files scattered across multiple file systems into a single git repo... if you have any ideas on that front, too...  Thanks!

DUOLabs333 commented 10 months ago

FUSE as an API, was designed for, and therefore only makes sense for, filesystems. This implies that there must be at least one directory. mount --bind uses some other API(s) that is/are not exposed to userspace.

If you only need separate files to be available, you could always use hard links.

AGI-chandler commented 10 months ago

Unfortunately, hard links only work within the same file system, and there are several involved in this case, multiple block devices and multiple NFS-mounts.

DUOLabs333 commented 10 months ago

For one of my projects, what I ended up doing was:

  1. Create a directory with just that file using a hardlink
  2. Mount the directory using bindfs (or in my case, unionfs, since it does the same thing, and has more features that I use)
  3. Symlink the file in the mounted directory to whereever you need it on the new FS.
  4. Profit.

It's not as clean as a single mount --bind, but since it was a part of a script, I could just "set and forget".

DUOLabs333 commented 10 months ago

The particular use case in this instance is a user needing to gather various files scattered across multiple file systems into a single git repo.

Why couldn't you use symlinks (I'm assuming you considered this)?

AGI-chandler commented 10 months ago

git doesn't follow symlinks

DUOLabs333 commented 10 months ago

Oh, didn't know that (kind of surprising though). Then yeah, you will basically have to create a directory for each FS, mount, then hardlink the files on the client.

AGI-chandler commented 10 months ago

hmm 🤔  Okay, so use bindfs to create a kind of staging area in ~/myGitStaging/ that would have bind mounts on sda1, sda2, nfs3, nfs4, and so on? Then use hard links on the individual files from there that are needed in ~/myGitRepo/?  That could work!  Thanks, I'll try it out!

DUOLabs333 commented 10 months ago

Yep!

AGI-chandler commented 10 months ago

Unfortunately, still getting the Invalid cross-device link error when try to link from the staging area to the git repo 😭  Any other ideas?

mpartel commented 10 months ago

Depending on your exact use case, --resolve-symlinks might help, but note that it's problematic when programs like some text editors delete and recreate files.

DUOLabs333 commented 10 months ago

If you're allowed to change where the files will be in the repo, you could just mount the directories into the repo itself and skip the hard links altogether.

AGI-chandler commented 10 months ago

Thanks guys... Yeah unfortunately --resolve-symlinks seems problematic and user would have to remember to take special care to only edit the file the symlink is pointing to.  Not sure I follow @DUOLabs333, the user has full control over the repo, but the idea is to have one dir such as ~/myRepo and several files within that are essentially linked to files across differing file systems, so either the source file or the file within the repo can be updated and the updates are reflected in both places. Having several directories in the repo won't work, plus we don't want/need to expose every item in the file system, so i suppose an extensive .gitignore would be needed in that case too.

Honestly, bind-mounted files would still work best... might have to just figure out how to grant a limited sudo access to the user, or create some systemd.mounts, but finding a way for the user to do it themselves would be ideal (since data is constantly changing), as well as something that is seamless and no different than working in a regular git repo...  Anyway, need to get to some other projects so shelving this for now...