diff --git a/pkgs/cpio-recursive/default.nix b/pkgs/cpio-recursive/default.nix new file mode 100644 index 0000000..7d9a003 --- /dev/null +++ b/pkgs/cpio-recursive/default.nix @@ -0,0 +1,27 @@ +{ runCommand, nix, jq, path }: +let + map-cpio = ./map-cpio.nix; + + makeCpioRecursive = { name, root, prepend ? [], compressor }: + runCommand "${name}-initrd" { + buildInputs = [ nix jq ]; + requiredSystemFeatures = [ "recursive-nix" ]; + exportReferencesGraph = [ "root" root ]; + NIX_PATH = "nixpkgs=${path}"; + inherit prepend compressor; + } '' + + cat root | grep /nix/store | sort | uniq | jq -R . | jq -s . > paths.json + nix-build ${map-cpio} --arg pathsJson ./paths.json --argstr compressor "$compressor" + + touch initrd + for pre in $prepend; do + cat "$pre" >> initrd + done + + cat result | xargs cat >> initrd + mkdir $out + mv initrd $out/initrd + ''; +in +makeCpioRecursive diff --git a/pkgs/cpio-recursive/map-cpio.nix b/pkgs/cpio-recursive/map-cpio.nix new file mode 100644 index 0000000..04db37f --- /dev/null +++ b/pkgs/cpio-recursive/map-cpio.nix @@ -0,0 +1,25 @@ +{ pathsJson, compressor, pkgs ? import {} }: +let + namePart = strPath: + let + last = list: builtins.elemAt list ((builtins.length list) - 1); + stripPathPrefix = path: last (builtins.split "[/]" path); + in + stripPathPrefix "${strPath}"; + + paths = builtins.fromJSON (builtins.readFile pathsJson); + mkcpio = strPath: pkgs.runCommand "${namePart strPath}-cpio" { + buildInputs = [ pkgs.cpio ]; + } '' + mkdir root + cd root + cp -prd --parents ${builtins.storePath strPath} . + find . -print0 | xargs -0r touch -h -d '@1' + find . -print0 \ + | sort -z \ + | cpio -o -H newc -R +0:+1 --reproducible --null \ + | ${compressor} \ + > $out + ''; +in +pkgs.writeText "cpios" (pkgs.lib.concatMapStringsSep "\n" mkcpio paths) diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 0000000..9401f9a --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,4 @@ +{ callPackage }: +{ + makeCpioRecursive = callPackage ./cpio-recursive {}; +}