neuromorph / openbar

A GNOME Shell extension for theming Gnome Top Bar / Top Panel, Menus, Dash/Dock, Gnome Shell and Gtk/Flatpak Apps.
https://extensions.gnome.org/extension/6580/open-bar/
GNU General Public License v3.0
269 stars 5 forks source link

Permission denied: Can't used Open Bar on an immutable OS #38

Closed balintbarna closed 4 months ago

balintbarna commented 5 months ago

I'm a NixOS user and install my gnome extensions with Home Manager, which means they are installed in a read only mount. When I try to enable Open Bar I get this error:

image

What it looks like to me is that open bar tries to open and modify the stylesheet in the installation location, which is illegal on an immutable OS. Is it trying to save changes in the install location?

neuromorph commented 5 months ago

Hello,

What it looks like to me is that open bar tries to open and modify the stylesheet in the installation location, which is illegal on an immutable OS. Is it trying to save changes in the install location?

You are right, OpenBar modifies the stylesheet.css of the extension as per the settings set by the user. It also modifies the 'switch' or 'checkbox' icons svg files inside the media sub-directory of the extension to match the current Accent color. It would thus need the write access to install location for it to work.

Just FYI, in the new upcoming version, there is also an option to style Gtk apps which require write access to ~/config/gtk3.0 and gtk4.0. That is only if gtk styling is desired.

I am not that familiar with immutable OS like NixOS but I suppose it would be possible to give the extension access to install location if you so wish.

Thank you for writing!

balintbarna commented 5 months ago

Hi @neuromorph thank you for your reply! The install location on immutable OSs is read only, that's what makes them immutable and also more reliable. The directory ~/.config is mutable and that's where most modern software put their configuration too. If open bar were to put its configuration there including the stylesheets and whatnot, it would work perfectly fine on immutable setups. Would you consider doing something like that? Also, thank you for putting all the work into this awesome project!

neuromorph commented 5 months ago

If open bar were to put its configuration there including the stylesheets and whatnot, it would work perfectly fine on immutable setups. Would you consider doing something like that?

That would be non-standard for an extension. Gnome installs everything including stylesheets into the install location and wipes the directory when extension is uninstalled. Technically, it may be possible to add such an option, similar to gtk css, by manually (through code) putting the css and media under config on enable and deleting it on disable. Gnome guidelines require cleaning up on every disable. However, such an option is not available now, nor in the upcoming release and also not sure if Gnome extension reviewer will be happy with it. Though, I may look into it later if more folks request it. BTW, some people have reported using Open Bar in NixOS but I don't know how they are going about it.

I will keep it open for now. Thank you for the suggestion.

Also, thank you for putting all the work into this awesome project!

Thanks! Hope you get to try the next update 'OpenBar 2.0'.

balintbarna commented 5 months ago

That would be non-standard for an extension. Gnome installs everything including stylesheets into the install location and wipes the directory when extension is uninstalled.

I didn't know that, not sure how it works with other extensions because this is the first time I'm running into this issue. Maybe they just save to dconf and modify the stylesheet in memory?

BTW, some people have reported using Open Bar in NixOS but I don't know how they are going about it.

There are ways to install things on NixOS outside of the read-only store I guess, but that kind of goes against the whole idea of it. Of course, it's not the end of the world to do it for a gnome extension :)

neuromorph commented 5 months ago

not sure how it works with other extensions because this is the first time I'm running into this issue. Maybe they just save to dconf and modify the stylesheet in memory?

Most extensions do not modify stylesheet at all, only ship a static one usually for the extension's own UI. For a minor or one-off widget, one could also directly style it without a stylesheet. Since this extension is designed to theme the Shell elements arbitrarily, it has to apply a dynamic stylesheet. I am not aware of any other extension that allow such dynamic styling with arbitrary colors/settings. Typically, for shell theming, an extension would generate a theme and require the user to compile it with something like sass and install it with tweaks. I wanted to avoid any installations and also wanted to apply it on top on any existing theme changing only the aspects selected in the OpenBar settings.

There are ways to install things on NixOS outside of the read-only store I guess, but that kind of goes against the whole idea of it. Of course, it's not the end of the world to do it for a gnome extension :)

True, I get the immutable OS thing though I was expecting some leeway to be there for it to be practical while being safe. About Gnome extension, the review process also prefers safety e.g. disallow any binaries, restrict too much subprocess use or unwanted permissions and they are open source. So, like you said, not the end of the world, esp. if you know what it's doing like writing to a stylesheet :)

balintbarna commented 5 months ago

I am not aware of any other extension that allow such dynamic styling with arbitrary colors/settings.

I use Dash to Panel and Blur My Shell, which both allow changing colors, transparency, etc. Dash to Panel is also an alternative status bar though with a different focus than Openbar. I don't know how they work internally, but I didn't run into any issues with these extensions.

True, I get the immutable OS thing though I was expecting some leeway to be there for it to be practical while being safe.

I would say it's got a lot of leeway. I can use Appimages, flatpaks, and even binaries compiled on other distros and those work just the same. Maybe I could just install gnome extensions the regular way but I much prefer using the package manager because of declarative configuration and all the benefits that come with that. The immutable OS is basically a collection of read-only packages handled by the package manager. If the packages could modify themselves you would lose reproducibility. The tech is really interesting.

neuromorph commented 5 months ago

I use Dash to Panel and Blur My Shell, which both allow changing colors, transparency, etc.

Good point, these are awesome extensions. Dash to Panel also uses static stylesheet for the most part and some inline style for dynamic styling. Open Bar started with inline style being assigned to each widget part but it became non-practical soon esp. also for event handling e.g. hover, focus, backdrop, disabled etc. Blur My Shell applies blur with transparency/color but not through css. Unfortunately, Gnome shell doesn't even support css blur. So BMS started with using the Gnome shell blur in Clutter but it also is very limited so they have moved on to writing custom GLSL shaders and combining with color or noise layers. Point being none of them need to write to the stylesheet so you may not have faced the issue.

Dash to Panel is also an alternative status bar though with a different focus than Openbar.

I was referring to Open Bar as in the new version now almost ready in 'openbar2.0' branch, just need to iron out some potential issues. That actually has options to style the entire shell and more. That's why it's more in line with building a custom shell theme vs. styling a widget and needs to go with applying stylesheets.

Maybe I could just install gnome extensions the regular way but I much prefer using the package manager because of declarative configuration and all the benefits that come with that.

I have heard about packaging the extension with declarative configuration, in fact a few people installed Open Bar on NixOS through such means but faced some error. They were able to get it to work when installed the regular way. I would like to know about how to package it for NixOS or how come there was a package in the first place but never got to it and I never used such an OS either.

The immutable OS is basically a collection of read-only packages handled by the package manager. If the packages could modify themselves you would lose reproducibility. The tech is really interesting.

For Open Bar, the stylesheet is more like an output of the package instead of the package itself. The reproducibility comes from rest of code and dconf settings. The content of the stylesheet are generated when the extension is enabled overwriting anything that it may originally had. So, the stylesheet does not affect the extension at all, it is an output of the extension which is loaded in the Gnome shell so that those styles are applied to the Gnome shell components. This may or may not be what exactly meant by package modifying itself but it is a helpful perspective. This is really interesting indeed!

balintbarna commented 5 months ago

This may or may not be what exactly meant by package modifying itself but it is a helpful perspective.

Yes, that’s what I meant. It sounds like the style sheet could be in a temporary location or in the cache directory if it’s regenerated anyway, right?

neuromorph commented 5 months ago

It sounds like the style sheet could be in a temporary location or in the cache directory if it’s regenerated anyway, right?

That makes sense. However, going back to our initial comments, Gnome would install and load it in the shell automatically only from the default install location. So, to make it work, I would need to add code to install/save in some other custom location on Enable and remove on Disable. (Side Note: enable/disable happens several times e.g. for every lock/logout). I will also need to load the stylesheet from that location. This should be doable, just not available currently or in the next upcoming version. I would look into it for future update if needed. Writing to stylesheet is also non-standard and not that efficient but I don't see a better option (only needed during config). Other than that I was trying to stay close to standard extension behavior as much possible. I would also not want people to miss on being able to use it so there's that as well :shrug:

You point is well taken . Let's see how it goes.

heywoodlh commented 5 months ago

Related, have been attempting to package this in nixpkgs: https://github.com/NixOS/nixpkgs/pull/320626

Hope I'm able to find a fix to this issue, but I suspect I'll be blocked by this.

jtojnar commented 5 months ago

I would say packages modifying their own source code is frowned upon in non-immutable distros as well. So loading the stylesheet on the fly like https://github.com/TomaszGasior/gnome-shell-user-stylesheet does is probably a good idea anyway.

neuromorph commented 5 months ago

Hello,

I would say packages modifying their own source code

This sounds like: say a particular version of Open Bar does precisely 'A', then it may modify itself such that it starts doing 'A*'. This is not the case. It will keep doing precisely the same thing, which is: Generate and load its stylesheet on the fly based on user selected configuration. User may change the configuration which would then lead to generation and reloading of new stylesheet. User may also opt for Auto-theming, wherein the stylesheet may get generated and reloaded with events like changing desktop background or Dark/Light mode. So a given version of the extension does not modify its 'source' or behavior by a bit. The stylesheet is an output generated by the extension as per user configuration.

So loading the stylesheet on the fly like https://github.com/TomaszGasior/gnome-shell-user-stylesheet does is probably a good idea anyway.

Stylesheet is already loaded on the fly, as many times as needed. The difference being it is also generated on the fly.

A suggestion in the above discussion was to move the stylesheet to '~/.config' instead of the extension's directory. Two points in that regard:

If all goes well, I will look into it, mainly so that nixpkgs can work with the extension. Though, I do not see any 'risky' or 'source modifying' behavior in this case.

Thanks!

jtojnar commented 5 months ago

So a given version of the extension does not modify its 'source' or behavior by a bit. The stylesheet is an output generated by the extension as per user configuration.

This is just semantics. The distinction between data/configuration and code can be a bit blurry sometimes but in this case, I would say it is pretty clear cut.

This sounds like: say a particular version of Open Bar does precisely 'A', then it may modify itself such that it starts doing 'A*'. This is not the case.

I would say this is precisely the case. Adjusting the Shell visuals is part of the extension’s behaviour, and the behaviour is changing based on the underlying configuration.

The stylesheet is an output generated by the extension as per user configuration.

If we consider it an output of the extension, all the more reason to evict it from the source directory.

Separation of code and data is important principle for security as well. This is why e.g. /usr is only meant to be written by root or why memory can have no-execute bit set. You will have exactly the same issue if other distros try to package it, because they will install it to (from the point of user running the extension) immutable /usr.

A suggestion in the above discussion was to move the stylesheet to '~/.config' instead of the extension's directory.

That directory is for configuration. Since the stylesheet is generated based on configuration, whatever we consider it, it cannot be itself configuration. It should go to one of the following XDG locations: cache dir, or preferably runtime dir.

It is non-standard for a Gnome extension to have the extension's stylesheet not in its directory. Gnome can automatically load the stylesheet on 'enable' when it follows standard path/name.

It is non-standard to modify the stylesheet too. Having it automatically load and unload is convenient but that does not make it correct.

neuromorph commented 5 months ago

I would say this is precisely the case. Adjusting the Shell visuals is part of the extension’s behaviour, and the behaviour is changing based on the underlying configuration.

There seems to be some misunderstanding. Adjusting the Shell visuals is the objective of the extension. It is a configurable extension where a user can decide how they want the extension to change the visuals. E.g. with 'Just Perfection', one can select what widgets to show or hide or with 'Blur My Shell' what components to add blur to with what sigma etc. Extensions are designed to modify the shell in some way and configurable extensions allow for flexibility to the user in how that's done. This does not mean the extension is changing its behavior in terms of what it's doing, the 'A' vs 'A*'.

If we consider it an output of the extension, all the more reason to evict it from the source directory.

I understand this point.

You will have exactly the same issue if other distros try to package it, because they will install it to (from the point of user running the extension) immutable /usr.

True. And this gave me some perspective. This extension is not designed to work that way from /usr. I have not considered packaging by distributions, only for the typical user install with gnome-extensions. Packaging for distros would need rethinking it.

That directory is for configuration. Since the stylesheet is generated based on configuration, whatever we consider it, it cannot be itself configuration.

Again, there is some confusion. Yes, the stylesheet is generated based on the extension's configuration and like you said we can consider it whatever but it is not itself configuration for the extension. But it can be configuration for the Shell similar to 'gtk-4.0.css' for Gtk (which goes in the same ~/.config path). That is the reason, I assumed, they suggested this location.

It is non-standard to modify the stylesheet too. Having it automatically load and unload is convenient but that does not make it correct.

Yes, I mentioned the same in a comment above - 'Writing to stylesheet is also non-standard' and not my preference either but applying stylesheet is the best way I found to style the shell. Having it automatically load and unload is a separate part and nothing wrong in it. The Gnome shell itself automatically loads and unloads extension stylesheets. The only issue is the stylesheet being written to a file (and also the assets SVGs being written). Rest everything is standard for extensions or also being done by Gnome shell itself. Earlier I thought writing in extension's install directory is an issue for NixOS and preferred location is ~/.config. However, it seems that may not be suitable as well so I will put a hold on going that way. I am also not inclined to move it to temp directories and not sure of what other issues it may bring in.

Keeping it open for now, any new suggestions are welcome.

jtojnar commented 5 months ago

@1amnotmad That’s weird. How are you installing it? It does not look like there is a Fedora package for openbar so you probably are not installing it through ostree-rpm. If you are installing it through e.g.o, I would expect it to end up in XDG_DATA_HOME, which I believe is mutable like on any other distro.

jtojnar commented 5 months ago

@neuromorph

There seems to be some misunderstanding. Adjusting the Shell visuals is the objective of the extension. It is a configurable extension where a user can decide how they want the extension to change the visuals. E.g. with 'Just Perfection', one can select what widgets to show or hide or with 'Blur My Shell' what components to add blur to with what sigma etc. Extensions are designed to modify the shell in some way and configurable extensions allow for flexibility to the user in how that's done. This does not mean the extension is changing its behavior in terms of what it's doing, the 'A' vs 'A*'.

I do understand how the extension works. I concede I used the term “behaviour” rather loosely. What I really meant is that while CSS is declarative and static compared to JavaScript, stylesheet.css is still code just like extension.js. GNOME Shell loads it and interprets it as given, and if you change the code, it is a different extension.

You have to generate a new stylesheet file because of the static nature of CSS (in before GNOME Shell implements CSS variables). You could similarly generate a new JavaScript module and load that but thanks to greater compositionality of JavaScript it would be less elegant method.

That directory is for configuration. Since the stylesheet is generated based on configuration, whatever we consider it, it cannot be itself configuration.

Again, there is some confusion. Yes, the stylesheet is generated based on the extension's configuration and like you said we can consider it whatever but it is not itself configuration for the extension. But it can be configuration for the Shell similar to 'gtk-4.0.css' for Gtk (which goes in the same ~/.config path). That is the reason, I assumed, they suggested this location.

I agree that it is not configuration for the extension. But calling it a configuration for Shell is a stretch too – you could just as well consider a Shell extension to be a configuration. And if it were that, it should go to ~/.config/gnome-shell anyway. Though main reason it cannot be considered Shell configuration is that Shell does not recognize the file unless told about it (or part of another extension).

I would say gtk-4.0.css is really an extension point masked as configuration. But at least GTK is aware of the path.

Yes, I mentioned the same in a comment above - 'Writing to stylesheet is also non-standard' and not my preference either but applying stylesheet is the best way I found to style the shell. Having it automatically load and unload is a separate part and nothing wrong in it. The Gnome shell itself automatically loads and unloads extension stylesheets. The only issue is the stylesheet being written to a file (and also the assets SVGs being written). Rest everything is standard for extensions or also being done by Gnome shell itself.

Yeah, I meant it more in way that stylesheet.css is normally immutable so it might be less confusing if we use different name/location. But that is pretty minor concern and will be resolved if we fix this anyway.

Earlier I thought writing in extension's install directory is an issue for NixOS and preferred location is ~/.config. However, it seems that may not be suitable as well so I will put a hold on going that way. I am also not inclined to move it to temp directories and not sure of what other issues it may bring in.

I think $XDG_RUNTIME_DIR/io.github.neuromorph.openbar is the most suitable directory for the files. Quoting from the Arch Wiki: “Used for non-essential, user-specific data files such as sockets, named pipes, etc.”

Temporary directory (including XDG_RUNTIME_DIR) would make leaving the file after extension uninstallation a non-issue. You would need to re-generate the file on every login but that is probably a good thing since it would allow you to not care about whether the file was generated by the current version of the extension – it would always be fresh.

1amnotmad commented 5 months ago

@jtojnar Apologies, meant to post this in https://github.com/neuromorph/openbar/issues/46 which is the issue I have ( errcode: 15). Will delete to clean up here so as not to cause confusion.

neuromorph commented 5 months ago

@jtojnar Thank you for your response and suggestion for going ahead! I will look into it soon.

@1amnotmad In reference to your earlier comment - it is on the cards to make it work with immutable package installations and the discussion here is helping to sort that out. Meanwhile you can continue with install from e.g.o. The fix for the other issue is available under the same (# 46) so hope that worked out as well.

heywoodlh commented 5 months ago

For NixOS, this is my current workaround with Home Manager to install the extension:

home.activation.gnome-extensions = ''
    ${pkgs.gnome-extensions-cli}/bin/gext install "openbar@neuromorph"
'';

(Since this is Home Manager, this works on non-NixOS, too)

And then all my configuration settings for openbar are codified in dconf. This allows me to codify my deployment, but still use OpenBar on immutable NixOS (albeit, I have to click the prompt to install the extension -- which is a bit of an anti-pattern).

neuromorph commented 5 months ago

Hi All,

I am working on it in the nixfix branch. I am trying the approach of moving the stylesheet and corresponding assets to $XDG_RUNTIME_DIR and an initial version is ready to test. I suppose it should be possible to create/install a package with it to test locally. If someone would like to try it out and provide feedback, that would be great.

Also, quoting from the XDG Base Dir Specification for $XDG_RUNTIME_DIR :

Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.

Will this be a potential issue? Should I be looking into setting the 'sticky' bit? The scenario is when a user has set their config for OpenBar, the stylesheet and SVG icons are created and saved here. Now they act as static files that will be loaded into and accessed from memory.

Thanks.

jtojnar commented 5 months ago

It really depends on how GNOME Shell handles the resources:

balintbarna commented 5 months ago

I suppose it should be possible to create/install a package with it to test locally. If someone would like to try it out and provide feedback, that would be great.

@neuromorph Thank you for looking into a fix so quickly! I never packaged anything for Nix but I will look into when I have the time unless someone else does it sooner.

heywoodlh commented 5 months ago

@balintbarna feel free to make suggestions here if you want: https://github.com/NixOS/nixpkgs/pull/320626

I will update my PR in a little while to use the nixfix branch and will report when I try it out on my NixOS machine.

heywoodlh commented 5 months ago

I'm happy to report that the latest commit (packaged in my openbar-init branch of nixpkgs) gets rid of the initial stylesheet.css issue!

Here's a screenshot of it happily working immediately after nixos-rebuild and a reboot:

image

I ran into one issue, though, after turning the extension off then back on: screenshot

(For anyone curious on how I'm consuming my branch in my nixos-configs flake, here is the commit: https://github.com/heywoodlh/nixos-configs/pull/10/commits/9a6fa5d6da4e1a85d3343855e72b40cee6e43bc4)

heywoodlh commented 5 months ago

Here are the permissions I have with the above file that is referenced in the above screenshot:

❯ stat /run/user/1000/io.github.neuromorph.openbar/assets/checkbox-off.svg
  File: /run/user/1000/io.github.neuromorph.openbar/assets/checkbox-off.svg
  Size: 474             Blocks: 8          IO Block: 4096   regular file
Device: 0,66    Inode: 184         Links: 1
Access: (0444/-r--r--r--)  Uid: ( 1000/heywoodlh)   Gid: (  100/   users)
Access: 2024-06-24 18:07:28.342998107 -0600
Modify: 1969-12-31 17:00:01.000000000 -0700
Change: 2024-06-24 18:07:28.342998107 -0600
Birth: 2024-06-24 18:07:28.342998107 -0600

It looks like all the files in that directory have permissions of 444 (owned by my user, though, so I can chmod it).

Is it on my end (i.e. something in NixOS) that's causing 444 permissions? I'm able to "fix" the issue by logging out and back in.

neuromorph commented 5 months ago

@heywoodlh

Thank you for trying out and providing feedback!!

It looks like all the files in that directory have permissions of 444 (owned by my user, though, so I can chmod it). Is it on my end (i.e. something in NixOS) that's causing 444 permissions? I'm able to "fix" the issue by logging out and back in.

FWIW, I am also currently using the install from nixfix branch, but on Ubuntu. In my case, the files' permissions remain at 664 even when the extension is turned Off and On.

jtojnar commented 5 months ago

/nix/store is read-only so you need to discard permissions when copying from it (example).

neuromorph commented 5 months ago

Thank you @jtojnar ! I have added a commit to keep the default target permissions when copying assets. @heywoodlh , can you please pull latest commit from nixfix and try with it?

Thanks.

balintbarna commented 5 months ago

@neuromorph I tested with the latest commit on your nixfix branch, it seems to work for the most part. There are a couple of bugs I ran into, such as not every setting triggers the style reload but most do, the bottom bar is halfway off screen, and a few similar ones, but that doesn't really seem related to the immutability issue. I think the fix worked. I'll keep using it for a bit and report back if anything breaks over time.

neuromorph commented 5 months ago

@balintbarna Thank you for the update!

Yes, those issues seem not to be related to immutability. Can you please log a separate bug for any such issue you may be facing? That will help to get more context and allow me to track and fix it. Thanks!

If there is an error about permissions or failed-to-load scenarios for stylesheet or SVG icons, that would likely be related to immutability (or its fix). That we can look into here and hopefully @heywoodlh will also have some feedback about the same when they get chance to try out.

balintbarna commented 5 months ago

Is the fix based on the 2.0 path or the main branch?

neuromorph commented 5 months ago

Is the fix based on the 2.0 path or the main branch?

If you mean the nixfix branch, it is based off of main. Or are you referring to any specific fix?

balintbarna commented 5 months ago

Ah good, then I guess it can soon be merged in and then the auto packager in nixpkgs will pull it in

neuromorph commented 5 months ago

Ah good, then I guess it can soon be merged in and then the auto packager in nixpkgs will pull it in

I believe the nixpkgs auto packager will pull it from e.g.o. after the next update is released.

Meanwhile, please let me know if you guys face any issues related to nixfix esp. if any "Crash" issues for the shell. Gnome shell can crash even with extension stylesheet access and loading/unloading e.g. here.

Once the switch is made, this will affect not only NixOS specific install but all the installs so I wanted to fix any issues before the release. I also thought of adding a toggle to switch between the two options but figured it could add unwanted issues for nixpkgs install or also if someone ends up with two stylesheets and their interference. So dropped the idea.

Thank you.

neuromorph commented 5 months ago

Update: The nixfix branch is now merged into main along with all the other fixes. So please install from the main branch for further tests.

Let me know if you face any issues. Thank you!

heywoodlh commented 4 months ago

Sorry for the delay, I'm testing right now and will push the latest commit soon to my PR in nixpkgs.

Will report back soon with my experience.

heywoodlh commented 4 months ago

Installed correctly and seems to be working for me as expected! Will likely repurpose my nixpkgs PR to ensure openbar is updated to the latest version using nixpkgs' automatic extension updating.

balintbarna commented 4 months ago

I’m closing this as it’s fixed, thank you all!