jvilk / BrowserFS

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.
Other
3.06k stars 215 forks source link

Support symlinks on core backends #268

Open pyramation opened 5 years ago

pyramation commented 5 years ago

I've been reading the docs and I'm under the impression that the core filesystems have symlinks?

I'm currently getting ENOTSUP not supported errors, so curious if there are any examples or pointers for getting symlinks to work, thanks!

pyramation commented 5 years ago

any one know how to create symlinks? Apparently they are readable, which is a good sign!

any help appreciated: https://stackoverflow.com/questions/55131565/how-to-create-a-symlink-within-browserfs

@jvilk 🙏🏻

jvilk commented 5 years ago

@pyramation I don't believe any backend currently supports symlinks. The basic abstraction is there should someone want to implement a backend that supports them, but I never got around to supporting them in the core backends.

pyramation commented 5 years ago

Thank you @jvilk!

Do you have an idea of how one could implement it for the Memory or LocalStorage backends? I'd be happy to dive in if there are some conceptual models for how to create the symlink.

I had one idea... I did look into potentially changing modes, and setting the contents manually. I found from this link that symlinks are mode 120000. I quickly realized I didn't know what the actual contents of a symlink look like, and couldn't find much info out there on the net or empirically in my shell (the OS wouldn't let me modify the mode of a sym link to turn it into a file and look at contents).

Any pointers on this thread are appreciated and I imagine would contribute to the creation of this feature ;)

jvilk commented 5 years ago

The contents of a symlink is the path to the file you're symlinking. So a symlink to ../foo will contain ../foo. It's symbolic, so if you delete ../foo and bring it back, your symlink will point to the new foo. If you rename ../foo, you'll have a broken symlink.

To implement symlinks, you'll need to somehow denote in the metadata of the file that it's a symlink (I think it's stashed in the mode as you suspect -- we stash file/dir in the mode as well), and then store it as a file with the contents of the symlink.

pyramation commented 5 years ago

Thanksd @jvilk ! I tried this out, and having issues editing mode. What's the best way to edit the mode or get into the metadata? I'm attempting to use chmodSync and getting ENOTSUP errors.

I'm trying to use chmod because If we try and write the mode on creation, we get issues because of umask, e.g.,

    fs.writeFileSync("value.txt", "hello world");
    fs.writeFileSync("alias", "./value.txt", {
      mode: 12000
    });
    console.log(fs.statSync("alias").mode.toString(8));

Which prints 127340 instead of 12000 because of UNIX permissions and umask, which makes sense. So in attempt to set mode after creation,

    fs.chmodSync("alias", 12000);

Then I get a nice not supported error: Error: ENOTSUP: Operation is not supported.

abhishiv commented 4 years ago

Hey @pyramation, did you manage to figure this out. I'm hitting the same problem.

Also, from the link that you posted should the mode change due to unix permissions for symlinks? It might make it easy to implement it If it doesn't.

In addition, on Linux systems you can't specify a symlink's permissions; all that matters is the target's permission (and effectively the full mode since that determines the symlink's behaviour too).

Also would readdir/readlink support symlinks automatically if we can figure this out? I think readdir might, but how would readlink know that it's a symlink if the mode changes? Does lstat help?

  /**
   * @return [Boolean] True if this item is a symbolic link (only valid through lstat)
   */
  public isSymbolicLink(): boolean {
    return (this.mode & 0xF000) === FileType.SYMLINK;
  }
pyramation commented 2 years ago

hey @abhishiv I don't think I ever got this working, nor did I see if there was work on it. Happy to see that more people want this feature, hopefully it can happen :)

james-pre commented 1 year ago

@pyramation

I'm attempting to use chmodSync and getting ENOTSUP errors.

chmod is supported with #334

If you do get it working a PR would definitely be welcome.

abhishiv commented 1 year ago

Hey @james-pre Has #334 been release? I'm on 1.4.3, and I still get ENOTSUP

EDIT: also doesn't work with 2.0.0

james-pre commented 1 year ago

@abhishiv #334 is merged. I'm currently working on getting NPM publish permissions from jvilk but for now it will have to be built from the main branch.

Note that #334 does not add symlinks (only chmod/chown support).

james-pre commented 1 year ago

Also, @abhishiv I plan on working on this after I get the internal API converted to promises. It is long overdue and something that should be relatively easy to implement.

james-pre commented 8 months ago

Please use https://github.com/browser-fs/core/issues/17