Discussion:
[Nix-dev] 5 somewhat related questions
Klaas van Schelven
2017-06-22 18:40:49 UTC
Permalink
Hello Nixians,

I've installed NixOs a number of days ago. So far I really like it!

I've read the documentation I could find, but I'm left with a number of
questions; not so much "how to do X" but rather of a slightly more
philosphofical (or cultural, a.k.a. "best practices") nature. I hope
someone can enlighten me on the "Nix Way".

1. In NixOs /etc/nixos/configuration.nix is the single configuration file
that determines the state of the system as a whole. How does this file
relate to the existence of the nix-env command, either executed as root or
by a single non-privileged user? In particular, I would assume that any
nix-env is undone by the time the system is rebuilt from the configuration
file. Assuming this is the case: should the usage of nix-env not be
actively discouraged in NixOs? (perhaps it is, and I simply did not find
the reference)

2. (Context: Assuming for a moment there _is_ in fact a use-case for
nix-env; e.g. the scenario where you're not running NixOs, but are using
Nix on top of another distribution). nix-env uses an "imperative style" of
manipulating your environment, i.e. using a sequence of commands in a
particular order. I understand that after each succesful manipulation the
_resulting_ environment becomes available as a separate generation. As far
as I understand there's even a "half-product", the so called "derivation"
that is available per generation, although I did not study those yet. My
question is, however, whether the original commands that led to these
constructions can somehow be retrieved. The reason for this question is the
observation that the sequence of nix-env (and potentially other similar)
commands can be seen as a transactional log that could simply be replayed
to reconstruct the resulting generations (assuming that the commands fully
express the information needed to construct the associated environments;
this assumption might not actually hold in practice. Question 2b: does the
assumption hold?).

3. In the scenario where I use the single configuration file
/etc/nixos/configuration.nix but I'm also subscribed to a channel, the
state of this channel may influence the outcome of nixos-rebuild (This is
by design, it allows us to stay up to date with e.g. security updates). The
consecutive states of the channel, as seen by my system when rebuilding,
are valuable pieces of information in their own right when I want to debug
a problem. Take the following example:

t=0, my system is good.
t=1, I want to install some extra package, I modify configuration.nix, and
run nixos-rebuild
t=2, system broken.

I understand that I always have the ability to roll back the system _as a
whole_, even using Grub if needed. This is awesome of course. The question
is: do I also have the ability to debug the parts that lead to that whole?
In particular: the precise state of the channel[s] on each rebuild? And
preferably also: the state of /etc/nixos/configuration.nix on each build?

4. Is a "single declarative file per user" (e.g. for dotfiles, but
potentially also to make it possible to declare which user-specific
packages are installed) available? I understand there some options exist,
but how do they relate? Is there convergence on a "one way to do it"?

5. In the commit linked below, the nix file for VTE 2.91 adds the following
2 propagatedBuildInputs: pcre2 & gnutls. As far as I understand this might
be not good practice. The reason I've added them is because pkg-config,
when run in the build context of xfce.terminal, cannot otherwise find the
package vte-2.91 because of a dependency error. Ignoring for a moment the
rationale of the commit itself (I've been convinced that adding this
particular version of xfce4-terminal to the repo by itself is not a good
idea) can someone tell me what the proper way to handle this particular
situation would be?

https://github.com/NixOS/nixpkgs/pull/26742/commits/5e566d3c8a078f6cd6304e7cf0b409a8260ee71c#diff-52903c4477fc53869e7e92148494cbe5R17

Hope this isn't too overwhelming a wall of text - feel free to answer only
partly if you see fit.

Thanks in advance,
Klaas
--
Klaas van Schelven
+31 6 811 599 10
David Izquierdo
2017-06-22 19:18:25 UTC
Permalink
I'll try to answer what I think I know...
Post by Klaas van Schelven
Hello Nixians,
I've installed NixOs a number of days ago. So far I really like it!
I've read the documentation I could find, but I'm left with a number of
questions; not so much "how to do X" but rather of a slightly more
philosphofical (or cultural, a.k.a. "best practices") nature. I hope
someone can enlighten me on the "Nix Way".
1. In NixOs /etc/nixos/configuration.nix is the single configuration file
that determines the state of the system as a whole. How does this file
relate to the existence of the nix-env command, either executed as root or
by a single non-privileged user? In particular, I would assume that any
nix-env is undone by the time the system is rebuilt from the configuration
file. Assuming this is the case: should the usage of nix-env not be
actively discouraged in NixOs? (perhaps it is, and I simply did not find
the reference)
They're mostly independent, but AFAIK nix-env binaries have priority
over conf.nix. Nothing gets undone, since whatever you install to your
user profile stays in the nix store (because your user profile is a gc
root). For me, the use of n-e is because it's faster to test or use
oneshot software installing it imperatively than adding-then-removing to
conf.nix. I guess `nix-shell -p` would be more "correct", but it's a
matter of not forgetting you've used it.
Post by Klaas van Schelven
2. (Context: Assuming for a moment there _is_ in fact a use-case for
nix-env; e.g. the scenario where you're not running NixOs, but are using
Nix on top of another distribution). nix-env uses an "imperative style" of
manipulating your environment, i.e. using a sequence of commands in a
particular order. I understand that after each succesful manipulation the
_resulting_ environment becomes available as a separate generation. As far
as I understand there's even a "half-product", the so called "derivation"
that is available per generation, although I did not study those yet. My
question is, however, whether the original commands that led to these
constructions can somehow be retrieved. The reason for this question is the
observation that the sequence of nix-env (and potentially other similar)
commands can be seen as a transactional log that could simply be replayed
to reconstruct the resulting generations (assuming that the commands fully
express the information needed to construct the associated environments;
this assumption might not actually hold in practice. Question 2b: does the
assumption hold?).
3. In the scenario where I use the single configuration file
/etc/nixos/configuration.nix but I'm also subscribed to a channel, the
state of this channel may influence the outcome of nixos-rebuild (This is
by design, it allows us to stay up to date with e.g. security updates). The
consecutive states of the channel, as seen by my system when rebuilding,
are valuable pieces of information in their own right when I want to debug
t=0, my system is good.
t=1, I want to install some extra package, I modify configuration.nix, and
run nixos-rebuild
t=2, system broken.
I understand that I always have the ability to roll back the system _as a
whole_, even using Grub if needed. This is awesome of course. The question
is: do I also have the ability to debug the parts that lead to that whole?
In particular: the precise state of the channel[s] on each rebuild? And
preferably also: the state of /etc/nixos/configuration.nix on each build?
I think you want `nix-channel --rollback`, and
`system.copySystemConfiguration = true` (for c.nix). Note however that
at some point it will probably be in your best interest to modularise
your c.nix into several files, and that option only copies c.nix, not
any imports. You can check this message for a fairly elegant method to
have your /etc/nixos tree be a part of each generation.

https://mailman.science.uu.nl/pipermail/nix-dev/2017-April/023403.html
Post by Klaas van Schelven
4. Is a "single declarative file per user" (e.g. for dotfiles, but
potentially also to make it possible to declare which user-specific
packages are installed) available? I understand there some options exist,
but how do they relate? Is there convergence on a "one way to do it"?
5. In the commit linked below, the nix file for VTE 2.91 adds the following
2 propagatedBuildInputs: pcre2 & gnutls. As far as I understand this might
be not good practice. The reason I've added them is because pkg-config,
when run in the build context of xfce.terminal, cannot otherwise find the
package vte-2.91 because of a dependency error. Ignoring for a moment the
rationale of the commit itself (I've been convinced that adding this
particular version of xfce4-terminal to the repo by itself is not a good
idea) can someone tell me what the proper way to handle this particular
situation would be?
https://github.com/NixOS/nixpkgs/pull/26742/commits/5e566d3c8a078f6cd6304e7cf0b409a8260ee71c#diff-52903c4477fc53869e7e92148494cbe5R17
Hope this isn't too overwhelming a wall of text - feel free to answer only
partly if you see fit.
Thanks in advance,
Klaas
_______________________________________________
nix-dev mailing list
https://mailman.science.uu.nl/mailman/listinfo/nix-dev
Klaas van Schelven
2017-06-23 10:28:45 UTC
Permalink
David,

Thanks for your reply; answering below with a few more findings based on
your pointers in the hope that this might be relevant for future readers
(including myself)

3. In the scenario where I use the single configuration file
Post by David Izquierdo
Post by Klaas van Schelven
/etc/nixos/configuration.nix but I'm also subscribed to a channel, the
state of this channel may influence the outcome of nixos-rebuild (This is
by design, it allows us to stay up to date with e.g. security updates). The
consecutive states of the channel, as seen by my system when rebuilding,
are valuable pieces of information in their own right when I want to debug
t=0, my system is good.
t=1, I want to install some extra package, I modify configuration.nix, and
run nixos-rebuild
t=2, system broken.
I understand that I always have the ability to roll back the system _as a
whole_, even using Grub if needed. This is awesome of course. The question
is: do I also have the ability to debug the parts that lead to that whole?
In particular: the precise state of the channel[s] on each rebuild? And
preferably also: the state of /etc/nixos/configuration.nix on each build?
I think you want `nix-channel --rollback`, and
`system.copySystemConfiguration = true` (for c.nix). Note however that at
some point it will probably be in your best interest to modularise your
c.nix into several files, and that option only copies c.nix, not any
imports. You can check this message for a fairly elegant method to have
your /etc/nixos tree be a part of each generation.
https://mailman.science.uu.nl/pipermail/nix-dev/2017-April/023403.html
Thanks for the pointer to `nix-channel --rollback`; it's indeed the kind of
thing I was thinking about, although it seems the various "seen states" of
the channel have not fully been exposed in all tooling. E.g. it's possible
to roll back to a particular generation of the channel, but it's not
possible to list all generations using the tooling (AFAICS); However, at
least we can inspect the directory layout and proceed from there.

system.copySystemConfiguration is the kind of thing I was talking about,
although it's indeed quite useless given it breaks under modularisation of
the config.

The discussion about "source closures" in this pull request is also
interesting: https://github.com/NixOS/nix/pull/709
(found by repairing a link in the discussion you mentioned).

For now, I think I'll just implement this by putting the sources in a more
conventional version control system.
Judson Lester
2017-06-22 20:30:43 UTC
Permalink
Klaas,

First, welcome to Nix! I hope you'll enjoy it as much as I've been.

Second, your questions seem like prime additions to
https://github.com/nixos-users/wiki/wiki/Documentation-Gaps which I hope
will inform future version of the Nix manuals.

I'll do my best to share my understanding vis-a-vis your questions, but
they highlight weaknesses in my own understanding as well.
Post by Klaas van Schelven
Hello Nixians,
I've installed NixOs a number of days ago. So far I really like it!
I've read the documentation I could find, but I'm left with a number of
questions; not so much "how to do X" but rather of a slightly more
philosphofical (or cultural, a.k.a. "best practices") nature. I hope
someone can enlighten me on the "Nix Way".
1. In NixOs /etc/nixos/configuration.nix is the single configuration file
that determines the state of the system as a whole. How does this file
relate to the existence of the nix-env command, either executed as root or
by a single non-privileged user? In particular, I would assume that any
nix-env is undone by the time the system is rebuilt from the configuration
file. Assuming this is the case: should the usage of nix-env not be
actively discouraged in NixOs? (perhaps it is, and I simply did not find
the reference)
The products of runinng nix-env --install live in profiles (as, in fact,
do nixos-rebuilds) - there's a diagram here
http://nixos.org/nix/manual/#sec-profiles that I found useful for
understanding how profiles work. Specificially, every user has their own
"~/.nix-profiles" directory, and the system as a whole has a collection of
profiles. System and user profiles are blended, using Unix pathing
mechanisms. If, for example, you check your PATH, you'll see references to
/home/username/.nix-profile/bin and /run/current-system/sw/bin.

nix-env --install is incredibly convenient to quickly install a program you
need in the moment. Even better is when the "not installed" warning are
working properly (which relies on your channel etc) and you can copy and
paste a nix-env command to get the tool you need _right then_, and take a
little maintenance time later to "purify" things.

I've found it useful from time to time to do a nix-env -q, and migrate the
list of installed packages to nix configuration.nix, and then delete my
local installs along the way. I sort of wish that there were a mechanical
way to do this, but it'd involve editing configuration.nix automatically
and triggering nixos-rebuild, which I'm loath to undertake myself.

Admittedly, there is some potential for confusion involved when you've
nix-env'd a package, since you e.g. won't see it update when nixos-build is
run. Also beware interactions like dmenu or neovim installed in one place
and programs or plugins installed in another.

2. (Context: Assuming for a moment there _is_ in fact a use-case for
Post by Klaas van Schelven
nix-env; e.g. the scenario where you're not running NixOs, but are using
Nix on top of another distribution). nix-env uses an "imperative style" of
manipulating your environment, i.e. using a sequence of commands in a
particular order. I understand that after each succesful manipulation the
_resulting_ environment becomes available as a separate generation. As far
as I understand there's even a "half-product", the so called "derivation"
that is available per generation, although I did not study those yet. My
question is, however, whether the original commands that led to these
constructions can somehow be retrieved. The reason for this question is the
observation that the sequence of nix-env (and potentially other similar)
commands can be seen as a transactional log that could simply be replayed
to reconstruct the resulting generations (assuming that the commands fully
express the information needed to construct the associated environments;
this assumption might not actually hold in practice. Question 2b: does the
assumption hold?).
That intuition holds modulo your Q3 - replaying a sequence of nix-env
commands would only reproduce the same generations if a) the states of all
channels involved were retained (i.e. you'd need to know which
nixpkgs-stable you installed from with each command) and b) all the builds
were reproduce-able or cached. Nix assumes reproduce-able builds, and so
retains the outcomes of building derivations based on a digest of the
derivation itself - but if you replayed the same nix-env commands from
scratch, you might get (trivially) different outcomes.
Post by Klaas van Schelven
3. In the scenario where I use the single configuration file
/etc/nixos/configuration.nix but I'm also subscribed to a channel, the
state of this channel may influence the outcome of nixos-rebuild (This is
by design, it allows us to stay up to date with e.g. security updates). The
consecutive states of the channel, as seen by my system when rebuilding,
are valuable pieces of information in their own right when I want to debug
t=0, my system is good.
t=1, I want to install some extra package, I modify configuration.nix, and
run nixos-rebuild
t=2, system broken.
I understand that I always have the ability to roll back the system _as a
whole_, even using Grub if needed. This is awesome of course. The question
is: do I also have the ability to debug the parts that lead to that whole?
In particular: the precise state of the channel[s] on each rebuild? And
preferably also: the state of /etc/nixos/configuration.nix on each build?
The rollbacks will be as-built, so implicitly they capture the state
implied by the channels and configuration.nix. However, there's no explicit
capture of those - there was discussion relatively recently about capturing
configuration.nix into the generation, but it turns out to be a little
harder than you'd expect. Likewise, you'd have to somehow capture the state
of all the involved channels.
Post by Klaas van Schelven
4. Is a "single declarative file per user" (e.g. for dotfiles, but
potentially also to make it possible to declare which user-specific
packages are installed) available? I understand there some options exist,
but how do they relate? Is there convergence on a "one way to do it"?
It is possible to use ~/.config/nixpkgs/config.nix for this. There used to
be a wiki article about using overrides to create an "all-packages"
derivation that would work like a personal packages: []. I don't think (but
might be wrong) that modules can be used in this context, so replacing
personal dotfiles is trickier. My impression is that this is an approach
that people take as they get very comfortable with nix, and as a result
everyone goes their own way.
Post by Klaas van Schelven
5. In the commit linked below, the nix file for VTE 2.91 adds the
following 2 propagatedBuildInputs: pcre2 & gnutls. As far as I understand
this might be not good practice. The reason I've added them is because
pkg-config, when run in the build context of xfce.terminal, cannot
otherwise find the package vte-2.91 because of a dependency error. Ignoring
for a moment the rationale of the commit itself (I've been convinced that
adding this particular version of xfce4-terminal to the repo by itself is
not a good idea) can someone tell me what the proper way to handle this
particular situation would be?
https://github.com/NixOS/nixpkgs/pull/26742/commits/5e566d3c8a078f6cd6304e7cf0b409a8260ee71c#diff-52903c4477fc53869e7e92148494cbe5R17
I'm keen to see someone better appraised's response to this.
Judson
Nawal Husnoo
2017-06-22 20:37:25 UTC
Permalink
This is what I use for config.nix, following the example I got it from
(link below).

# nix-env -i all
# https://github.com/kamilchm/.nixpkgs/blob/master/config.nix

with import <nixpkgs> {};

{
allowUnfree = true;

packageOverrides = pkgs_: with pkgs_; {

all = with pkgs; buildEnv {
name = "all";
paths = [

bunch
of
things
I
use
but
didnt
want
to
pollute
configuration
dot
nix
with

];
};
};
}
Post by Judson Lester
Klaas,
First, welcome to Nix! I hope you'll enjoy it as much as I've been.
Second, your questions seem like prime additions to
https://github.com/nixos-users/wiki/wiki/Documentation-Gaps which I hope
will inform future version of the Nix manuals.
I'll do my best to share my understanding vis-a-vis your questions, but
they highlight weaknesses in my own understanding as well.
Post by Klaas van Schelven
Hello Nixians,
I've installed NixOs a number of days ago. So far I really like it!
I've read the documentation I could find, but I'm left with a number of
questions; not so much "how to do X" but rather of a slightly more
philosphofical (or cultural, a.k.a. "best practices") nature. I hope
someone can enlighten me on the "Nix Way".
1. In NixOs /etc/nixos/configuration.nix is the single configuration file
that determines the state of the system as a whole. How does this file
relate to the existence of the nix-env command, either executed as root or
by a single non-privileged user? In particular, I would assume that any
nix-env is undone by the time the system is rebuilt from the configuration
file. Assuming this is the case: should the usage of nix-env not be
actively discouraged in NixOs? (perhaps it is, and I simply did not find
the reference)
The products of runinng nix-env --install live in profiles (as, in fact,
do nixos-rebuilds) - there's a diagram here http://nixos.org/nix/
manual/#sec-profiles that I found useful for understanding how profiles
work. Specificially, every user has their own "~/.nix-profiles" directory,
and the system as a whole has a collection of profiles. System and user
profiles are blended, using Unix pathing mechanisms. If, for example, you
check your PATH, you'll see references to /home/username/.nix-profile/bin
and /run/current-system/sw/bin.
nix-env --install is incredibly convenient to quickly install a program
you need in the moment. Even better is when the "not installed" warning are
working properly (which relies on your channel etc) and you can copy and
paste a nix-env command to get the tool you need _right then_, and take a
little maintenance time later to "purify" things.
I've found it useful from time to time to do a nix-env -q, and migrate the
list of installed packages to nix configuration.nix, and then delete my
local installs along the way. I sort of wish that there were a mechanical
way to do this, but it'd involve editing configuration.nix automatically
and triggering nixos-rebuild, which I'm loath to undertake myself.
Admittedly, there is some potential for confusion involved when you've
nix-env'd a package, since you e.g. won't see it update when nixos-build is
run. Also beware interactions like dmenu or neovim installed in one place
and programs or plugins installed in another.
2. (Context: Assuming for a moment there _is_ in fact a use-case for
Post by Klaas van Schelven
nix-env; e.g. the scenario where you're not running NixOs, but are using
Nix on top of another distribution). nix-env uses an "imperative style" of
manipulating your environment, i.e. using a sequence of commands in a
particular order. I understand that after each succesful manipulation the
_resulting_ environment becomes available as a separate generation. As far
as I understand there's even a "half-product", the so called "derivation"
that is available per generation, although I did not study those yet. My
question is, however, whether the original commands that led to these
constructions can somehow be retrieved. The reason for this question is the
observation that the sequence of nix-env (and potentially other similar)
commands can be seen as a transactional log that could simply be replayed
to reconstruct the resulting generations (assuming that the commands fully
express the information needed to construct the associated environments;
this assumption might not actually hold in practice. Question 2b: does the
assumption hold?).
That intuition holds modulo your Q3 - replaying a sequence of nix-env
commands would only reproduce the same generations if a) the states of all
channels involved were retained (i.e. you'd need to know which
nixpkgs-stable you installed from with each command) and b) all the builds
were reproduce-able or cached. Nix assumes reproduce-able builds, and so
retains the outcomes of building derivations based on a digest of the
derivation itself - but if you replayed the same nix-env commands from
scratch, you might get (trivially) different outcomes.
Post by Klaas van Schelven
3. In the scenario where I use the single configuration file
/etc/nixos/configuration.nix but I'm also subscribed to a channel, the
state of this channel may influence the outcome of nixos-rebuild (This is
by design, it allows us to stay up to date with e.g. security updates). The
consecutive states of the channel, as seen by my system when rebuilding,
are valuable pieces of information in their own right when I want to debug
t=0, my system is good.
t=1, I want to install some extra package, I modify configuration.nix,
and run nixos-rebuild
t=2, system broken.
I understand that I always have the ability to roll back the system _as a
whole_, even using Grub if needed. This is awesome of course. The question
is: do I also have the ability to debug the parts that lead to that whole?
In particular: the precise state of the channel[s] on each rebuild? And
preferably also: the state of /etc/nixos/configuration.nix on each build?
The rollbacks will be as-built, so implicitly they capture the state
implied by the channels and configuration.nix. However, there's no explicit
capture of those - there was discussion relatively recently about capturing
configuration.nix into the generation, but it turns out to be a little
harder than you'd expect. Likewise, you'd have to somehow capture the state
of all the involved channels.
Post by Klaas van Schelven
4. Is a "single declarative file per user" (e.g. for dotfiles, but
potentially also to make it possible to declare which user-specific
packages are installed) available? I understand there some options exist,
but how do they relate? Is there convergence on a "one way to do it"?
It is possible to use ~/.config/nixpkgs/config.nix for this. There used
to be a wiki article about using overrides to create an "all-packages"
derivation that would work like a personal packages: []. I don't think (but
might be wrong) that modules can be used in this context, so replacing
personal dotfiles is trickier. My impression is that this is an approach
that people take as they get very comfortable with nix, and as a result
everyone goes their own way.
Post by Klaas van Schelven
5. In the commit linked below, the nix file for VTE 2.91 adds the
following 2 propagatedBuildInputs: pcre2 & gnutls. As far as I understand
this might be not good practice. The reason I've added them is because
pkg-config, when run in the build context of xfce.terminal, cannot
otherwise find the package vte-2.91 because of a dependency error. Ignoring
for a moment the rationale of the commit itself (I've been convinced that
adding this particular version of xfce4-terminal to the repo by itself is
not a good idea) can someone tell me what the proper way to handle this
particular situation would be?
https://github.com/NixOS/nixpkgs/pull/26742/commits/
5e566d3c8a078f6cd6304e7cf0b409a8260ee71c#diff-
52903c4477fc53869e7e92148494cbe5R17
I'm keen to see someone better appraised's response to this.
Judson
_______________________________________________
nix-dev mailing list
https://mailman.science.uu.nl/mailman/listinfo/nix-dev
Klaas van Schelven
2017-06-23 10:42:29 UTC
Permalink
Judson,

Thanks for your answers!
I've documented where your answers led me below for myself and others below.
Post by Judson Lester
Second, your questions seem like prime additions to
https://github.com/nixos-users/wiki/wiki/Documentation-Gaps which I hope
will inform future version of the Nix manuals.
Maybe... the biggest missing "thing" in the documentation that I've
encountered so far is not any particular gap, but rather the organization
of the material. I have not yet reached the level where I can reorganize
all of the documentation myself though, nor do I have the time for it :-)
Post by Judson Lester
I'll do my best to share my understanding vis-a-vis your questions, but
they highlight weaknesses in my own understanding as well.
[..]
Post by Klaas van Schelven
1. In NixOs /etc/nixos/configuration.nix is the single configuration file
that determines the state of the system as a whole. How does this file
relate to the existence of the nix-env command, either executed as root or
by a single non-privileged user? In particular, I would assume that any
nix-env is undone by the time the system is rebuilt from the configuration
file. Assuming this is the case: should the usage of nix-env not be
actively discouraged in NixOs? (perhaps it is, and I simply did not find
the reference)
The products of runinng nix-env --install live in profiles (as, in fact,
do nixos-rebuilds) - there's a diagram here http://nixos.org/nix/
manual/#sec-profiles that I found useful for understanding how profiles
work. Specificially, every user has their own "~/.nix-profiles" directory,
and the system as a whole has a collection of profiles. System and user
profiles are blended, using Unix pathing mechanisms. If, for example, you
check your PATH, you'll see references to /home/username/.nix-profile/bin
and /run/current-system/sw/bin.
Yes, the diagram is very useful!
One thing that's missing from the diagram (and my understanding until an
hour ago) is that the PATH value is in practice not a single value, but
rather a list (as is usual for paths, but I didn't necessarily assume that
Nix would do the usual thing). This gives rise to the "blending" that you
mention above, so that a non-privileged user has access to their own env,
the root's env, and the "system" env (AFAIU, the env that's generated from
the configuration.nix).

To answer my own question: root's nix-env and the configuration.nix are
independent from each other and their blended results will be available to
all users. This means that running nixos-rebuild after some imperative
style nix-env commands will in fact *not *undo those nix-env commands. Your
remark that ~
Post by Judson Lester
nix-env --install is incredibly convenient to quickly install a program
you need in the moment. Even better is when the "not installed" warning are
working properly (which relies on your channel etc) and you can copy and
paste a nix-env command to get the tool you need _right then_, and take a
little maintenance time later to "purify" things.
I've found it useful from time to time to do a nix-env -q, and migrate the
list of installed packages to nix configuration.nix, and then delete my
local installs along the way. I sort of wish that there were a mechanical
way to do this, but it'd involve editing configuration.nix automatically
and triggering nixos-rebuild, which I'm loath to undertake myself.
Admittedly, there is some potential for confusion involved when you've
nix-env'd a package, since you e.g. won't see it update when nixos-build is
run. Also beware interactions like dmenu or neovim installed in one place
and programs or plugins installed in another.
This is a good tip on an actually practical workflow!
Post by Judson Lester
2. (Context: Assuming for a moment there _is_ in fact a use-case for
Post by Klaas van Schelven
nix-env; e.g. the scenario where you're not running NixOs, but are using
Nix on top of another distribution). nix-env uses an "imperative style" of
manipulating your environment, i.e. using a sequence of commands in a
particular order. I understand that after each succesful manipulation the
_resulting_ environment becomes available as a separate generation. As far
as I understand there's even a "half-product", the so called "derivation"
that is available per generation, although I did not study those yet. My
question is, however, whether the original commands that led to these
constructions can somehow be retrieved. The reason for this question is the
observation that the sequence of nix-env (and potentially other similar)
commands can be seen as a transactional log that could simply be replayed
to reconstruct the resulting generations (assuming that the commands fully
express the information needed to construct the associated environments;
this assumption might not actually hold in practice. Question 2b: does the
assumption hold?).
That intuition holds modulo your Q3 - replaying a sequence of nix-env
commands would only reproduce the same generations if a) the states of all
channels involved were retained (i.e. you'd need to know which
nixpkgs-stable you installed from with each command) and b) all the builds
were reproduce-able or cached. Nix assumes reproduce-able builds, and so
retains the outcomes of building derivations based on a digest of the
derivation itself - but if you replayed the same nix-env commands from
scratch, you might get (trivially) different outcomes.
Out of those 2 remarks "a" is the big one, especially if the channel you've
subscribed to is in fact not the stable one.
As far as I understand now, there is no solution for this (yet). Good to
know though.
Post by Judson Lester
3. In the scenario where I use the single configuration file
Post by Klaas van Schelven
/etc/nixos/configuration.nix but I'm also subscribed to a channel, the
state of this channel may influence the outcome of nixos-rebuild (This is
by design, it allows us to stay up to date with e.g. security updates). The
consecutive states of the channel, as seen by my system when rebuilding,
are valuable pieces of information in their own right when I want to debug
t=0, my system is good.
t=1, I want to install some extra package, I modify configuration.nix,
and run nixos-rebuild
t=2, system broken.
I understand that I always have the ability to roll back the system _as a
whole_, even using Grub if needed. This is awesome of course. The question
is: do I also have the ability to debug the parts that lead to that whole?
In particular: the precise state of the channel[s] on each rebuild? And
preferably also: the state of /etc/nixos/configuration.nix on each build?
The rollbacks will be as-built, so implicitly they capture the state
implied by the channels and configuration.nix. However, there's no explicit
capture of those - there was discussion relatively recently about capturing
configuration.nix into the generation, but it turns out to be a little
harder than you'd expect. Likewise, you'd have to somehow capture the state
of all the involved channels.
Do you have a pointer to this discussion? I cannot find it using the
keywords you mentioned above.
Post by Judson Lester
Post by Klaas van Schelven
4. Is a "single declarative file per user" (e.g. for dotfiles, but
potentially also to make it possible to declare which user-specific
packages are installed) available? I understand there some options exist,
but how do they relate? Is there convergence on a "one way to do it"?
It is possible to use ~/.config/nixpkgs/config.nix for this. There used
to be a wiki article about using overrides to create an "all-packages"
derivation that would work like a personal packages: []. I don't think (but
might be wrong) that modules can be used in this context, so replacing
personal dotfiles is trickier. My impression is that this is an approach
that people take as they get very comfortable with nix, and as a result
everyone goes their own way.
The 2 starting points into this (1 of them linked by Nawal) are:

https://github.com/kamilchm/.nixpkgs/
https://github.com/NixOS/nixpkgs/issues/1750


Thanks very much,
Klaas
Linus Heckemann
2017-06-23 17:07:18 UTC
Permalink
Hi Klaas,
Post by Klaas van Schelven
Post by Judson Lester
That intuition holds modulo your Q3 - replaying a sequence of
nix-env commands would only reproduce the same generations if a)
the states of all channels involved were retained (i.e. you'd need
to know which nixpkgs-stable you installed from with each command)
and b) all the builds were reproduce-able or cached. Nix assumes
reproduce-able builds, and so retains the outcomes of building
derivations based on a digest of the derivation itself - but if you
replayed the same nix-env commands from scratch, you might get
(trivially) different outcomes.
Out of those 2 remarks "a" is the big one, especially if the channel
you've subscribed to is in fact not the stable one. As far as I
understand now, there is no solution for this (yet). Good to know
though.
You can, instead of using nixpkgs/config.nix, write an expression for
your user environment somewhat like this (say software.nix):

let pkgs = import <nixpkgs> {}; in
{
inherit (pkgs) vim ripgrep ;
}

You can install this using:

nix-env -f software.nix -i

If you add the -r flag, the result will not depend on the previous
generation of your user environment. The benefit of this approach is
that you can replace pkgs in order to pin specific versions, for instance…

let
# System nixpkgs used only to fetch pinned nixpkgs
bootPkgs = import <nixpkgs> {};
pkgs = import (bootPkgs.fetchFromGitHub {
owner = "nixos";
repo = "nixpkgs";
rev = "d10fe641247e29b72139776cd3163344443b13ba";
sha256 = "06viplacb5w49yf3rirsn4jdcfssj98f3s1zic0l8raxng7pmdcq";
}) {};
in {
inherit (pkgs) vim ripgrep;
};

Which is a bit harder to maintain but should be much less stateful,
depending only on fetchFromGitHub from your current nixpkgs not breaking
compatibility and on github staying up — and importantly, it would allow
reproducing previous generations more easily. You could of course also
factor the fetching out into a separate file which you could import and
have a script to automatically update. I wouldn't be surprised if
someone had already done that somewhere.

In a similar vein of functionality, you could version your user
environment in a git repo with nixpkgs as a submodule and update it
explicitly. This would provide a similar experience and further reduce
the variability.
Post by Klaas van Schelven
The rollbacks will be as-built, so implicitly they capture the state
implied by the channels and configuration.nix. However, there's no
explicit capture of those - there was discussion relatively recently
about capturing configuration.nix into the generation, but it turns
out to be a little harder than you'd expect. Likewise, you'd have to
somehow capture the state of all the involved channels.
Do you have a pointer to this discussion? I cannot find it using the
keywords you mentioned above.
This was the discussion David Izquierdo linked in his reply:
https://mailman.science.uu.nl/pipermail/nix-dev/2017-April/023403.html

Linus
Matt McHenry
2017-06-24 19:07:27 UTC
Permalink
I had some of the same thoughts as Klass about nix-env vs.
/etc/nixos/configuration.nix when I started using NixOS about a year
ago. Since all the machines I run it on are single-user, I've found
it simplest to never run nix-env, and just 'sudo emacs
/etc/nixos/pkgs-configuration.nix && sudo nixos-rebuild switch' to
install new packages. (I've modularized my
/etc/nixos/configuration.nix.)

I keep /etc/nixos under git version control, so that I can move
between versions of the machine config independently of versions of
nixpkgs. This also has the benefit of making in very easy to keep
configuration changes in sync between my different NixOS machines
(they all push/pull to/from each other as remote repos).

Rather than using nix-channel to manage my channels, I've instead just
relied on a clone of the nixpkgs repo. If you do 'git remote add
channels git://github.com/NixOS/nixpkgs-channels.git', then 'git fetch
--all' will pull down channels/nixos-unstable etc. branch pointers,
and you can track them locally very easily. 'nixos-version
--revision' will report the commit hash that your currently-running
system was build from -- very handy for bisects etc. It's also part
of the system derivation name.

Having a local nixpkgs repo lowers the barrier to contributing fixes
back into it, too. :)

I also use the 'nox' tool to preview nixpkgs updates before applying
them. Following is a short script that I wrote to handle it. It
fetches the latest nixos-unstable, checks whether there's anything new
in it, and if so, uses 'nixos-rebuild build' to build (but not swtich
to) it. Then if that succeeds, it uses 'nox-update' to generate a
summary report of the differences between the current system and the
newly-built system. This lets me know what to keep an eye on WRT
possible breakages.

The only major downside of this approach is that I have to always
remember to give '-I nixpkgs=...' arguments to all the usual nix
commands. But that's become pretty second nature to me by now. :)


#!/usr/bin/env bash

set -o errexit
set -o nounset

git fetch --all

current=$(nixos-version --revision);

if git merge-base --is-ancestor channels/nixos-unstable $current; then
echo "current version ($current) already contains latest nixos-unstable";
exit 0;
fi;

d=$(date +%Y-%m-%d-%H-%M)

wt=/home/matt/git/nixos/nixpkgs-update-$d

git worktree add -b update-$d $wt $current

pushd $wt

git merge channels/nixos-unstable -m "Merge remote-tracking branch
'channels/nixos-unstable'";

nixos-rebuild build -I nixpkgs=$wt

echo;
echo "rebuild complete, computing changes";
echo;

nox-update --quiet /run/current-system result | \
grep -v '\.drv : $' | \
sed 's|^ */nix/store/[a-z0-9]*-||' | \
sort -u > \
update-${d}.txt

popd;

mv $wt/update-$d.txt .;

rm -rf $wt;
git worktree prune;

echo;
echo "to review changes:";
echo;
echo "less update-$d.txt";
echo;
echo "to switch to new system:";
echo;
echo "git merge --ff-only update-$d";
echo "sudo nixos-rebuild boot -I nixpkgs=$(pwd)";
echo;
Linus
2017-06-25 06:01:46 UTC
Permalink
Post by Matt McHenry
The only major downside of this approach is that I have to always
remember to give '-I nixpkgs=...' arguments to all the usual nix
commands. But that's become pretty second nature to me by now. :)
You could also set NIX_PATH in one of various locations to avoid having to specify it on every invocation.
Klaas van Schelven
2017-06-26 07:59:02 UTC
Permalink
Linux & Matt: thanks for these further insights. This has all been very
useful!
Post by Linus
Post by Matt McHenry
The only major downside of this approach is that I have to always
remember to give '-I nixpkgs=...' arguments to all the usual nix
commands. But that's become pretty second nature to me by now. :)
You could also set NIX_PATH in one of various locations to avoid having to
specify it on every invocation.
_______________________________________________
nix-dev mailing list
https://mailman.science.uu.nl/mailman/listinfo/nix-dev
--
Klaas van Schelven
+31 6 811 599 10
Roger Qiu
2017-06-26 08:26:03 UTC
Permalink
Oh I wrote a blog post before on the usage of nix env and nix path and
using a custom nixpkgs clone for reproducible nix env and
configuration.nix. You may find it useful:
http://matrix.ai/2017/03/13/intro-to-nix-channels-and-reproducible-nixos-environment/
Post by Klaas van Schelven
Linux & Matt: thanks for these further insights. This has all been very
useful!
Post by Linus
Post by Matt McHenry
The only major downside of this approach is that I have to always
remember to give '-I nixpkgs=...' arguments to all the usual nix
commands. But that's become pretty second nature to me by now. :)
You could also set NIX_PATH in one of various locations to avoid having
to specify it on every invocation.
_______________________________________________
nix-dev mailing list
https://mailman.science.uu.nl/mailman/listinfo/nix-dev
--
Klaas van Schelven
+31 6 811 599 10
_______________________________________________
nix-dev mailing list
https://mailman.science.uu.nl/mailman/listinfo/nix-dev
Loading...