patos/lib/make-sysext.nix

162 lines
4.6 KiB
Nix

{
lib,
runCommand,
pkgs,
name,
packages,
services ? [],
osId ? "patos",
version ? null,
}:
let
metadata = {
ID = osId;
VERSION_ID = osId;
IMAGE_ID = name;
IMAGE_VERSION = version;
} // lib.optionalAttrs (services != []) { EXTENSION_RELOAD_MANAGER = "1"; };
metadataFile = lib.concatStringsSep "\n" (
lib.mapAttrsToList (k: v: "${k}=${v}") (lib.filterAttrs (_: v: v != null) metadata)
);
doCopy =
{
drv,
prefix ? "usr",
path,
destpath ? null,
}:
"do_copy ${prefix} ${drv} ${path} ${drv.name} " + builtins.concatStringsSep "," (map (l: l.shortName or "unknown") (lib.toList (drv.meta.license or []))) + lib.optionalString (destpath != null) " ${destpath}";
in
runCommand name
{
passthru.name = name;
inherit metadataFile;
passAsFile = [ "metadataFile" ];
nativeBuildInputs = [
pkgs.erofs-utils
pkgs.cryptsetup
pkgs.gawk
pkgs.jq
];
}
''
set -ex -o pipefail
do_copy () {
local prefix="$1"
local drv="$2"
local path="$3"
local pkgname="$4"
local license="$5"
local destpath="''${6:-$path}"
local srcfile
local destdir
local destfile
srcfile="$drv/$path"
destfile="$out/tree/$prefix/$destpath"
destdir="$(dirname -- "$destfile")"
echo "pkgname=\"$pkgname\",licenses=\""$license"\"" >> $out/.tmp-pkgs.txt
mkdir -pv "$destdir"
# recursively copy if ending with /
if [[ "$destfile" =~ /$ ]]; then
basedir="$(dirname -- "$destfile")"
chmod -R 755 "$basedir"
# remove if exists
for f in $srcfile/*; do
basename="$(basename -- "$f")"
rm -rf "$destfile/$basename"
done
cp -rPv "$srcfile" "$basedir"
chmod -R 755 "$basedir"
for f in $destfile/*; do
interpreter=$(patchelf --print-interpreter $f || echo "")
[ -n "$interpreter" ] && ldLinux=$(basename $interpreter)
patchelf --set-interpreter /lib/$ldLinux $f || true
patchelf --set-rpath /usr/lib $f || true
done
return
fi
cp -Pv "$srcfile" "$destfile"
chmod 755 "$destfile"
interpreter=$(patchelf --print-interpreter $destfile || echo "")
[ -n "$interpreter" ] && ldLinux=$(basename $interpreter)
patchelf --set-rpath /usr/lib $destfile || true
patchelf --set-interpreter /lib/$ldLinux $destfile || true
}
do_service () {
local unit="$1"
local content="$2"
local unit_file="$out/tree/usr/lib/systemd/system/$unit"
mkdir -p $out/tree/usr/lib/systemd/system
echo "$content" > $unit_file
# look for [Install] section and WantedBy in unit
if ! grep -q "^\[Install\]" "$unit_file"; then
echo "No [Install] section found in $unit_file"
return
fi
local wanted_by=$(sed -n '/^\[Install\]/,/^\[/{/^WantedBy=/s/^WantedBy=//p}' "$unit_file")
if [ -z "$wanted_by" ]; then
echo "No WantedBy found in [Install] section of $unit_file"
exit 1
fi
mkdir -p $out/tree/usr/lib/systemd/system/"$wanted_by".wants
ln -s ../$unit $out/tree/usr/lib/systemd/system/"$wanted_by".wants/$unit
}
mkdir -p $out/tree
${lib.concatStringsSep "\n" (map doCopy packages)}
${lib.concatStringsSep "\n" (map (service: "do_service '${service.unit}' '${service.content}'") services)}
# bake metadata into the structure
if ! [ -f $out/tree/usr/lib/extension-release.d/extension-release."${name}" ]; then
mkdir -p $out/tree/usr/lib/extension-release.d
cat "$metadataFilePath" > $out/tree/usr/lib/extension-release.d/extension-release."${name}"
fi
pushd $out
find tree -type d -exec chmod 0755 {} \;
mkfs.erofs -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking --all-root $name.raw tree/
veritysetup format --root-hash-file $name.roothash $name.raw $name.verity
# TODO: pcks7 signature
# openssl smime -sign -nocerts -noattr -binary -in ${name}.roothash \
# -inkey key.pem -signer cert.pem -outform der -out ${name}.roothash.p7s
# create contents list
pushd tree
find . -ls > $out/"$name"_contents.txt
popd
# create nixpkgs packages list
sort -u $out/.tmp-pkgs.txt > $out/"$name"_packages.txt
rm -f $out/.tmp-pkgs.txt
jq -R -s 'split("\n") | map(select(length > 0)) | map(capture("pkgname=\"(?<name>[^\"]*)\",licenses=\"(?<licenses>[^\"]*)\"") | .licenses |= split(",")) | map(select(. != null))' $out/"$name"_packages.txt > $out/"$name"_packages.json
rm -rf tree
sha256sum * > SHA256SUMS
ln -s SHA256SUMS SHA256SUMS.asc
# TODO: add gpg signature
popd
''