Skip to content

Support copy-on-write to use installed firefox runtime #214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JJRcop opened this issue Sep 14, 2022 · 12 comments
Closed

Support copy-on-write to use installed firefox runtime #214

JJRcop opened this issue Sep 14, 2022 · 12 comments
Labels
enhancement New feature or request
Milestone

Comments

@JJRcop
Copy link
Contributor

JJRcop commented Sep 14, 2022

Problem Description

You must more or less install Firefox again to use this extension, maintaining two versions of it rather than only one.

Proposed Solution

Support some form of union mounting/CoW mount/overlayfs on platforms that support it, and offer to use the installed Firefox runtime instead of downloading another one.

This would mount the installed Firefox runtime into $XDG_DATA_HOME/firefoxpwa/runtime or $HOME/.local/share/firefoxpwa/runtime like it currently uses when installing a new runtime, but using a union mount or similar technology to patch the runtime, so that the original firefox runtime is untouched, but viewing the runtime within the union mounted directory shows a patched version.

Additional Information

This may need to be unmounted then cleared and re-patched/remounted when an update is detected.
I don't consider myself skilled enough yet, especially not in Rust, to do this myself at this time.

I am doing this myself manually using fuse-overlayfs, and in my experience it works great, especially since the runtime patching is not so big. Recently I did have a problem after an update, but clearing out the folder and restarting the mount worked great after re-patching.

@JJRcop JJRcop added the enhancement New feature or request label Sep 14, 2022
@filips123 filips123 moved this to To Do in PWAsForFirefox Sep 18, 2022
@MenacingPerson
Copy link

MenacingPerson commented Oct 30, 2022

Windows and Mac support :/

@JJRcop
Copy link
Contributor Author

JJRcop commented Jul 20, 2023

I have created a systemd mount file that uses fuse-overlayfs. (Available in Debian and derivatives, Fedora, Arch, and Gentoo)

firefoxpwa-runtime-overlayfs.service

I feel this could easily be added to the project, and users could be provided with the means to automatically install it by clicking a button, at least on systemd-enabled systems.

@filips123
Copy link
Owner

This needs to be done once (per user) and it will automatically mount FUSE each time the user logs in, right? If so, this is quite nice and shouldn't be hard to add. I'll probably add some option to automatically set up this in the coming weeks.

@JJRcop
Copy link
Contributor Author

JJRcop commented Jul 20, 2023

Yeah once per user, then it's automatic every time they log in. If added as an option, it should automatically enable "Always patch profile and runtime" then lock it out from being changed while enabled.

Also, I noticed that for example openSUSE has the Firefox runtime under /usr/lib64/firefox. So, if added that path should be configurable by the user, which will then be changed in the unit file under AssertPathIsDirectory= and lowerdir=. (Like with a chooser dialog to select the installed firefox runtime path)

EDIT: And finally, if you are using this already: I found a bug where sometimes when shutting down your pc the mount could get corrupted on next boot, requiring a remount. This is fixed by adding LazyUnmount=yes, which I have done just now.

@JJRcop
Copy link
Contributor Author

JJRcop commented Jul 21, 2023

I just edited everything to be a .service unit instead. With FUSE it's more robust to use the FUSE tools rather than the mount and umount programs like .mount units do.

firefoxpwa-runtime-overlayfs.service

[Unit]
Description=FirefoxPWA overlayfs to use installed Firefox runtime
AssertPathIsDirectory=%%runtime_path

[Service]
Type=simple
ExecStart=fuse-overlayfs -f -o squash_to_uid=%U,squash_to_gid=%G,lowerdir=%%runtime_path,upperdir=%t/firefoxpwa/overlayfs/upper,workdir=%t/firefoxpwa/overlayfs/work %h/.local/share/firefoxpwa/runtime/
ExecStop=fusermount -u %h/.local/share/firefoxpwa/runtime/
RuntimeDirectory=firefoxpwa/overlayfs firefoxpwa/overlayfs/upper firefoxpwa/overlayfs/work

[Install]
WantedBy=default.target

%%runtime_path should be replaced with the installed Firefox runtime path (like /usr/lib/firefox(-esr)) before use.
More detailed install instructions are in the Gist.

@filips123
Copy link
Owner

I think that for now, I will just add instructions (based on your gist) for setting up OverlayFS to the documentation website and link them from the extension.

For a completely automated setup, the program would also need to detect distro and install fuse-overlayfs, detect if systemd is used, the source Firefox patch, etc., which could make it quite complicated. Also, additional handling would need to be added when Firefox is installed as Flatpak or Snap (once Flatpak starts supporting native messaging).

As will probably get used OverlayFS by more "advanced" users, they likely won't have problems with following the setup instructions. In the future, I might still make this more automated if I find a good way to do it.

@filips123 filips123 moved this from To Do to In Progress in PWAsForFirefox Sep 25, 2023
@filips123 filips123 modified the milestones: 3.0.0, 2.8.0 Sep 25, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in PWAsForFirefox Sep 25, 2023
@JJRcop
Copy link
Contributor Author

JJRcop commented Sep 25, 2023

I was going to post this a few months ago but I forgot, sorry.

You don't really need a systemd unit to do this if implemented in the native component, as the native component can just run fuse-overlayfs itself with the required arguments, and also unmount it by running the unmount command in my gist instructions (actually, killing the fuse-overlayfs process works just as well, and you will probably get the PID of it if you are the one to launch it). No systemd stuff required at all, only fuse-overlayfs (and fuse as well, of course).

A button could be added to enable this, but instruct users to install fuse-overlayfs through their distro's package manager if it's missing, then otherwise handle everything for fuse-overlayfs directly

@filips123
Copy link
Owner

as the native component can just run fuse-overlayfs itself with the required arguments

This could be run when the web app is launched (if the runtime isn't already mounted), right? And for unmounting, would it work to just let the OS clean everything on logout?

I might try to do this in the future. I plan to create a biger release with quite a lot of rewritten stuff at some point, including how runtime and profile patching is handled, so this could probably be done then. However, I don't know when this release will happen as I don't have much time currently.

@JJRcop
Copy link
Contributor Author

JJRcop commented Sep 25, 2023

This could be run when the web app is launched (if the runtime isn't already mounted), right?

Yeah, that's fine. It doesn't need to be mounted until it's needed anyway.

And for unmounting, would it work to just let the OS clean everything on logout?

For most systems in default configurations, yeah it should be fine. If you want, you can just delete the upper and work directories when mounting if they already exist and remake them so they are empty.

@JJRcop
Copy link
Contributor Author

JJRcop commented Sep 25, 2023

Also, if you SIGKILL the fuse-overlayfs process it doesn't properly shutdown the mount, however if you SIGTERM it does.

@filips123
Copy link
Owner

So, will the system shutdown/logout properly shutdown the mount?

It could be quite hard to track when any web apps are open and properly stop the mount after they are closed. So, if the OS won't properly unmount in on logout, it might still be easier to just add an option to automatically create a systemd service that handles everything.

@JJRcop
Copy link
Contributor Author

JJRcop commented Sep 26, 2023

So, will the system shutdown/logout properly shutdown the mount?

I just tested this, and yes it does. Shutdown or Logout sends SIGTERM to all open processes which means fuse-overlayfs will shutdown the mount properly.

So, what you can do is as you said, have the native component launch fuse-overlayfs if enabled and the runtime isn't already mounted, then leave cleanup of the mount to the OS.

Now, the mount will be cleaned up but the work/ and upper/ directories won't necessarily be (specifically on Logout they persist, but on Shutdown or Restart the entire /run directory is cleared), so these directories should be deleted by the native component if it's about to launch fuse-overlayfs but finds those directories already exist, then recreate them for a fresh slate.

No need to concern yourself with tracking open web apps, just worry logically about mounting the runtime with fuse-overlayfs if it isn't mounted and that feature is enabled. Also if that feature is enabled, "Always patch runtime" should also be implied

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

No branches or pull requests

3 participants