162 lines
4.6 KiB
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
|
|
''
|