|
|
| (11 intermediate revisions by 8 users not shown) |
| Line 1: |
Line 1: |
| | {{FAQ/breadcrumb}} |
| It is possible (and indeed, fairly easy) to pin a specific version of | | It is possible (and indeed, fairly easy) to pin a specific version of |
| Nixpkgs. This can be used to upgrade individual applications | | Nixpkgs. This can be used to upgrade individual applications |
| Line 4: |
Line 5: |
| not impacted by other systems' requirements. | | not impacted by other systems' requirements. |
|
| |
|
| == Pinning an unstable service ==
| | Another reason why one would want to pin nixpkgs is to get older versions of a specific software. [https://lazamar.co.uk/nix-versions/ This site] can show you all the versions a package went through, and what nixpkgs revision to use to get your specific version. |
| How to upgrade a single package and service to an unstable version
| |
| | |
| There is probably a better way, especially once flakes comes around. Some packages, let you specify which <code>package</code> to run as an option for instance. Most don't in my experience. This is how you do it for one that doesn't.
| |
| | |
| add to configuration.nix a set allowing unstable packages.
| |
| This assumes a channel named <code>nixpkgs-unstable</code> exists, like so:
| |
| <syntaxhighlight lang="bash">
| |
| nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable
| |
| nix-channel --update
| |
| </syntaxhighlight>
| |
| | |
| then in <code>configuration.nix</code> allow unstable packages:
| |
| <syntaxhighlight lang="nix">
| |
| # Allow unstable packages.
| |
| nixpkgs.config = {
| |
| allowUnfree = true;
| |
| packageOverrides = pkgs: {
| |
| unstable = import <nixpkgs-unstable> {
| |
| config = config.nixpkgs.config;
| |
| };
| |
| };
| |
| };
| |
| </syntaxhighlight>
| |
| | |
| This means you can now refer to unstable packages as <code>pkgs.unstable.nameofpackage</code> which is great. | |
| For example:
| |
| | |
| <syntaxhighlight lang="nix">
| |
| environment.systemPackages = with pkgs; [
| |
| unstable.bind
| |
| unstable.dnsutils
| |
| vim
| |
| ];
| |
| </syntaxhighlight>
| |
| | |
| This will use unstable bind and dnsutils, but the stable vim.
| |
| | |
| Except bind is a service, and if you want a service....usually you just do something like:
| |
| | |
| <syntaxhighlight lang="nix">
| |
| services.bind.enable = true;
| |
| ...
| |
| </syntaxhighlight>
| |
| | |
| Except services will refer to <code>pkgs.bind</code>, not <code>pkgs.unstable.bind</code>
| |
| | |
| so disable services.bind and create your own:
| |
| | |
| <syntaxhighlight lang="nix">
| |
| users.users.named =
| |
| { uid = config.ids.uids.bind;
| |
| description = "BIND daemon user";
| |
| };
| |
| systemd.services.mybind = {
| |
| description = "BIND Domain Name Server";
| |
| unitConfig.Documentation = "man:named(8)";
| |
| after = [ "network.target" ];
| |
| wantedBy = [ "multi-user.target" ];
| |
| preStart = ''
| |
| mkdir -m 0755 -p /etc/bind
| |
| if ! [ -f "/etc/bind/rndc.key" ]; then
| |
| ${pkgs.unstable.bind.out}/sbin/rndc-confgen -c /etc/bind/rndc.key -u named -a -A hmac-sha256 2>/dev/null
| |
| fi
| |
| ${pkgs.coreutils}/bin/mkdir -p /run/named
| |
| chown named /run/named
| |
| '';
| |
| serviceConfig = {
| |
| ExecStart = "${pkgs.unstable.bind.out}/sbin/named -u named -4 -c /etc/bind/named.conf -f";
| |
| ExecReload = "${pkgs.unstable.bind.out}/sbin/rndc -k '/etc/bind/rndc.key' reload";
| |
| ExecStop = "${pkgs.unstable.bind.out}/sbin/rndc -k '/etc/bind/rndc.key' stop";
| |
| };
| |
| | |
| };
| |
| </syntaxhighlight>
| |
| | |
| where all the stuff just comes from the bind services definition(which you can get from the source link on the nixos options page.)
| |
| Just replace named variables, and replace <code>${pkgs.bind.out</code> with <code>${pkgs.unstable.bind.out}</code>
| |
|
| |
|
| | Note: You can <code>sudo nix-channel --remove nixpkgs</code>, but you still need a nix-channel for nixos |
|
| |
|
| | Be aware that this also pins all dependencies of the application which often causes issues for GUI applications and also brings in back outdated and potentially vulnerable dependencies. |
|
| |
|
| == Nix 2.0 onwards ==
| | <pre> |
| | sudo nix-channel --list |
| | nixos https://nixos.org/channels/nixos-21.05 |
| | </pre> |
|
| |
|
| Nix 2.0 introduces new builtins, <code>fetchTarball</code> and <code>fetchGit</code>, which make it possible to fetch a specific version of nixpkgs without depending on an existing one: | | Nix 2.0 introduces new builtins, <code>fetchTarball</code> and <code>fetchGit</code>, which make it possible to fetch a specific version of nixpkgs without depending on an existing one: |
| Line 100: |
Line 29: |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| Or, to use git for fetching<!-- (this has the advantage of being somewhat faster for updates, but is slower for the initial fetch) [not true anymore, the repository sharing mechanism has been disabled (https://github.com/NixOS/nix/pull/2358)]-->: | | Or, to use git for fetching: |
|
| |
|
| <syntaxhighlight lang="nix"> | | <syntaxhighlight lang="nix"> |
| Line 124: |
Line 53: |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| == Before 2.0 == | | == Pinning an unstable service == |
| | How to upgrade a single package and service to an unstable version |
|
| |
|
| The following code uses the host's Nixpkgs as a | | There is probably a better way, especially once flakes come around. Some packages let you specify which <code>package</code> to run as an option but most don't. The following is a generic way that also works for those which don't. |
| springboard to fetch and import a specific, pinned version of Nixpkgs.
| | |
| This is safe because the specific code we're using from the variable | | add to configuration.nix a set allowing unstable packages. |
| host Nixpkgs is using a very stable API, and will be thrown away as
| | This assumes a channel named <code>nixpkgs-unstable</code> exists, like so: |
| soon as we are done importing the pinned version of Nixpkgs.
| | <syntaxhighlight lang="bash"> |
| | nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable |
| | nix-channel --update |
| | </syntaxhighlight> |
|
| |
|
| Where before you would use <code>pkgs = import <nixpkgs> {}</code>
| | then in <code>configuration.nix</code> allow unstable packages: |
| (which uses the host's Nixpkgs version) you can pin to an exact
| | <syntaxhighlight lang="nix"> |
| version of Nixpkgs by instead using:
| | # Allow unstable packages. |
| | nixpkgs.config = { |
| | allowUnfree = true; |
| | packageOverrides = pkgs: { |
| | unstable = import <nixpkgs-unstable> { |
| | config = config.nixpkgs.config; |
| | }; |
| | }; |
| | }; |
| | </syntaxhighlight> |
|
| |
|
| | This means you can now refer to unstable packages as <code>pkgs.unstable.nameofpackage</code> which is great. |
| | For example: |
|
| |
|
| <syntaxhighlight lang="nix"> | | <syntaxhighlight lang="nix"> |
| pkgs = let | | environment.systemPackages = with pkgs; [ |
| hostPkgs = import <nixpkgs> {};
| | unstable.bind |
| pinnedPkgs = hostPkgs.fetchFromGitHub { | | unstable.dnsutils |
| owner = "NixOS";
| | vim |
| repo = "nixpkgs";
| | ]; |
| # nixos-unstable as of 2017-11-13T08:53:10-00:00
| |
| rev = "ac355040656de04f59406ba2380a96f4124ebdad";
| |
| sha256 = "0frhc7mnx88sird6ipp6578k5badibsl0jfa22ab9w6qrb88j825";
| |
| };
| |
| in import pinnedPkgs {}
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| This can also be instead used to pull nixpkgs from an internal fork of | | This will use unstable bind and dnsutils, but the stable vim. |
| Nixpkgs, with your own changes on top. Note, however, as it stands
| |
| Nix 1.11 has difficulties fetching repositories which require
| |
| authentication, this is to be fixed in Nix 1.12.
| |
|
| |
|
| The package <code>nix-prefetch-git</code> can be used to automatically
| | Except bind is a service, and if you want a service....usually you just do something like: |
| calculate the current version and hash of a branch, and output the
| |
| information to a file:
| |
|
| |
|
| <syntaxhighlight> | | <syntaxhighlight lang="nix"> |
| $ nix-shell -p nix-prefetch-git
| | services.bind.enable = true; |
|
| |
| [nix-shell:~]$ nix-prefetch-git https://github.com/nixos/nixpkgs.git refs/heads/nixos-unstable > nixpkgs-version.json
| |
|
| |
| ... | | ... |
|
| |
| [nix-shell:~]$ cat nixpkgs-version.json
| |
| {
| |
| "url": "https://github.com/nixos/nixpkgs.git",
| |
| "rev": "f607771d0f5e4fa905afff1c772febd9f3103e1a",
| |
| "date": "2018-01-09T11:18:25-05:00",
| |
| "sha256": "1icphqpdcl8akqhfij2pxkfr7wfn86z5sr3jdjh88p9vv1550dx7",
| |
| "fetchSubmodules": true
| |
| }
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| | |
| This file can then be used to specify the version of Nixpkgs:
| | Except services will refer to <code>pkgs.bind</code>, not <code>pkgs.unstable.bind</code> |
| | |
| | so disable services.bind and create your own: |
|
| |
|
| <syntaxhighlight lang="nix"> | | <syntaxhighlight lang="nix"> |
| pkgs = let
| | users.users.named = { |
| hostPkgs = import <nixpkgs> {};
| | uid = config.ids.uids.bind; |
| pinnedVersion = hostPkgs.lib.importJSON ./nixpkgs-version.json;
| | description = "BIND daemon user"; |
| pinnedPkgs = hostPkgs.fetchFromGitHub {
| | }; |
| owner = "NixOS";
| | systemd.services.mybind = { |
| repo = "nixpkgs";
| | description = "BIND Domain Name Server"; |
| inherit (pinnedVersion) rev sha256;
| | unitConfig.Documentation = "man:named(8)"; |
| };
| | after = [ "network.target" ]; |
| in import pinnedPkgs {};
| | wantedBy = [ "multi-user.target" ]; |
| | preStart = '' |
| | mkdir -m 0755 -p /etc/bind |
| | if ! [ -f "/etc/bind/rndc.key" ]; then |
| | ${pkgs.unstable.bind.out}/sbin/rndc-confgen -c /etc/bind/rndc.key -u named -a -A hmac-sha256 2>/dev/null |
| | fi |
| | ${pkgs.coreutils}/bin/mkdir -p /run/named |
| | chown named /run/named |
| | ''; |
| | serviceConfig = { |
| | ExecStart = "${pkgs.unstable.bind.out}/sbin/named -u named -4 -c /etc/bind/named.conf -f"; |
| | ExecReload = "${pkgs.unstable.bind.out}/sbin/rndc -k '/etc/bind/rndc.key' reload"; |
| | ExecStop = "${pkgs.unstable.bind.out}/sbin/rndc -k '/etc/bind/rndc.key' stop"; |
| | }; |
| | }; |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| Finally, this can be taken a step further, and you can apply extra
| | where all the stuff just comes from the bind services definition(which you can get from the source link on the nixos options page.) |
| patches to the pinned version of Nixpkgs, for perhaps PRs that are not
| | Just replace named variables, and replace <code>${pkgs.bind.out</code> with <code>${pkgs.unstable.bind.out}</code> |
| yet merged, or private internal changes that you need. If you take
| |
| this route, probably best to move the following in to its own file
| |
| that you then import.
| |
|
| |
|
| <syntaxhighlight lang="nix">
| | == See also == |
| pkgs = let
| | |
| hostPkgs = import <nixpkgs> {};
| | * [https://nix.dev/reference/pinning-nixpkgs Pinning Nixpkgs] |
| pinnedVersion = hostPkgs.lib.importJSON ./nixpkgs-version.json;
| | * [https://nix.dev/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs Towards Reproducibility: Pinning Nixpkgs] |
| pinnedPkgs = hostPkgs.fetchFromGitHub {
| | * [https://nix.dev/guides/recipes/dependency-management.html Dependency Management] |
| owner = "NixOS";
| |
| repo = "nixpkgs";
| |
| inherit (pinnedVersion) rev sha256;
| |
| };
| |
|
| |
| patches = [
| |
| ./patches/0001-my-nixpkgs-change.patch
| |
| ];
| |
|
| |
| patchedPkgs = hostPkgs.runCommand "nixpkgs-${pinnedVersion.rev}"
| |
| {
| |
| inherit pinnedPkgs;
| |
| inherit patches;
| |
| }
| |
| ''
| |
| cp -r $pinnedPkgs $out
| |
| chmod -R +w $out
| |
| for p in $patches; do
| |
| echo "Applying patch $p";
| |
| patch -d $out -p1 < "$p";
| |
| done
| |
| '';
| |
| in import patchedPkgs {};
| |
| </syntaxhighlight>
| |