liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

base.nix (6524B)


      1 ## Base options
      2 ## ============
      3 
      4 {
      5   lib,
      6   pkgs,
      7   config,
      8   ...
      9 }:
     10 let
     11   inherit (lib) mkOption types;
     12   inherit (pkgs.pseudofile) dir symlink;
     13 
     14   type_service = pkgs.liminix.lib.types.service;
     15 
     16 in
     17 {
     18   options = {
     19     defaultProfile = {
     20       packages = mkOption {
     21         type = types.listOf types.package;
     22         description = ''
     23           List of packages which are available in a login shell. (This
     24           is analogous to systemPackages in NixOS, but we don't symlink into
     25           /run/current-system, we just add the paths in /etc/profile
     26         '';
     27       };
     28     };
     29     services = mkOption {
     30       type = types.attrsOf type_service;
     31     };
     32     system.callService = mkOption {
     33       type = types.functionTo (types.functionTo types.anything);
     34     };
     35     hosts = mkOption {
     36       type = with types; attrsOf (listOf str);
     37       description = "Locally defined IP address to hostname map";
     38       example = {
     39         "127.0.0.1" = [ "foo.bar.baz" ];
     40         "192.168.0.2" = [ "fileserver.local" "nameserver.local" ];
     41       };
     42     };
     43     filesystem = mkOption {
     44       type = types.anything;
     45       description = ''
     46         Skeleton filesystem, represented as nested attrset. Consult the
     47         source code if you need to add to this
     48       '';
     49       # internal = true;  # probably a good case to make this internal
     50     };
     51     rootfsType = mkOption {
     52       default = "squashfs";
     53       type = types.enum [
     54         "btrfs"
     55         "ext4"
     56         "jffs2"
     57         "squashfs"
     58         "ubifs"
     59       ];
     60     };
     61     rootOptions = mkOption {
     62       type = types.nullOr types.str;
     63       default = null;
     64     };
     65 
     66     boot = {
     67       commandLine = mkOption {
     68         type = types.listOf types.nonEmptyStr;
     69         default = [ ];
     70         description = "Kernel command line";
     71       };
     72       commandLineDtbNode = mkOption {
     73         type = types.enum [
     74           "bootargs"
     75           "bootargs-override"
     76         ];
     77         default = "bootargs";
     78         description = "Kernel command line's devicetree node";
     79       };
     80       imageType = mkOption {
     81         type = types.enum [
     82           "primary"
     83           "secondary"
     84         ];
     85         default = "primary";
     86       };
     87       imageFormat = mkOption {
     88         type = types.enum [
     89           "fit"
     90           "uimage"
     91         ];
     92         default = "uimage";
     93       };
     94       tftp = {
     95         loadAddress = mkOption {
     96           type = types.ints.unsigned;
     97           description = ''
     98             RAM address at which to load data when transferring via
     99             TFTP. This is not the address of the flash storage,
    100             nor the kernel load address: it should be set to some part
    101             of RAM that's not used for anything else and suitable for
    102             temporary storage.
    103           '';
    104         };
    105         # These names match the uboot environment variables. I reserve
    106         # the right to change them if I think of better ones.
    107         ipaddr = mkOption {
    108           type = types.str;
    109           description = ''
    110             Our IP address to use when creating scripts to
    111             boot or flash from U-Boot. Not relevant in normal operation
    112           '';
    113         };
    114         serverip = mkOption {
    115           type = types.str;
    116           description = ''
    117             IP address of the TFTP server.  Not relevant in normal operation
    118           '';
    119         };
    120       };
    121     };
    122   };
    123   imports = [ ./early ];
    124   config = {
    125     hosts."127.0.0.1" = [ "localhost" ] ;
    126 
    127     defaultProfile.packages = with pkgs; [
    128       s6
    129       s6-init-bin
    130       execline
    131       s6-linux-init
    132       s6-rc
    133     ];
    134 
    135     boot.commandLine = [
    136       "panic=10 oops=panic init=/bin/init loglevel=8"
    137       "root=${config.hardware.rootDevice}"
    138       "rootfstype=${config.rootfsType}"
    139       "fw_devlink=off"
    140     ]
    141     ++ lib.optional (config.rootOptions != null) "rootflags=${config.rootOptions}";
    142 
    143     system.callService =
    144       path: parameters:
    145       let
    146         typeChecked =
    147           caller: type: value:
    148           let
    149             inherit (lib) types mergeDefinitions;
    150             defs = [
    151               {
    152                 file = caller;
    153                 inherit value;
    154               }
    155             ];
    156             type' = types.submodule { options = type; };
    157           in
    158           (mergeDefinitions [ ] type' defs).mergedValue;
    159         cp = lib.callPackageWith (pkgs // { svc = config.system.service; });
    160         pkg = cp path { };
    161         checkTypes = t: p: typeChecked (builtins.toString path) t p;
    162       in
    163       {
    164         inherit parameters;
    165         build =
    166           {
    167             dependencies ? [ ],
    168             ...
    169           }@args:
    170           let
    171             s = pkg (checkTypes parameters (builtins.removeAttrs args [ "dependencies" ]));
    172           in
    173           s.overrideAttrs (o: {
    174             dependencies = dependencies ++ o.dependencies;
    175             buildInputs = dependencies ++ o.buildInputs;
    176           });
    177       };
    178 
    179     users.root = {
    180       uid = 0;
    181       gid = 0;
    182       gecos = "Root of all evaluation";
    183       dir = "/home/root/";
    184       passwd = lib.mkDefault "";
    185       shell = "/bin/sh";
    186     };
    187     groups = {
    188       root = {
    189         gid = 0;
    190         usernames = [ "root" ];
    191       };
    192       system = {
    193         gid = 1;
    194         usernames = [ "root" ];
    195       };
    196     };
    197 
    198     early.sysctl.net.ipv6.conf =
    199       let
    200         v = {
    201           autoconf = 0;
    202           accept_ra = 0;
    203         };
    204       in
    205       {
    206         default = v; # sets values for new interfaces
    207         all = v; # probably does nothing
    208       };
    209 
    210     filesystem = dir {
    211       dev =
    212         let
    213           node = type: major: minor: mode: {
    214             inherit
    215               type
    216               major
    217               minor
    218               mode
    219               ;
    220           };
    221         in
    222         dir {
    223           null = node "c" "1" "3" "0666";
    224           zero = node "c" "1" "5" "0666";
    225           tty = node "c" "5" "0" "0666";
    226           console = node "c" "5" "1" "0600";
    227           pts = dir { };
    228         };
    229       etc =
    230         let
    231           profile = symlink (
    232             pkgs.writeScript ".profile" ''
    233               PATH=${lib.makeBinPath config.defaultProfile.packages}:/bin
    234                export PATH
    235             ''
    236           );
    237           hosts = symlink (
    238             pkgs.writeText "hosts" (
    239               lib.concatMapAttrsStringSep ""
    240                 (n: v: "${n}  ${lib.concatStringsSep " " v}\n")
    241                 config.hosts
    242             )
    243           );
    244         in
    245         dir {
    246           inherit hosts profile;
    247           ashrc = profile;
    248         };
    249 
    250       proc = dir { };
    251       run = dir { };
    252       sys = dir { };
    253       tmp = dir { };
    254     };
    255   };
    256 }