Provide a simple way to log into containers

On the host, you can run

  $ socat unix:<path-to-container>/var/lib/login.socket -,echo=0,raw

to get a login prompt.  So this allows logging in even if the
container has no SSH access enabled.

You can also do

  $ socat unix:<path-to-container>/var/lib/root-shell.socket -

to get a plain root shell.  (This socket is only accessible by root,
obviously.)  This makes it easy to execute commands in the container,
e.g.

  $ echo reboot | socat unix:<path-to-container>/var/lib/root-shell.socket -
switch-to-configuration: Restart sockets.target
switch-to-configuration: Don't require /etc/NIXOS

Check /etc/os-release if /etc/NIXOS doesn't exist.
httpd: Don't require keys.target

This has the unintended side-effect of restarting httpd every time we
run switch-to-configuration, even if httpd hasn't changed (because
we're doing a "stop keys.target" now).  So use a "Wants" dependency
instead.
Add an option to reload rather than restart changed units
Don't reboot a container when its configuration changes

Instead, just run "switch-to-configuration" inside the container.
Give containers a writable /nix/var/nix/{profiles,gcroots}

These are stored on the host in
/nix/var/nix/{profiles,gcroots}/per-container/<container-name> to
ensure that container profiles/roots are not garbage-collected.
Add support for running a container with a private network interface

For example, the following sets up a container named ‘foo’.  The
container will have a single network interface eth0, with IP address
10.231.136.2.  The host will have an interface c-foo with IP address
10.231.136.1.

  systemd.containers.foo =
    { privateNetwork = true;
      hostAddress = "10.231.136.1";
      localAddress = "10.231.136.2";
      config =
        { services.openssh.enable = true; };
    };

With ‘privateNetwork = true’, the container has the CAP_NET_ADMIN
capability, allowing it to do arbitrary network configuration, such as
setting up firewall rules.  This is secure because it cannot touch the
interfaces of the host.

The helper program ‘run-in-netns’ is needed at the moment because ‘ip
netns exec’ doesn't quite do the right thing (it remounts /sys without
bind-mounting the original /sys/fs/cgroups).
Ensure that the container root can always be accessed via /var/lib/containers
Add command ‘nixos-container-shell’ for logging into a container
Don't run dhcpcd in containers
Fix permissions
Rename systemd.containers -> containers

That NixOS containers use systemd-nspawn is just an implementation
detail (which we could change in the future).
nixos-container-shell -> nixos-container { login | root-shell }
Add support for imperative container management

The command nixos-container can now create containers.  For instance,
the following creates and starts a container named ‘database’:

  $ nixos-container create database

The configuration of the container is stored in
/var/lib/containers/<name>/etc/nixos/configuration.nix.  After editing
the configuration, you can make the changes take effect by doing

  $ nixos-container update database

The container can also be destroyed:

  $ nixos-container destroy database

Containers are now executed using a template unit,
‘container@.service’, so the unit in this example would be
‘container@database.service’.
Allow dashes in container names
nixos-container: NixOps helper functions
Remove hard-coded SSH key
Provide nixos-container unconditionally
nixpkgs-lint: Tweak