This is a standard environment that doesn't contain a C/C++
compiler. This is mostly to prevent trivial builders like runCommand
and substituteAll from pulling in gcc for simple configuration changes
on NixOS.
This patch adds handling of a directory becoming a symlink in
/etc. Before this patch, the directory wasn't removed and then
symlinking failed, which caused directory not being updated at all.
The idea for the patch goes to @abbradar at
https://github.com/NixOS/nixpkgs/issues/16978#issuecomment-232921903:
> A heuristic idea for this -- a function `isStatic :: Path -> Bool`:
>
> * if path `/etc/foo` is a file, return True iff it's a symlink to `/etc/static/foo`.
> * if path is a directory, return True iff for all items in it `isStatic` is True.
>
> On any conflicts, if old path is static, it's safe to replace and/or
> delete stale. Otherwise make a backup and notify the user via a
> journal entry and console output.
The only difference here -- it will not replace user configs.
This also fixes https://github.com/NixOS/nixpkgs/issues/16978.
A user noticed the example for `hosts`, took the `mode` permissions literally, and ended up with surprising behavior on their system. Updating the documentation to not reference a real config file which might have real permissions requirements.
We now track copied files in /etc/.clean. This is important, because
otherwise files that are removed from environment.etc will not
actually be removed from the file system. In particular, changing
users.extraUsers.<user>.openssh.authorizedKeys.keys to an empty list
would not cause /etc/ssh/authorized_keys.d/<user> to be removed, which
was a security issue.
Using pkgs.lib on the spine of module evaluation is problematic
because the pkgs argument depends on the result of module
evaluation. To prevent an infinite recursion, pkgs and some of the
modules are evaluated twice, which is inefficient. Using ‘with lib’
prevents this problem.
Some programs (notably the Java Runtime Environment) expect to be able
to extract the name of the time zone from the target of the
/etc/localtime symlink. That doesn't work if /etc/localtime is a
symlink to /etc/static/localtime. So make it a direct symlink.