Skip to content
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

nixos/dconf: Allow creating custom databases #54150

Closed
jtojnar opened this issue Jan 17, 2019 · 36 comments
Closed

nixos/dconf: Allow creating custom databases #54150

jtojnar opened this issue Jan 17, 2019 · 36 comments
Labels
0.kind: enhancement Add something new 6.topic: GNOME GNOME desktop environment and its underlying platform 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 9.needs: module (update) This needs a module to be changed

Comments

@jtojnar
Copy link
Member

jtojnar commented Jan 17, 2019

GLib’s GSettings system stores application settings in one of supported backends and uses compiled schemas (located in $XDG_DATA_DIRS/glib-2.0/schemas/gschemas.compiled) to determine type and default value of configuration keys. The schemas are compiled from XML files provided by applications and optionally, the default value can be changed by overrides.

Current situation

At the moment, we use GSettings overrides to declaratively change settings for GNOME & co., relying on the overridden default value. While this is great for non-important things like distribution-default background image, it suffers from many problems and inconveniences:

  • Since the compiled schemas are looked up in XDG_DATA_DIRS on first come, first served basis, we need to make sure our overrides are first in the chain. This is only possible by patching GLib.
  • Passing the NIX_GSETTINGS_OVERRIDES_DIR environment variable to applications is fragile. It does not really work for things like display managers, resulting in issues like GNOME keeps suspending on unstable #42053
  • It is easy to change a setting key in the user interface, breaking the overrides.
  • Compiling overridden schemas requires packages with matching XML definitions.
  • extraGSettingsOverrides option needs to be written in keyfile syntax, it would be much more convenient if we could use Nix syntax.

The goal of this issue is to attack the problem from the other side: modifying the backend.

Going through the backend

On Linux, the dconf backend is commonly used. It will select a profile pointing to a list of binary databases that are used for retrieving settings, see its overview for the gory details. Since the database is binary, the attrsets serialized into keyfiles will need to be compiled with dconf compile

Our dconf module can create profiles, which GDM module is incorrectly taking advantage of. In order to be able to configure application declaratively, we would also need to generate keyfiles and compile them to databases.

We probably do not want people to have to spell everything out

programs.dconf.profiles.user = pkgs.writeText "dconf-user-profile" ''
  user-db:user
  system-db:nixos
'';
programs.dconf.systemDatabases.nixos.system.proxy.http.host = "172.16.0.1";

It is not clear to me how should we handle locking – do we allow users to change the keys set through the module? Do we add lock control in the module?

Interesting links

cc @worldofpeace @hedning

@jtojnar jtojnar added 0.kind: enhancement Add something new 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: GNOME GNOME desktop environment and its underlying platform 9.needs: module (update) This needs a module to be changed labels Jan 17, 2019
@worldofpeace
Copy link
Contributor

It is not clear to me how should we handle locking – do we allow users to change the keys set through the module? Do we add lock control in the module?

I'd think if someone declared a key in the module that they'd want it to not change.

Though reading https://wiki.gnome.org/Projects/dconf/SystemAdministrators

Presently (as of dconf 0.7.4) lockdown is only supported on a per-key basis. Put another way: you may not yet lock entire subpaths. This is for performance reasons, but there are plans to address this in future releases.

So the lockdown feature needs improvement.

@jtojnar
Copy link
Member Author

jtojnar commented Jan 17, 2019

Though reading wiki.gnome.org/Projects/dconf/SystemAdministrators

Presently (as of dconf 0.7.4) lockdown is only supported on a per-key basis. Put another way: you may not yet lock entire subpaths. This is for performance reasons, but there are plans to address this in future releases.

So the lockdown feature needs improvement.

I do not think that would be an obstacle to

I'd think if someone declared a key in the module that they'd want it to not change.

It would be useful for things like setting the NixOS wallpaper, which we want to be overridable.

@jtojnar jtojnar mentioned this issue Jan 17, 2019
6 tasks
@hedning
Copy link
Contributor

hedning commented Jan 18, 2019

So working from the code snippet from @jtojnar there would be two ways of specifying locks I think:

programs.dconf.dbs.<name> = {
  settings.<key> = "foo";
  locks = [];
  # Perhaps something like this too:
  lock = false; # whether to lock all keys
};

or

programs.dconf.dbs.<name>.<key> = {
  value = "foo";
  lock = true;
};

I don't think keys should be locked by default, as it's easy to revert keys back in eg. dconf-editor. As such putting all the locks in a separate array seems fine (though I guess we could support keys that are strings _or attrsets).

At that point we could build gsettingsOverrides on top of the dbs config.

Not sure if there's much point in supporting more than one setting file per db?

@jtojnar
Copy link
Member Author

jtojnar commented Jan 18, 2019

Initially, I was thinking about having options like programs.dconf.dbs.<name>.org.gnome.desktop.background.picture-uri but that would make string + attrset ambiguous. <name>.<schema>.<key> would probably be better, albeit the presence of periods would mean having to quote the schema id: <name>."org.gnome.desktop.background".picture-uri.

Personally, I like your second example (with the possibility of using the value directly when not locking) better, since I do not need many locks and think that having them next to the key they are locking would be most clear. But I can imagine someone wanting to lock everything, which would not be very comfortable this way.

Also note that GSettings values are typed so we might need to serialize arbitrary GVariants.

Not sure if there's much point in supporting more than one setting file per db?

Perhaps if they came from a different source (network drive). I would not bother with that.

What we probably do want is the ability to specify name of the user-db. And maybe setting some extra file-db for special profiles like gdm.

@jtojnar
Copy link
Member Author

jtojnar commented Jan 18, 2019

Not sure if there's much point in supporting more than one setting file per db?

Actually each database corresponds to a single binary file. (And possibly multiple source keyfiles in <db>.d directory but they are irrelevant for us.) Did you mean to write about profiles?

Hmm, using file-db pointing to a generated DB in Nix store might even be cleaner than using system-db and generating the file somewhere in /etc.

@hedning
Copy link
Contributor

hedning commented Jan 18, 2019

And possibly multiple source keyfiles in .d directory but they are irrelevant for us

Was referring to the source keyfiles, I can't come up with a reason to support more than one either.

@hedning
Copy link
Contributor

hedning commented Jan 18, 2019

Personally, I like your second example

It does look cleaner, and perhaps optimal if we support strings and attrsets.

albeit the presence of periods would mean having to quote the schema id

It looks like the keyfiles use the schema path, not id. Ie. /, though that still needs to be quoted.

@jtojnar
Copy link
Member Author

jtojnar commented Jan 18, 2019

It looks like the keyfiles use the schema path, not id. Ie. /, though that still needs to be quoted.

Yeah, just realized that. dconf works on lower level so it cannot translate the ids. The benefit is that the keys are no longer demarcated.

@jtojnar
Copy link
Member Author

jtojnar commented Jun 26, 2019

There is now a pull request to create a dconf db in GDM module. If we could just generalize this.

@chkno
Copy link
Member

chkno commented Dec 20, 2019

Re: Per-value locks and mass-lock tedium: In the unlikely event that many locks are needed this seems easy enough to handle with mapAttrs (_: v: { value = v; lock = true; })

@chkno
Copy link
Member

chkno commented Dec 20, 2019

Please keep in mind list-valued configuration: Dconf does not support merging list-valued keys. At least two important Gnome settings are list-valued: /org/gnome/shell/enabled-extensions and /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings. For example, to enable two extensions a@a and b@b, this must be set to ['a@a','b@b']. It is quite hard for a@a and b@b to be added by different modules & end up with ['a@a','b@b'] at the end if dconf values are nix strings, but very easy if dconf values can be nix lists.

@jtojnar
Copy link
Member Author

jtojnar commented Jan 9, 2020

Yet another issue caused by NIX_GSETTINGS_OVERRIDES_DIR: When the overrides use older version of GTK schemas, it will crash newer GTK applications that require the new show-type-column key.

In the light of this and other issues like NIX_GSETTINGS_OVERRIDES_DIR not being composable (#64611), I would like to implement this even without the locks as an internal option subject to change and drop the gsettings overrides use in NixOS modules in favour of that. Until we decide the new options are stable, the extraGSettingsOverrides would still work but warn user about the issues and suggest to use either the internal option (subject to change) or home-manager.

I would like to base the new options on top of NixOS/rfcs#42 but its custom writer story needs to be improved first in order to allow us to implement the full support for GVariant-type system the dconf’s gvdb format uses.

I think the locks could be implemented on NixOS module level using something like mkLocked = content: { _type = "annotation:dconf-locked"; inherit content; }; and similarly for the types not supported by Nix mkTuple = values: { _type = "gvariant:tuple"; inherit content; };. Not sure if NixOS module system allows custom (how do you even call these?) fragment types. cc @infinisil

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Sep 14, 2021
@Artturin
Copy link
Member

Artturin commented Oct 1, 2021

using the formats.ini gets us close to making keyfiles (imo its fine like this afaik but we need to add '' manually)

  settings = {
    "org/gnome/settings-daemon/plugins/power" = {
      sleep-inactive-ac-type = "'nothing'";
    };
  };
[org/gnome/settings-daemon/plugins/power]
sleep-inactive-ac-type='nothing'

nix-build -E "with import <nixpkgs> {}; callPackage ./genfile.nix {}"

{ lib, stdenv, formats }:

let 
  settings = {
    "org/gnome/settings-daemon/plugins/power" = {
      sleep-inactive-ac-type = "'nothing'";
    };
  };
  settingsFormat = formats.ini { };
  configFile = settingsFormat.generate "custom.conf" settings;
in

stdenv.mkDerivation rec {
  pname = "something";
  version = "0.0.1";
  src = configFile;
  dontUnpack = true;
  installPhase = ''
  cp ${src} $out
  '';
}

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/desync-between-scalling-governeror-and-gnome-power-profile/16387/1

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/the-keyboard-layout-does-not-change-after-modifying-config/16666/14

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/linux-accessibility-an-unmaintained-mess/19126/4

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Nov 12, 2022
@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/need-help-for-nixos-gnome-scaling-settings/24590/5

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jan 11, 2023
@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/making-nixos-more-user-friendly-whats-needed/25567/6

@Alizter

This comment was marked as duplicate.

@linsui
Copy link
Contributor

linsui commented Aug 31, 2023

Since #234615 has been merged, can this be closed? What's the next step? Should we deprecate extraGSettingsOverrides?

@Thesola10
Copy link
Contributor

Fixed by #234615

@bam80
Copy link

bam80 commented Apr 27, 2024

Fixed by #234615

Not reflected in the https://nixos.org/manual/nixos/unstable/#sec-gnome-gsettings-overrides?

Overrides really only change the default values for GSettings keys so if you or an application changes the setting value, the value set by the override will be ignored. Until NixOS’s dconf module implements changing values, you will either need to keep that in mind and clear the setting from the backend using dconf reset command when that happens, or use the module from home-manager.

@bam80
Copy link

bam80 commented Apr 27, 2024

Since #234615 has been merged, can this be closed? What's the next step? Should we deprecate extraGSettingsOverrides?

Deprecate extraGSettingsOverrides in favor of what?
Sorry I couldn't find any documentation related to #234615

@JohnRTitor JohnRTitor added this to GNOME Jun 20, 2024
@JohnRTitor JohnRTitor moved this to To Do in GNOME Jun 20, 2024
@rudra-code-creator
Copy link

Should we deprecate extraGSettingsOverrides?

Yes. I think deprecating extraGSettingsOverrides is the goal. From my understanding

@jtojnar
Copy link
Member Author

jtojnar commented Jun 21, 2024

One thing that extraGSettingsOverrides does is schema validation. So ideally, we would have a high-level GSettings module, that checks provided settings against specified schemas. Edit: Opened #321438

Deprecation will also include writing docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: enhancement Add something new 6.topic: GNOME GNOME desktop environment and its underlying platform 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 9.needs: module (update) This needs a module to be changed
Projects
Status: To Do
Development

No branches or pull requests