diff --git a/morph/README.rst b/morph/README.rst index d008f07bd7c514da4d6808acf5a503087e03dfa5..33062489c50a1d364a1f249ed8e8a5af755b56d9 100644 --- a/morph/README.rst +++ b/morph/README.rst @@ -7,6 +7,13 @@ and some JSON-based configuration in ``.config.json`` files. This configuration is fed to `morph`_ to make changes to the deployment. +bootstrap-configuration.nix +--------------------------- + +This is meant as a minimal system configuration to use as part of crossgrading a Debian install to NixOS. +It has a lot of comments explaining different parts of Nix and NixOS. +You may want to browse it before looking at other ``.nix`` files here. + grid.config.json ---------------- @@ -23,4 +30,23 @@ You can do things like build the network:: morph build grid.nix +<hostname>-hardware.nix +----------------------- + +These are the generated hardware-related configuration files for servers in the grid. +These files are referenced from the corresponding ``<hostname>.nix`` files. + +<hostname>-config.nix +--------------------- + +Each such file contains a minimal Nix expression supplying critical system configuration details. +"Critical" roughly corresponds to anything which must be specified to have a bootable system. +These files are referenced by the corresponding ``<hostname>.nix`` files. + +<hostname>.nix +-------------- + +Each such file contains the parts of the system configuration that aren't *so* related to hardware. +They are referenced from ``grid.nix``. + .. _`morph`: https://github.com/DBCDK/morph diff --git a/morph/staging002.nix b/morph/staging002.nix index 443c127d55b1bbea82078f60167798b639d1f1f8..df0f2e9a04846c8b85f515ca07bce8745f26de92 100644 --- a/morph/staging002.nix +++ b/morph/staging002.nix @@ -1,12 +1,18 @@ -{ config, pkgs, ... }: -{ imports = +{ ... }: +{ + imports = [ # Include the results of the hardware scan. ./staging002-hardware.nix # Configure it as a system operated by 100TB. - # Instance details are read from <hostName>.config.json ../nixos/modules/100tb.nix ]; + # Pass the configuration specific to this host to the 100TB module to be + # expanded into a complete system configuration. See the 100tb module for + # handling of this value. + # + # The module name is quoted because `1` makes `100tb` look an awful lot like + # it should be a number. "100tb".config = import ./staging002-config.nix; # This value determines the NixOS release with which your system is to be diff --git a/nixos/modules/100tb.nix b/nixos/modules/100tb.nix index c701acd7001545809146ca97cad50e10d82d3862..243da0dd72913ed4f582b52ca5cfe0494936c744 100644 --- a/nixos/modules/100tb.nix +++ b/nixos/modules/100tb.nix @@ -1,7 +1,36 @@ -# A NixOS module which configures a system that is hosted by 100TB. -{ pkgs, lib, config, ... }: +# A NixOS module which configures a system that is hosted by 100TB. Each of +# our servers hosted with 100TB will probably import this module and pass it +# the minimum system configuration to get the server to boot and accept +# administrative ssh connections. +# +# A NixOS module is defined as a Nix expression language function. +{ + # This contains generally useful library functionality provided by nixpkgs. + # These are things like string manipulation and, notably for us, a library + # for defining options for configuring moduless. + lib, + + # This is all of the configuration for a particular system where this module + # might be instantiated. For any system where we want the 100TB module to + # be active, this should have the 100TB configuration details (IP, gateway, + # etc). + config, + + # More parameters exist and are accepted but we don't need them so we ignore them. + ... +}: let + # Pull out the configuration for this module for convenient use later. The + # module name is quoted because `1` makes `100tb` look an awful lot like it + # should be a number. cfg = config."100tb".config; + + # Define the API to this module. Everything in `options` is about + # specifying what kind of values we expect to be given. This is both + # human-facing documentation as well as guidance to NixOS about acceptable + # values (mainly by type) so it can automatically reject certain bogus + # values. This value is in the `let` to make the code below a little easier + # to read. See below where we use it. options = { interface = lib.mkOption { type = lib.types.str; @@ -42,6 +71,9 @@ let }; }; in { + # Here we actually define the module's options. They're what we said they + # were above, all bundled up into a "submodule" which is really just a set + # of options. options = { "100tb".config = lib.mkOption { type = lib.types.submodule { inherit options; }; @@ -49,16 +81,31 @@ in { }; }; + # Now compute the configuration that results from whatever values were + # supplied for our options. A lot of this is currently very similar to + # what's in bootstrap-configuration.nix (which is well commented). The + # similarity makes sense - both that configuration and this one need to get + # a 100TB machine to boot and let an admin SSH in. + # + # Values that go into `config` here are merged into values that go into + # `config` in any other active modules. Basically, everything in this + # `config` is treated as if it were in the configuration set defined by + # `/etc/nixos/configuration.nix`. The module just gives us a way to factor + # separate concerns separately and make reuse easier. + # + # Note that this is not where Tahoe-LAFS configuration goes. It's just + # about getting base platform into good shape. + # + # Perhaps at some point this can be refactored to remove the duplication. + # It's slightly tricky because we don't want to introduce any external + # dependencies to bootstrap-configuration.nix because that would make it + # harder to deploy in the bootstrap environment. config = { boot.loader.grub.enable = true; boot.loader.grub.version = 2; boot.loader.grub.device = "/dev/disk/by-id/${cfg.grubDeviceID}"; - # Get a slightly faster boot time than default. Maybe this could even be - # 0 but I'm not sure. boot.loader.timeout = 1; - - # Let me in to do subsequent configuration. networking.firewall.enable = false; services.openssh.enable = true; @@ -66,7 +113,6 @@ in { cfg.rootPublicKey ]; - # Provide the static network configuration. networking.dhcpcd.enable = false; networking.interfaces = { "${cfg.interface}".ipv4.addresses = [