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/redshift: rework to use config file #50979

Closed
wants to merge 1 commit into from

Conversation

hyperfekt
Copy link
Contributor

@hyperfekt hyperfekt commented Nov 24, 2018

Motivation for this change

Redshift has some more options that are not reachable via the CLI (for example dawn-time and dusk-time) - this inspired me to rework the module to allow configuring it via the config file directly, automatically allowing users to take advantage of any options redshift might offer with a convenient (although less directly documented) interface while decreasing the burden of maintaining the module.

This is more of a proposal and not yet tested at all, I'd like to gather some input if this model is something that has a chance of getting merged at all, if there are any big improvements that could be made to it, any big problems I've overlooked etc.
Specifically I'd be interested in adding back some level of in-line documentation, implementing backwards-compatibility if wished and the most elegant way to check if an attribute is set (for the asserts) - that last one might interact with the first one; I've just put a placeholder for now, checking for null would obviously throw errors.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Assured whether relevant documentation is up to date
  • Fits CONTRIBUTING.md.

Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I like the config option in general, I'm not sure if it's fit for redshift, because there's not too many things you can configure anyways, and I can't find any docs on what options are supported in general (link me to it if there is). This combination makes it not very attractive to use such an unchecked, undocumented config option. Let me know if you have a good reason for it.

I introduced the same thing for #45470, but there ZNC has a lot of options, which are all documented well, and there are too many for NixOS, and they change a lot in addition, which wouldn't be very maintainable.

nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
nixos/modules/services/x11/redshift.nix Outdated Show resolved Hide resolved
between <literal>0.1</literal> and <literal>1.0</literal>.
'';
};
night = mkOption {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would have to introduce backwards compatible aliases for these removed options with mkAliasOptionModule

Copy link
Contributor Author

@hyperfekt hyperfekt Nov 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've chosen mkRenamedOptionModule in order to get people to migrate to the new configuration method in case the config file options change in a way that doesn't allow an alias in the future.

Your current latitude, between
<literal>-90.0</literal> and <literal>90.0</literal>. Must be provided
along with longitude.
Configuration to give to redshift.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description should be a lot longer, explain what this option does and how it can be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referring to man page now, I hope that's sufficient.

@infinisil
Copy link
Member

infinisil commented Nov 25, 2018

Ah and I just read the description again, you mention the problems with unset attributes and that you didn't test it yet, disregard my comments on that. You can check whether a nested attribute exists with:

foo.bar ? baz.qux

And this also works even when foo.bar doesn't have a baz:

foo.bar.baz.qux or "fallback value"

@hyperfekt
Copy link
Contributor Author

hyperfekt commented Nov 25, 2018

EDIT: Ignore this for now, I think I can use your approach in the ZNC module. Thanks for the pointer!

I can't find any docs on what options are supported in general

You're correct, unfortunately redshift does not provide any documentation for its config file. What do you think about leaving the existing options in place, but exposing the config file as an option (and realizing the existing ones through that in order to allow composition for any settings defined therein?

I'm not sure how to recreate the existing options with documentation though, since I can't set the configuration file options in the config part of the module, nor can I attach documentation with mkAliasOptionModule.

There would either need to be a way to further detail some of the attributes in the configuration file option, or we could manually merge a configuration generated by the other options and the configuration file option.

If neither of those is a good option, we could leave them implemented as command line arguments and leave redshift to handle any collisions, but that seems highly suboptimal. I think I'll attempt the second method for now unless you have good idea on getting the first one to work.

@infinisil
Copy link
Member

One of the main motivations for the config option for ZNC was that there isn't the need anymore to maintain docs in NixOS. Docs should be part of the package and if redshift doesn't have that then it should be fixed on the redshift side imo.

@hyperfekt
Copy link
Contributor Author

hyperfekt commented Nov 27, 2018

It turns out that redshift, contrary to several statements on the web, actually has a complete documentation for the config file: It can be found on the man page.
As a result, I've referred to that as documentation for the config option and gone ahead with the change without providing any further documentation for individual options.
If you'd still like me to reduce the abstractions in the assertions, I can do that.

@xaverdh
Copy link
Contributor

xaverdh commented Mar 24, 2019

Just noticed this pull request.
You may be interested in #57975.

@infinisil
Copy link
Member

Btw I've since opened an RFC for such config options: NixOS/rfcs#42

@hyperfekt
Copy link
Contributor Author

Wow, I only just noticed I never removed the [WIP] tag. -_-

@hyperfekt hyperfekt changed the title [WIP] nixos/redshift: rework to use config file nixos/redshift: rework to use config file Mar 30, 2019
@hyperfekt
Copy link
Contributor Author

hyperfekt commented Mar 31, 2019

This is ultimately up to @infinisil (and the RFC, I guess); but the way @xaverdh did it in #57975 a collision between a module-provided option and a config attribute set option will have the latter silently overwrite the former instead of failing like I think it should.
I've integrated the earlier target for the drm method here, I wasn't sure how to test that but I assume @xaverdh did so.

@infinisil
Copy link
Member

#64309 is very relevant for this and almost in shape to be merged, this PR will need some adjustments after that. Pinging @eadwu as well

@hyperfekt
Copy link
Contributor Author

hyperfekt commented Sep 30, 2019

Adjusted accordingly. Thanks for the help.

also uses an earlier target for the drm adjustment method,
and allows using dawn / dusk time even if a location provider is set
apply = c:
if !(c ? redshift.dawn-time || c ? redshift.dusk-time) && !(c ? redshift.location-provider) && options.locations.provider.isDefined then
c // {
redshift.location-provider = lcfg.provider;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This clears all other redshift.* keys, you need to use recursiveUpdate instead

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And location.provider is always defined because it has a default, also c ? dawn-time == c ? dusk-time as per assertion, so this can be

c: if ! c ? redshift.dawn-time && ! c ? redshift.location-provider
  then recursiveUpdate c {
    redshift.location-provider = lcfg.provider;
  } else c

} ];

services.redshift.settings.manual = {
lat = mkIf options.location.latitude.isDefined lcfg.latitude;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be something like

let
  needsLocationProvider = ! cfg.settings ? redshift.dawn-time;
in mkIf (needsLocationProvider && lcfg.provider == "manual") {
  lat = lcfg.latitude;
  lon = lcfg.longitude;
}

Setting lcfg == "manual" should force the user to set longitude and latitude if it's needed. isDefined doesn't do that.


assertions = mkIf (cfg.configFile == generatedConfig) [ {
assertion = (cfg.settings ? redshift.dawn-time) == (cfg.settings ? redshift.dusk-time);
message = "Time of dawn and time of dusk must be provided together.";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertion message should also mention that this is about redshift

services.redshift.configFile = mkDefault generatedConfig;

assertions = mkIf (cfg.configFile == generatedConfig) [ {
assertion = (cfg.settings ? redshift.dawn-time) == (cfg.settings ? redshift.dusk-time);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No parens needed

'';
};
settings = mkOption {
type = with types; attrsOf (attrsOf (nullOr (oneOf [ str float bool int ])));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toINI doesn't seem to support floats yet. And you should either remove nullOr or make sure null results in nothing being generated.

default = {};
description = ''
The configuration to pass to redshift.
See <command>man redshift</command> under the section
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the nasty syntax for man pages: <citerefentry><refentrytitle>redshift</refentrytitle><manvolnum>1</manvolnum></citerefentry>

<option>settings</option> option instead.
</para>
<para>
Setting this option will override any configuration file auto-generated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be disallowed by assertion? Allowing a settings object that's going to have no effect since it's overridden adds potential for confusion but little value, doesn't it?

@xaverdh
Copy link
Contributor

xaverdh commented Aug 22, 2020

friendly ping (is somebody still working on this?)

@hyperfekt
Copy link
Contributor Author

Thanks for the ping, I was waiting on RFC 42 but the code seems to have been merged a week ago! Will get it into shape when I find the time.

@infinisil
Copy link
Member

Note that the two relevant PR's are #75584 and #82743 :)

@xaverdh
Copy link
Contributor

xaverdh commented Jan 7, 2021

@hyperfekt are you still working on this?
(people started implementing this again in #108625)

@stale
Copy link

stale bot commented Jul 21, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 21, 2021
@Lassulus
Copy link
Member

seems like the other PRs were abandoned. Do you want to continue this?

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Apr 11, 2022
@Artturin Artturin closed this May 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants