liminix

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

default.nix (2945B)


      1 # The ideal is that a Liminix system can boot with only the files in
      2 # /nix/store.  This package generates a small program that is run at early
      3 # boot (from the initramfs) to populate directories such as /etc,
      4 # /bin, /home according to whatever the configuration says
      5 # they should contain
      6 
      7 {
      8   writeText
      9 , lib
     10 , s6-init-bin
     11 , closureInfo
     12 , stdenv
     13 }:
     14 let
     15   inherit (lib.attrsets) mapAttrsToList;
     16   escaped = msg : builtins.replaceStrings
     17     ["\n"  "="   "\""  "$"  ]
     18     ["\\x0a" "\\x3d" "\\x22" "\\x24"]
     19     msg;
     20 
     21   visit = prefix: attrset:
     22     let makeFile = prefix : filename: {
     23           type ? "f"
     24           , mode ? null
     25           , target ? null
     26           , contents ? null
     27           , file ? null
     28           , major ? null
     29           , minor ? null
     30           , uid ? 0
     31           , gid ? 0
     32         }:
     33           let
     34             pathname = "${prefix}/${filename}";
     35             qpathname = builtins.toJSON pathname;
     36             mode' = if mode != null
     37                     then mode
     38                     else
     39                       (if type == "d" then "0755" else "0644");
     40             cmds = {
     41               "f" = "PRINTFILE(${qpathname}, ${mode'}, ${builtins.toJSON (escaped file)});";
     42               "d" = "MKDIR(${qpathname}, ${mode'});\n"  +
     43                     (builtins.concatStringsSep "\n"
     44                       (visit pathname contents));
     45               "c" = "MKNOD_C(${qpathname}, ${mode'}, ${major}, ${minor});";
     46               "b" = "MKNOD_B(${qpathname}, ${mode'}, ${major}, ${minor});";
     47               "s" = "LN_S(${builtins.toJSON target}, ${qpathname});";
     48               "l" = "LN(${builtins.toJSON target}, ${qpathname})";
     49               "i" = "MKNOD_P(${qpathname}, ${mode'});";
     50             };
     51             cmd = cmds.${type};
     52             chown = if uid>0 || gid>0
     53                     then "\nCHOWN(${qpathname},${toString uid},${toString gid});\n"
     54                     else "";
     55           in "${cmd} ${chown}";
     56     in mapAttrsToList (makeFile prefix) attrset;
     57   activateScript = attrset: writeText "makedevs.c" ''
     58     #include "defs.h"
     59     int main(int argc, char* argv[]) {
     60       chdir(argv[1]);
     61       ${(builtins.concatStringsSep "\n" (visit "." attrset))}
     62     }
     63   '';
     64 in attrset:
     65   let makedevs = activateScript attrset;
     66   in stdenv.mkDerivation {
     67     name="make-stuff";
     68     src = ./.;
     69 
     70     CFLAGS = "-Os";
     71     LDFLAGS  = "-static -Xlinker -static";
     72 
     73     postConfigure = ''
     74       cp ${makedevs} makedevs.c
     75     '';
     76     makeFlags = ["makedevs"];
     77     installPhase = ''
     78       closure=${closureInfo { rootPaths = [ makedevs ]; }}
     79       mkdir -p $out/bin $out/etc
     80       cp $closure/store-paths $out/etc/nix-store-paths
     81       $STRIP --remove-section=.note  --remove-section=.comment --strip-all makedevs -o $out/bin/activate
     82       ln -s ${s6-init-bin}/bin/init $out/bin/init
     83       cat > $out/bin/install <<EOF
     84       #!/bin/sh
     85       cp -v -fP $out/bin/* $out/etc/* \''${1-/}/persist
     86       EOF
     87       chmod +x $out/bin/install
     88     '';
     89   }