liminix

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

base.nix (5700B)


      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 
     36     filesystem = mkOption {
     37       type = types.anything;
     38       description = ''
     39         Skeleton filesystem, represented as nested attrset. Consult the
     40         source code if you need to add to this
     41       '';
     42       # internal = true;  # probably a good case to make this internal
     43     };
     44     rootfsType = mkOption {
     45       default = "squashfs";
     46       type = types.enum [
     47         "btrfs"
     48         "ext4"
     49         "jffs2"
     50         "squashfs"
     51         "ubifs"
     52       ];
     53     };
     54     rootOptions = mkOption {
     55       type = types.nullOr types.str;
     56       default = null;
     57     };
     58 
     59     boot = {
     60       commandLine = mkOption {
     61         type = types.listOf types.nonEmptyStr;
     62         default = [ ];
     63         description = "Kernel command line";
     64       };
     65       commandLineDtbNode = mkOption {
     66         type = types.enum [
     67           "bootargs"
     68           "bootargs-override"
     69         ];
     70         default = "bootargs";
     71         description = "Kernel command line's devicetree node";
     72       };
     73       imageType = mkOption {
     74         type = types.enum [
     75           "primary"
     76           "secondary"
     77         ];
     78         default = "primary";
     79       };
     80       imageFormat = mkOption {
     81         type = types.enum [
     82           "fit"
     83           "uimage"
     84         ];
     85         default = "uimage";
     86       };
     87       tftp = {
     88         loadAddress = mkOption {
     89           type = types.ints.unsigned;
     90           description = ''
     91             RAM address at which to load data when transferring via
     92             TFTP. This is not the address of the flash storage,
     93             nor the kernel load address: it should be set to some part
     94             of RAM that's not used for anything else and suitable for
     95             temporary storage.
     96           '';
     97         };
     98         # These names match the uboot environment variables. I reserve
     99         # the right to change them if I think of better ones.
    100         ipaddr = mkOption {
    101           type = types.str;
    102           description = ''
    103             Our IP address to use when creating scripts to
    104             boot or flash from U-Boot. Not relevant in normal operation
    105           '';
    106         };
    107         serverip = mkOption {
    108           type = types.str;
    109           description = ''
    110             IP address of the TFTP server.  Not relevant in normal operation
    111           '';
    112         };
    113       };
    114     };
    115   };
    116   config = {
    117     defaultProfile.packages = with pkgs; [
    118       s6
    119       s6-init-bin
    120       execline
    121       s6-linux-init
    122       s6-rc
    123     ];
    124 
    125     boot.commandLine = [
    126       "panic=10 oops=panic init=/bin/init loglevel=8"
    127       "root=${config.hardware.rootDevice}"
    128       "rootfstype=${config.rootfsType}"
    129       "fw_devlink=off"
    130     ] ++ lib.optional (config.rootOptions != null) "rootflags=${config.rootOptions}";
    131 
    132     system.callService =
    133       path: parameters:
    134       let
    135         typeChecked =
    136           caller: type: value:
    137           let
    138             inherit (lib) types mergeDefinitions;
    139             defs = [
    140               {
    141                 file = caller;
    142                 inherit value;
    143               }
    144             ];
    145             type' = types.submodule { options = type; };
    146           in
    147           (mergeDefinitions [ ] type' defs).mergedValue;
    148         cp = lib.callPackageWith (pkgs // { svc = config.system.service; });
    149         pkg = cp path { };
    150         checkTypes = t: p: typeChecked (builtins.toString path) t p;
    151       in
    152       {
    153         inherit parameters;
    154         build =
    155           {
    156             dependencies ? [ ],
    157             ...
    158           }@args:
    159           let
    160             s = pkg (checkTypes parameters (builtins.removeAttrs args [ "dependencies" ]));
    161           in
    162           s.overrideAttrs (o: {
    163             dependencies = dependencies ++ o.dependencies;
    164             buildInputs = dependencies ++ o.buildInputs;
    165           });
    166       };
    167 
    168     users.root = {
    169       uid = 0;
    170       gid = 0;
    171       gecos = "Root of all evaluation";
    172       dir = "/home/root/";
    173       passwd = lib.mkDefault "";
    174       shell = "/bin/sh";
    175     };
    176     groups = {
    177       root = {
    178         gid = 0;
    179         usernames = [ "root" ];
    180       };
    181       system = {
    182         gid = 1;
    183         usernames = [ "root" ];
    184       };
    185     };
    186 
    187     filesystem = dir {
    188       dev =
    189         let
    190           node = type: major: minor: mode: {
    191             inherit
    192               type
    193               major
    194               minor
    195               mode
    196               ;
    197           };
    198         in
    199         dir {
    200           null = node "c" "1" "3" "0666";
    201           zero = node "c" "1" "5" "0666";
    202           tty = node "c" "5" "0" "0666";
    203           console = node "c" "5" "1" "0600";
    204           pts = dir { };
    205         };
    206       etc =
    207         let
    208           profile = symlink (
    209             pkgs.writeScript ".profile" ''
    210               PATH=${lib.makeBinPath config.defaultProfile.packages}:/bin
    211                export PATH
    212             ''
    213           );
    214         in
    215         dir {
    216           inherit profile;
    217           ashrc = profile;
    218         };
    219 
    220       proc = dir { };
    221       run = dir { };
    222       sys = dir { };
    223       tmp = dir { };
    224     };
    225   };
    226 }