Modify type of ERIS­manifest

Convert the manifest to have a more general type.
This commit is contained in:
Ehmry - 2023-09-28 11:49:50 +01:00
parent 4d3d152f50
commit ccc2f4f79f
9 changed files with 136 additions and 78 deletions

View File

@ -60,11 +60,19 @@ let
manifest = fromJSON (unsafeDiscardStringContext manifest = fromJSON (unsafeDiscardStringContext
(readFile "${pkg}/nix-support/eris-manifest.json")); (readFile "${pkg}/nix-support/eris-manifest.json"));
entry = manifest.${filename}; entry = manifest.${filename};
in entry // { in {
cap = "(${pkg}/nix-support/eris-manifest.dhall).${filename}.cap"; inherit (entry) cap;
closure = map (ce:
if ce.cap == entry.cap then
ce // {
# hack to build a string with context to propagate a
# dependency on the rest of the closure
path = "${pkg}${ path = "${pkg}${
substring (stringLength pkg) (stringLength entry.path) entry.path substring (stringLength pkg) (stringLength ce.path) ce.path
}"; # hack to build a string with context }";
}
else
ce) entry.closure;
}; };
getErisMainProgram = pkg: getErisMainProgram = pkg:

View File

@ -12,7 +12,8 @@
nixConfig = { nixConfig = {
extra-substituters = [ "https://sigil.cachix.org" ]; extra-substituters = [ "https://sigil.cachix.org" ];
extra-trusted-public-keys = [ "sigil.cachix.org-1:poBTiAr1x94vX0ONljw+R22Hmxd5rtHi9UYdHlRaWoM=" ]; extra-trusted-public-keys =
[ "sigil.cachix.org-1:poBTiAr1x94vX0ONljw+R22Hmxd5rtHi9UYdHlRaWoM=" ];
}; };
outputs = { self, eris, nixpkgs, nimble }: outputs = { self, eris, nixpkgs, nimble }:
@ -84,14 +85,21 @@
manifest = fromJSON (unsafeDiscardStringContext manifest = fromJSON (unsafeDiscardStringContext
(readFile "${pkg}/nix-support/eris-manifest.json")); (readFile "${pkg}/nix-support/eris-manifest.json"));
entry = manifest.${filename}; entry = manifest.${filename};
in entry // { in {
cap = "(${pkg}/nix-support/eris-manifest.dhall).${filename}.cap"; inherit (entry) cap;
closure = map (ce:
if ce.cap == entry.cap then
ce // {
# hack to build a string with context to propagate a
# dependency on the rest of the closure
path = "${pkg}${ path = "${pkg}${
substring (stringLength pkg) (stringLength entry.path) substring (stringLength pkg) (stringLength ce.path)
entry.path ce.path
}"; # hack to build a string with context }";
}
else
ce) entry.closure;
}; };
getErisMainProgram = pkg: getErisMainProgram = pkg:
final.getEris (final.getMainProgram pkg) (prev.getOutput "bin" pkg); final.getEris (final.getMainProgram pkg) (prev.getOutput "bin" pkg);

View File

@ -23,7 +23,7 @@
( VFS.vfs ( VFS.vfs
[ VFS.leafAttrs [ VFS.leafAttrs
"plugin" "plugin"
(toMap { load = ${vfsRump.cap}, fs = "cd9660", ram = "12M", writeable="no" }) (toMap { load = "${vfsRump.cap}", fs = "cd9660", ram = "12M", writeable="no" })
] ]
) )
''; '';

View File

@ -107,7 +107,7 @@ let
let XML = Sigil.Prelude.XML let XML = Sigil.Prelude.XML
in in
${./store-wrapper.dhall} ${./store-wrapper.dhall}
{ binaries.rtc_drv = ${rtc_drv.cap} { binaries.rtc_drv = "${rtc_drv.cap}"
, extraCoreChildren = ${extraCoreChildren} , extraCoreChildren = ${extraCoreChildren}
, subinit = ${config.genode.init.configFile} , subinit = ${config.genode.init.configFile}
, storeSize = $(stat --format '%s' ${tarball}) , storeSize = $(stat --format '%s' ${tarball})
@ -232,11 +232,15 @@ in {
}]; }];
genode.core.romModules = with builtins; genode.core.romModules = with builtins;
(lib.lists.flatten ((map (getAttr "roms") (attrValues children')) ++ (map let
({ cap, path, ... }: { childRomEntries =
name = cap; lib.lists.flatten (map (getAttr "roms") (attrValues children'));
coreErisCapEntries = lib.lists.flatten (map ({ cap, closure }:
map ({ cap, path }: {
name = ''"${cap}"'';
value = path; value = path;
}) (attrValues coreErisCaps)))) ++ [ }) closure) (attrValues coreErisCaps));
in childRomEntries ++ coreErisCapEntries ++ [
{ {
name = ''"init"''; name = ''"init"'';
value = "${pkgs.genodePackages.init}/bin/init"; value = "${pkgs.genodePackages.init}/bin/init";

View File

@ -32,15 +32,15 @@ in {
ahciConfig = lib.optionalString cfg.ahci.enable (with cfg.ahci; '' ahciConfig = lib.optionalString cfg.ahci.enable (with cfg.ahci; ''
, ahci_drv = Some { , ahci_drv = Some {
, binary = ${ahciEris.cap} , binary = "${ahciEris.cap}"
, atapi = ${toDhall atapiSupport} , atapi = ${toDhall atapiSupport}
} }
''); '');
usbConfig = lib.optionalString cfg.usb.enable (with cfg.usb.host; '' usbConfig = lib.optionalString cfg.usb.enable (with cfg.usb.host; ''
, usb_block_drv = Some { binary = ${usbEris.usb_block_drv.cap} } , usb_block_drv = Some { binary = "${usbEris.usb_block_drv.cap}" }
, usb_host_drv = Some { , usb_host_drv = Some {
, binary = ${usbEris.usb_host_drv.cap} , binary = "${usbEris.usb_host_drv.cap}"
, bios_handoff = ${toDhall biosHandoff} , bios_handoff = ${toDhall biosHandoff}
, ehci = ${toDhall ehciSupport} , ehci = ${toDhall ehciSupport}
, ohci = ${toDhall ohciSupport} , ohci = ${toDhall ohciSupport}
@ -54,7 +54,7 @@ in {
in Manager.toChildAttributes in Manager.toChildAttributes
Manager::{ Manager::{
, part_block.binary = ${partBlockEris.cap} , part_block.binary = "${partBlockEris.cap}"
${ahciConfig} ${ahciConfig}
${usbConfig} ${usbConfig}
, verbose = ${toDhall cfg.verbose} , verbose = ${toDhall cfg.verbose}

View File

@ -73,14 +73,11 @@
lib.attrsets.mapAttrs (_: lib.attrsets.mapAttrs (_:
{ binary, configFile, extraErisInputs, package, ... }: { binary, configFile, extraErisInputs, package, ... }:
let let
toRoms = { cap, closure, path }: toRoms = { closure, ... }:
[{ map ({ cap, path }: {
name = cap; name = ''"${cap}"'';
value = path; value = path;
}] ++ (lib.mapAttrsToList (name: value: { }) closure;
name = ''"${value}"'';
value = name;
}) closure);
extraRoms = map toRoms extraErisInputs; extraRoms = map toRoms extraErisInputs;
in if binary != null then { in if binary != null then {
config = ''${configFile} "${binary}"''; config = ''${configFile} "${binary}"'';
@ -88,7 +85,7 @@
} else } else
let bin = lib.getErisMainProgram package; let bin = lib.getErisMainProgram package;
in { in {
config = "${configFile} ${bin.cap}"; config = ''${configFile} "${bin.cap}"'';
roms = toRoms bin ++ extraRoms; roms = toRoms bin ++ extraRoms;
}) children; }) children;
}; };

View File

@ -264,10 +264,13 @@ in nullPkgs // {
solo5-tools = callPackage ./solo5-tools { }; solo5-tools = callPackage ./solo5-tools { };
stdenv = overrideHost (old: { stdenv = if prev.stdenv.hostPlatform.isGenode then
extraNativeBuildInputs = old.extraNativeBuildInputs stdenv.override (prev': {
extraNativeBuildInputs = prev'.extraNativeBuildInputs
++ [ final.buildPackages.erisPatchHook ]; ++ [ final.buildPackages.erisPatchHook ];
}) prev.stdenv; })
else
prev.stdenv;
tor = overrideAttrsHost (attrs: { tor = overrideAttrsHost (attrs: {
patches = attrs.patches or [ ] ++ [ patches = attrs.patches or [ ] ++ [

View File

@ -3,6 +3,26 @@ import cbor, dhall/[render, terms], eris
const selfDescribedCbor = 55799 const selfDescribedCbor = 55799
type
Manifest = Table[string, ManifestEntry]
ManifestEntry = object
path: string
closure: Table[string, ErisCap]
proc parseManifestFile(path: string): Manifest =
let js = parseFile(path)
for key, val in js.pairs:
var
entry: ManifestEntry
entryCap = val["cap"].getStr.parseErisUrn
for e in val["closure"].items:
var
cap = e["cap"].getStr.parseErisUrn
path = e["path"].getStr
if cap == entryCap: entry.path = path
entry.closure[path] = cap
result[key] = entry
proc writeErisLinks(path: string; node: CborNode) = proc writeErisLinks(path: string; node: CborNode) =
# Inspired by "Package Metadata for Core Files" # Inspired by "Package Metadata for Core Files"
# - https://systemd.io/COREDUMP_PACKAGE_METADATA/ # - https://systemd.io/COREDUMP_PACKAGE_METADATA/
@ -25,16 +45,31 @@ proc toCbor(cap: ErisCap): CborNode =
result = initCborBytes(cap.bytes) result = initCborBytes(cap.bytes)
result.tag = erisCborTag result.tag = erisCborTag
proc toDhall(js: JsonNode): Value = proc toDhall(entry: ManifestEntry): Value =
case js.kind var closure = newSeqOfCap[Value](entry.closure.len)
of JString: for path, cap in entry.closure.pairs:
result = newValue(js.str) closure.add newRecordLiteral(
of JObject: { "cap": newValue $cap, "path": newValue path })
result = newRecordLiteral(js.fields.len) newRecordLiteral {
for key, val in js.fields.pairs: "cap": newValue $(entry.closure[entry.path]),
result.table[key] = val.toDhall "closure": newValue closure,
else: }
raiseAssert "unhandled JSON value"
proc toDhall(manifest: Manifest): Value =
result = newRecordLiteral(manifest.len)
for name, entry in manifest.pairs:
result.table[name] = entry.toDhall
proc toJson(entry: ManifestEntry): JsonNode =
var closure = newJArray()
for path, cap in entry.closure.pairs:
closure.add %*{ "cap": %($cap), "path": %path }
%*{ "cap": %($entry.closure[entry.path]), "closure": closure }
proc toJson(manifest: Manifest): JsonNode =
result = newJObject()
for name, entry in manifest.pairs:
result[name] = entry.toJSON
proc isElf(path: string): bool = proc isElf(path: string): bool =
var magic: array[4, char] var magic: array[4, char]
@ -66,7 +101,7 @@ proc main =
erisLinks: CborNode erisLinks: CborNode
var var
outputManifests = initTable[string, JsonNode]() outputManifests = initTable[string, Manifest]()
pendingFiles = initDeque[PendingFile]() pendingFiles = initDeque[PendingFile]()
failed = false failed = false
if getEnv("outputs") == "": if getEnv("outputs") == "":
@ -78,7 +113,7 @@ proc main =
if fileExists(outputRoot / jsonManifestSubPath): if fileExists(outputRoot / jsonManifestSubPath):
stderr.writeLine "Not running ERIS patch hook again" stderr.writeLine "Not running ERIS patch hook again"
quit 0 quit 0
outputManifests[outputRoot] = newJObject() outputManifests[outputRoot] = Manifest()
let buildInputs = getEnv("buildInputs").splitWhitespace let buildInputs = getEnv("buildInputs").splitWhitespace
@ -149,10 +184,11 @@ proc main =
let manifestPath = storePath / jsonManifestSubPath let manifestPath = storePath / jsonManifestSubPath
if fileExists(manifestPath): if fileExists(manifestPath):
let let
manifest = parseFile(manifestPath) manifest = parseManifestFile(manifestPath)
entry = manifest[filePath.extractFilename] entry = manifest[filePath.extractFilename]
for path, urn in entry["closure"].pairs: for path, cap in entry.closure.pairs:
result[path] = parseErisUrn urn.getStr if path != filePath:
result[path] = cap
let otherClosure = fileClosure(path) let otherClosure = fileClosure(path)
for otherPath, otherCap in otherClosure.pairs: for otherPath, otherCap in otherClosure.pairs:
# merge the closure of the dependency # merge the closure of the dependency
@ -196,7 +232,7 @@ proc main =
pendingFiles.addLast(pendingFile) pendingFiles.addLast(pendingFile)
break selfReferenceCheck break selfReferenceCheck
var var
closure = newJObject() closure = initTable[string, ErisCap]()
replaceCmd = patchelf & " --set-rpath '' " & filePath replaceCmd = patchelf & " --set-rpath '' " & filePath
for need, replacementPath in pendingFile.replacements.pairs: for need, replacementPath in pendingFile.replacements.pairs:
if replacementPath == "": continue if replacementPath == "": continue
@ -204,11 +240,11 @@ proc main =
cap = fileCap(replacementPath) cap = fileCap(replacementPath)
urn = $cap urn = $cap
stderr.writeLine "replace reference to ", need, " with ", urn stderr.writeLine "replace reference to ", need, " with ", urn
closure[replacementPath] = %urn closure[replacementPath] = cap
pendingFile.erisLinks[ replacementPath.toCbor] = cap.toCbor pendingFile.erisLinks[replacementPath.toCbor] = cap.toCbor
replaceCmd.add(" --replace-needed $# $#" % [need, urn]) replaceCmd.add(" --replace-needed $# $#" % [need, urn])
for path, cap in fileClosure(replacementPath).pairs: for path, cap in fileClosure(replacementPath).pairs:
closure[path] = %($cap) closure[path] = cap
pendingFile.erisLinks[path.toCbor] = cap.toCbor pendingFile.erisLinks[path.toCbor] = cap.toCbor
if runPatchelf and pendingFile.replacements.len != 0: if runPatchelf and pendingFile.replacements.len != 0:
@ -238,11 +274,13 @@ proc main =
quit("Adding note to $1 failed" % pendingFile.filePath) quit("Adding note to $1 failed" % pendingFile.filePath)
moveFile(tmpFile, pendingFile.filePath) moveFile(tmpFile, pendingFile.filePath)
outputManifests[pendingFile.outputRoot][filePath.extractFilename] = %* { var cap = fileCap(filePath)
"cap": $fileCap(filePath), closure[filePath] = cap
"closure": closure, outputManifests[pendingFile.outputRoot][filePath.extractFilename] =
"path": filePath ManifestEntry(
} closure: closure,
path: filePath,
)
if pendingFiles.len == prevPrevLen: if pendingFiles.len == prevPrevLen:
failed = true failed = true
@ -260,7 +298,7 @@ proc main =
for outputRoot, manifest in outputManifests: for outputRoot, manifest in outputManifests:
let supportDir = outputRoot / "nix-support" let supportDir = outputRoot / "nix-support"
createDir(supportDir) createDir(supportDir)
writeFile(outputRoot / jsonManifestSubPath, $manifest) writeFile(outputRoot / jsonManifestSubPath, $manifest.toJson)
writeFile(outputRoot / dhallManifestSubPath, $(manifest.toDhall)) writeFile(outputRoot / dhallManifestSubPath, $manifest.toDhall)
main() main()

View File

@ -24,9 +24,9 @@
${./bash.dhall} { ${./bash.dhall} {
, bash = "${pkgs.bash}" , bash = "${pkgs.bash}"
, coreutils = "${pkgs.coreutils}" , coreutils = "${pkgs.coreutils}"
, cached_fs_rom = ${extraErisInputs'.cached_fs_rom.cap} , cached_fs_rom = "${extraErisInputs'.cached_fs_rom.cap}"
, vfs = ${extraErisInputs'.vfs.cap} , vfs = "${extraErisInputs'.vfs.cap}"
, vfs_pipe = ${extraErisInputs'.vfs_pipe.cap} , vfs_pipe = "${extraErisInputs'.vfs_pipe.cap}"
} }
''; '';
extraInputs = with pkgs.genodePackages; [ pkgs.bash libc posix ]; extraInputs = with pkgs.genodePackages; [ pkgs.bash libc posix ];