2023-04-04 22:35:49 +00:00
|
|
|
# The ideal is that a Liminix system can boot with only the files in
|
2023-04-15 16:15:44 +00:00
|
|
|
# /nix/store. This package generates a small program that is run at early
|
2023-04-04 22:35:49 +00:00
|
|
|
# boot (from the initramfs) to populate directories such as /etc,
|
|
|
|
# /bin, /home according to whatever the configuration says
|
|
|
|
# they should contain
|
|
|
|
|
|
|
|
{
|
2024-06-30 15:58:29 +00:00
|
|
|
writeText,
|
2024-08-30 19:57:42 +00:00
|
|
|
writeFennel,
|
2024-06-30 15:58:29 +00:00
|
|
|
lib,
|
|
|
|
s6-init-bin,
|
|
|
|
closureInfo,
|
|
|
|
stdenv,
|
2023-04-04 22:35:49 +00:00
|
|
|
}:
|
|
|
|
let
|
|
|
|
inherit (lib.attrsets) mapAttrsToList;
|
|
|
|
escaped = msg : builtins.replaceStrings
|
|
|
|
["\n" "=" "\"" "$" ]
|
|
|
|
["\\x0a" "\\x3d" "\\x22" "\\x24"]
|
|
|
|
msg;
|
|
|
|
|
|
|
|
visit = prefix: attrset:
|
|
|
|
let makeFile = prefix : filename: {
|
|
|
|
type ? "f"
|
|
|
|
, mode ? null
|
|
|
|
, target ? null
|
|
|
|
, contents ? null
|
|
|
|
, file ? null
|
|
|
|
, major ? null
|
|
|
|
, minor ? null
|
2023-04-14 22:19:56 +00:00
|
|
|
, uid ? 0
|
|
|
|
, gid ? 0
|
2023-04-04 22:35:49 +00:00
|
|
|
}:
|
|
|
|
let
|
|
|
|
pathname = "${prefix}/${filename}";
|
2023-04-15 16:15:44 +00:00
|
|
|
qpathname = builtins.toJSON pathname;
|
|
|
|
mode' = if mode != null
|
|
|
|
then mode
|
|
|
|
else
|
|
|
|
(if type == "d" then "0755" else "0644");
|
2023-04-04 22:35:49 +00:00
|
|
|
cmds = {
|
2023-04-15 16:15:44 +00:00
|
|
|
"f" = "PRINTFILE(${qpathname}, ${mode'}, ${builtins.toJSON (escaped file)});";
|
|
|
|
"d" = "MKDIR(${qpathname}, ${mode'});\n" +
|
2023-04-04 22:35:49 +00:00
|
|
|
(builtins.concatStringsSep "\n"
|
|
|
|
(visit pathname contents));
|
2023-04-15 16:15:44 +00:00
|
|
|
"c" = "MKNOD_C(${qpathname}, ${mode'}, ${major}, ${minor});";
|
|
|
|
"b" = "MKNOD_B(${qpathname}, ${mode'}, ${major}, ${minor});";
|
|
|
|
"s" = "LN_S(${builtins.toJSON target}, ${qpathname});";
|
|
|
|
"l" = "LN(${builtins.toJSON target}, ${qpathname})";
|
|
|
|
"i" = "MKNOD_P(${qpathname}, ${mode'});";
|
2023-04-04 22:35:49 +00:00
|
|
|
};
|
|
|
|
cmd = cmds.${type};
|
2023-04-15 21:53:28 +00:00
|
|
|
chown = if uid>0 || gid>0
|
|
|
|
then "\nCHOWN(${qpathname},${toString uid},${toString gid});\n"
|
|
|
|
else "";
|
2024-03-28 23:45:10 +00:00
|
|
|
in "unlink(${qpathname}); ${cmd} ${chown}";
|
2023-04-04 22:35:49 +00:00
|
|
|
in mapAttrsToList (makeFile prefix) attrset;
|
2023-04-15 16:15:44 +00:00
|
|
|
activateScript = attrset: writeText "makedevs.c" ''
|
|
|
|
#include "defs.h"
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
chdir(argv[1]);
|
|
|
|
${(builtins.concatStringsSep "\n" (visit "." attrset))}
|
|
|
|
}
|
2023-04-04 22:35:49 +00:00
|
|
|
'';
|
|
|
|
in attrset:
|
2023-05-19 22:53:29 +00:00
|
|
|
let makedevs = activateScript attrset;
|
|
|
|
in stdenv.mkDerivation {
|
2023-04-15 16:15:44 +00:00
|
|
|
name="make-stuff";
|
|
|
|
src = ./.;
|
|
|
|
|
|
|
|
CFLAGS = "-Os";
|
2023-10-16 18:55:17 +00:00
|
|
|
LDFLAGS = "-static -Xlinker -static";
|
2023-04-15 16:15:44 +00:00
|
|
|
|
|
|
|
postConfigure = ''
|
2023-05-19 22:53:29 +00:00
|
|
|
cp ${makedevs} makedevs.c
|
2023-04-15 16:15:44 +00:00
|
|
|
'';
|
|
|
|
makeFlags = ["makedevs"];
|
|
|
|
installPhase = ''
|
2023-05-19 22:53:29 +00:00
|
|
|
closure=${closureInfo { rootPaths = [ makedevs ]; }}
|
|
|
|
mkdir -p $out/bin $out/etc
|
|
|
|
cp $closure/store-paths $out/etc/nix-store-paths
|
2023-04-15 21:53:28 +00:00
|
|
|
$STRIP --remove-section=.note --remove-section=.comment --strip-all makedevs -o $out/bin/activate
|
2023-05-17 14:03:45 +00:00
|
|
|
ln -s ${s6-init-bin}/bin/init $out/bin/init
|
2024-08-30 19:57:42 +00:00
|
|
|
cp -p ${writeFennel "restart-services" {} ./restart-services.fnl} $out/bin/restart-services
|
2023-12-23 23:53:47 +00:00
|
|
|
cat > $out/bin/install <<EOF
|
2024-01-07 16:44:36 +00:00
|
|
|
#!/bin/sh -e
|
|
|
|
prefix=\''${1-/}
|
|
|
|
src=\''${prefix}$out
|
2024-01-08 18:58:07 +00:00
|
|
|
dest=\$prefix
|
|
|
|
${# if we are running on a normal mounted system then
|
|
|
|
# the actual device root is mounted on /persist
|
|
|
|
# and /nix is bind mounted from /persist/nix
|
|
|
|
# (see the code in preinit). So we need to check for this
|
|
|
|
# case otherwise we will install into a ramfs/rootfs
|
|
|
|
""
|
|
|
|
}
|
2024-02-04 17:19:03 +00:00
|
|
|
if test -d \$dest/persist; then dest=\$dest/persist; fi
|
2024-01-08 18:58:07 +00:00
|
|
|
cp -v -fP \$src/bin/* \$src/etc/* \$dest
|
|
|
|
${if attrset ? boot then ''
|
2024-02-04 17:19:03 +00:00
|
|
|
(cd \$dest
|
|
|
|
if test -e boot ; then rm boot ; fi
|
|
|
|
ln -sf ${lib.strings.removePrefix "/" attrset.boot.target} ./boot
|
|
|
|
)
|
2024-01-08 18:58:07 +00:00
|
|
|
'' else ""}
|
2023-12-23 23:53:47 +00:00
|
|
|
EOF
|
|
|
|
chmod +x $out/bin/install
|
2023-04-15 16:15:44 +00:00
|
|
|
'';
|
|
|
|
}
|