-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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: make it easy to apply kernel patches #15095
Conversation
By analyzing the blame information on this pull request, we identified @thoughtpolice, @edolstra and @shlevy to be potential reviewers |
d0cc79c
to
a618189
Compare
@henrytill maybe good for musnix? |
I'm tempted to factor out the recursive bits into something reusable. Would something like this in # Compose two extension functions:
#
# nix-repl> h = self: super: { bar = "<${super.bar}>"; }
#
# nix-repl> fix (extends (composeExtensions h g) f)
# { bar = "<bar>"; foo = "foo + "; foobar = "foo + <bar>"; }
composeExtensions = f: g: self: super:
let attrs = g self super;
super' = super // attrs;
in attrs // f self super';
# Create an overridable, recursive attribute set. For example:
#
# nix-repl> obj = makeObject (self: { })
#
# nix-repl> obj
# { override = «lambda»; }
#
# nix-repl> obj = obj.override (self: super: { foo = "foo"; })
#
# nix-repl> obj
# { foo = "foo"; override = «lambda»; }
#
# nix-repl> obj = obj.override (self: super: { foo = super.foo + " + "; bar = "bar"; foobar =
# self.foo + self.bar; })
#
# nix-repl> obj
# { bar = "bar"; foo = "foo + "; foobar = "foo + bar"; override = «lambda»; }
makeObject = f:
let
construct = overrides: self:
let
override = f:
let overrides' = composeExtensions f overrides;
in fix (extends overrides' (construct overrides'));
in f self // { inherit override; };
in fix (construct (self: super: {})); |
I pushed up a second commit that shows what this would look like with the recursive bits factored out. What do you think? I'd like some feedback before this gets merged. |
c7fc7eb
to
3f99906
Compare
Actually, I suppose this would be a better/leaner implementation of the the makeObject = rattrs:
let
construct = rattrs:
fix (self: rattrs self // {
override = f: construct (extends f rattrs);
});
in construct rattrs; |
cbd0a18
to
aacb684
Compare
@dezgeg What are your thoughts on the |
Does {
boot.kernelPackages = with pkgs;
let self = linuxPackagesFor (kernel.override { kernelPatches = [ /* ... */ ]; }) self; in self;
} not accomplish the same thing? |
That can definitely work, however:
As an example, when we want to extend/override Haskell packages, we aren't required to re-implement I believe this PR makes things compose better and makes the kernel packages extensible without leaking knowledge of the implementation details into your configuration. |
This interface is better, no doubt about it. I'm not convinced composing kernel patches like this is really sane, but it is quite user unfriendly to do it at all right now, so ... |
override = f: construct (extends f rattrs); | ||
}); | ||
in construct rattrs; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Off topic: but we should make a fix.nix
/combinator.nix
/etc for all these. It's getting rather presumptuous to have all this is trivial.nix
. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's not looking so trivial anymore :). I can move things around, if we so wish.
Right - the more patches you throw in, the greater the chance that one of the patches won't apply (or worse, will apply, but will be buggy). For the simple, 99.9% case where someone just wants to add their patches to the default And, of course, having a way to add packages to the set of |
linuxPackages_4_3 = recurseIntoAttrs (self.linuxPackagesFor self.linux_4_3); | ||
linuxPackages_4_4 = recurseIntoAttrs (self.linuxPackagesFor self.linux_4_4); | ||
linuxPackages_4_5 = recurseIntoAttrs (self.linuxPackagesFor self.linux_4_5); | ||
linuxPackages_testing = recurseIntoAttrs (self.linuxPackagesFor self.linux_testing); | ||
linuxPackages_custom = {version, src, configfile}: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn that's some crazy indenting. IIUC our style these days + removing unneeded bindings would make it more like:
let # the `let` is just for syntax highlighting
linuxPackages_custom = {version, src, configfile}:
recurseIntoAttrs (self.linuxPackagesFor (self.linuxManualConfig {
inherit version src configfile;
allowImportFromDerivation = true;
}));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to keep the diff easy to view, but I suppose I could also reformat things. I think I'd prefer to do that in a separate PR, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah there's "we're touching the lines anyways" on one and and "PR mission creep" on the other.
Big +1 from me! I think in a follow-up PR it should be fairly straightforward to deal with with the multiple |
@Ericson2314 Thanks for reviewing :) |
I see a potential problem regarding the above definitions of
To address that last point, I'm thinking that That also happens to resolve the first point, but that does make me wonder about how combinations of Option 1 - don't preserve extensions when overriding
Note how in Option 2 - do preserve extensions when overriding
Note how in TL;DR I think I'd like to have the second @Ericson2314 How does that sound? |
I rebased on top of the tip of master and made some of the suggested changes. I chose the word "extensible" (e.g. in
@domenkozar How does this look now? If the changes look good, I can add docs in |
I won't have time to look at this this week, but noone else does, I'll do my best next week. |
071d71d
to
89e62c9
Compare
@domenkozar Any chance you'll have some free time to take a look at this? 😄 |
This makes it easy to specify kernel patches: boot.kernelPatches = [ pkgs.kernelPatches.ubuntu_fan_4_4 ]; To make the `boot.kernelPatches` option possible, this also makes it easy to extend and/or modify the kernel packages within a linuxPackages set. For example: pkgs.linuxPackages.extend (self: super: { kernel = super.kernel.override { kernelPatches = super.kernel.kernelPatches ++ [ pkgs.kernelPatches.ubuntu_fan_4_4 ]; }; });
89e62c9
to
d1030ef
Compare
@cstrahan after 16.09 :) |
Understandable, though it would be nice to have 16.09 :) |
Agreed, but it's going to be released tomorrow so that ship is already gone. We can talk about backporting once it's stable enough in the master branch. |
Besides the merge conflict, this is ready now? I'm very interested in seeing this merged :) |
Good job, @cstrahan rebase and merge :) |
# nix-repl> obj | ||
# { __unfix__ = «lambda»; bar = "bar"; extend = «lambda»; foo = "foo + "; foobar = "foo + bar"; } | ||
makeExtensible = rattrs: | ||
fix' rattrs // { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be plain fix
? Will work either way
@@ -21,6 +23,11 @@ in | |||
|
|||
boot.kernelPackages = mkOption { | |||
default = pkgs.linuxPackages; | |||
apply = kernelPackages: kernelPackages.override (self: super: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be .extend
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, yikes. Yes -- thanks for catching that. Didn't catch that after the renaming override
to extend
.
@@ -11419,121 +11419,123 @@ in | |||
for a specific kernel. This function can then be called for | |||
whatever kernel you're using. */ | |||
|
|||
linuxPackagesFor = kernel: self: let callPackage = newScope self; in rec { | |||
linuxPackagesFor = kernel: lib.makeExtensible (self: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Come to think of it, we could just do (self: with self; {
and cut down a lot of the diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not opposed to that.
I did my changes and rebased in https://github.com/Ericson2314/nixpkgs/tree/kernel-patches |
@Ericson2314 If you'd like to correct that broken reference to Alternatively, I have a deployment to tend to tonight, and I'll either have time much later tonight, or I can try to push this up tomorrow. |
@cstrahan I would do the honors, but I don't have push :). There's no rush so tomorrow is fine. |
Eh, I just went ahead and got it out of the way -- it only took a minute or two to rebase. |
|
||
acpi_call = callPackage ../os-specific/linux/acpi-call {}; | ||
acpi_call = self.callPackage ../os-specific/linux/acpi-call {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer if this line could be read as super.callPackage
, in order to avoid mistakes while using the overlays.
It seems pretty ad hoc to have an option for applying patches to the kernel. Why not add an option for applying patches to Firefox, or any of the thousands of packages in Nixpkgs? This opens the door for a huge amount of option bloat. |
@edolstra I believe it is because Linux already was exposing parameters for patches, unlike most packages? This old PR merely reexposes that parameter on the NixOS level. |
Things done
(nix.useSandbox on NixOS,
or option
build-use-sandbox
innix.conf
on non-NixOS)
nix-shell -p nox --run "nox-review wip"
./result/bin/
)This makes it easy to specify kernel patches:
To make the
boot.kernelPatches
option possible, this also makes it easyoverride the kernel and/or packages within a linuxPackages set. For
example:
For additional context, you can read my letter to the mailing list: http://lists.science.uu.nl/pipermail/nix-dev/2016-May/020342.html
/cc @thoughtpolice @nshalman