Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions image/compose.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -536,10 +536,10 @@ def _bootable_disk_image_impl(ctx: AnalysisContext) -> list[Provider]:

# The system partitions are filled by their own repart run and imported into this one, so what
# the disk holds is what the two runs between them listed.
written = system.info.written + disk.info.written
manifests = system.info.manifests | disk.info.manifests

sub_targets = dict(disk.sub_targets)
sub_targets.update(manifest_sub_targets(written))
sub_targets.update(manifest_sub_targets(manifests))
sub_targets.update({
"boot": [
DefaultInfo(
Expand Down Expand Up @@ -593,10 +593,8 @@ def _bootable_disk_image_impl(ctx: AnalysisContext) -> list[Provider]:
"{}.vmlinuz".format(basename): boot.kernel,
raw.basename: raw,
}
for partition in written:
if partition.manifest != None:
name = partition.definition["name"]
artifacts["{}.{}.Uapi16Manifest".format(basename, name)] = partition.manifest
for name, listing in manifests.items():
artifacts["{}.{}.Uapi16Manifest".format(basename, name)] = listing
whole = disk.info.manifest
if whole != None:
artifacts[whole.basename] = whole
Expand Down
38 changes: 16 additions & 22 deletions image/ddi.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,13 @@ def _check_definitions(
if bool(signatures) != signed:
fail("ddi: Verity=signature and signing credentials must be specified together")

WrittenPartitionInfo = record(
definition = Partition,
# What it carries; absent for a partition whose content no listing describes.
manifest = Artifact | None,
)

PartitionInfo = record(
definition = Partition,
blocks = Artifact,
metadata = Artifact,
# What it carries; absent for the same reason. An imported partition brings this with it, so
# the invocation that copies it in can list the whole disk without listing that partition.
# The manifest lists the files of the partition. It is None for a partition that copies no
# files. The invocation that wrote an imported partition also wrote its manifest, and the
# invocation that copies the partition in uses that manifest to list the whole disk.
manifest = Artifact | None,
)

Expand All @@ -215,11 +210,11 @@ DdiInfo = provider(
"disk": provider_field(Artifact | None, default = None),
# What the composed disk carries, its own partitions and its imported ones taken together.
"manifest": provider_field(Artifact | None, default = None),
# manifests maps each partition that this invocation writes to the manifest of its files.
# Imported partitions are in `partitions`, with the manifest of the invocation that wrote them.
"manifests": provider_field(dict[str, Artifact], default = {}),
"partitions": provider_field(list[PartitionInfo]),
"root_hash": provider_field(RootHashInfo | None, default = None),
# The partitions this invocation populates itself. Imported ones are in `partitions`
# instead, already listed by the invocation that filled them.
"written": provider_field(list[WrittenPartitionInfo], default = []),
},
)

Expand Down Expand Up @@ -255,16 +250,15 @@ def _partition_sub_targets(partitions: list[PartitionInfo]) -> dict[str, list[Pr
def _output(artifact: Artifact | None) -> OutputArtifact | None:
return artifact.as_output() if artifact != None else None

def manifest_sub_targets(written: list[WrittenPartitionInfo]) -> dict[str, list[Provider]]:
def manifest_sub_targets(manifests: dict[str, Artifact]) -> dict[str, list[Provider]]:
"""What each partition carries, under the name of the definition that carries it."""
listings = {it.definition["name"]: it.manifest for it in written if it.manifest != None}
if not listings:
if not manifests:
return {}
return {
"manifests": [
DefaultInfo(
default_outputs = listings.values(),
sub_targets = {name: [DefaultInfo(default_output = out)] for name, out in listings.items()},
default_outputs = manifests.values(),
sub_targets = {name: [DefaultInfo(default_output = out)] for name, out in manifests.items()},
),
],
}
Expand Down Expand Up @@ -327,7 +321,7 @@ def declare_ddi(
definition_specs = []
outputs = []
new_partitions = []
written = []
manifests = {}
for definition in definitions:
name = definition["name"]

Expand Down Expand Up @@ -361,7 +355,8 @@ def declare_ddi(
"manifest": _output(listing),
"metadata": _output(metadata),
})
written.append(WrittenPartitionInfo(definition = definition, manifest = listing))
if listing != None:
manifests[name] = listing

spec = {
# repart has no partition type for any architecture, so an `_any` DDI gets the build host's types.
Expand Down Expand Up @@ -401,8 +396,7 @@ def declare_ddi(

# Nothing to assemble a listing of the whole from when no part of this disk was listed,
# which is a disk of imported verity partitions and nothing else.
listed = [it for it in imported_partitions + written if it.manifest != None]
if listed:
if manifests or [it for it in imported_partitions if it.manifest != None]:
manifest = declare_out(ctx, identifier, basename + ".Uapi16Manifest")
spec["manifest"] = manifest.as_output()

Expand All @@ -422,10 +416,10 @@ def declare_ddi(
disk = out,
manifest = manifest,
partitions = available_partitions,
manifests = manifests,
root_hash = root_hash,
written = written,
)
sub_targets = manifest_sub_targets(written)
sub_targets = manifest_sub_targets(manifests)
if manifest != None:
# Qualified, unlike the provider field: a logical image publishes a `manifest` subtarget of
# its own (image.bzl:image_metadata_subtargets) listing its whole tree, and a composition
Expand Down
Loading