85 lines
2 KiB
Nix
85 lines
2 KiB
Nix
![]() |
{
|
||
|
lib,
|
||
|
erofs-utils,
|
||
|
runCommand,
|
||
|
python3Minimal,
|
||
|
bubblewrap,
|
||
|
writeClosure,
|
||
|
}:
|
||
|
{
|
||
|
name ? "${label}.erofs",
|
||
|
label ? "image",
|
||
|
roots ? [ ],
|
||
|
rootsExclude ? [ ],
|
||
|
erofsArgs ? [
|
||
|
"--mount-point=/nix/store"
|
||
|
"-z"
|
||
|
"lz4hc,level=3"
|
||
|
"-T0"
|
||
|
"-L"
|
||
|
label
|
||
|
"--all-root"
|
||
|
],
|
||
|
...
|
||
|
}@attrs:
|
||
|
|
||
|
let
|
||
|
old = writeClosure rootsExclude;
|
||
|
new = writeClosure roots;
|
||
|
attrs' = lib.removeAttrs [ "name" "roots" "rootsExclude" "erofsArgs" ] attrs;
|
||
|
in
|
||
|
runCommand name
|
||
|
(
|
||
|
attrs
|
||
|
// {
|
||
|
__structuredAttrs = true;
|
||
|
inherit name label;
|
||
|
unsafeDiscardReferences.out = true;
|
||
|
nativeBuildInputs = [
|
||
|
erofs-utils
|
||
|
bubblewrap
|
||
|
python3Minimal
|
||
|
]
|
||
|
++ attrs.nativeBuildInputs or [ ];
|
||
|
inherit old new erofsArgs;
|
||
|
}
|
||
|
)
|
||
|
''
|
||
|
mkdir -p store
|
||
|
python3 << EOF
|
||
|
import hashlib, json, os, subprocess
|
||
|
from uuid import UUID
|
||
|
|
||
|
|
||
|
def uuid_from_node(node: int = 0) -> UUID:
|
||
|
return UUID(fields=(*((0,) * 5), node))
|
||
|
|
||
|
|
||
|
out_path = os.environ.get("out")
|
||
|
default_uuid = uuid_from_node((2**48 - 1) & int.from_bytes(hashlib.sha256(out_path.encode("ascii")).digest()))
|
||
|
with open(os.environ.get("NIX_ATTRS_JSON_FILE"), mode="r") as f:
|
||
|
attrs = json.load(f)
|
||
|
name = attrs["name"]
|
||
|
with open(attrs["old"], mode="r") as f:
|
||
|
old_paths = set(ln.rstrip() for ln in f)
|
||
|
with open(attrs["new"], mode="r") as f:
|
||
|
new_paths = [ln.rstrip() for ln in f]
|
||
|
new_paths = [p for p in new_paths if p not in old_paths]
|
||
|
erofs_args = attrs.get("erofsArgs", [])
|
||
|
if not any(a.startswith("-U") for a in erofs_args):
|
||
|
erofs_args.extend(["-U", str(default_uuid)])
|
||
|
subprocess.run(
|
||
|
check=True,
|
||
|
env=os.environ,
|
||
|
args=[
|
||
|
"bwrap",
|
||
|
"--dev-bind", "/", "/",
|
||
|
"--chdir", os.getcwd(),
|
||
|
*[a for p in new_paths for a in [f"--ro-bind", p, f"{os.getcwd()}/store/{os.path.basename(p)}"]],
|
||
|
"--",
|
||
|
"mkfs.erofs", *attrs.get("erofsArgs", []), out_path, "store",
|
||
|
],
|
||
|
)
|
||
|
EOF
|
||
|
''
|