Documentation
¶
Overview ¶
Package iso synthesizes deterministic ISO9660 volumes on the runner for the data.hyperv_iso_volume data source. The bytes the runner produces are stable across hosts, OSes, and clocks: same `volume_label` + same `files` map -> byte-identical output -> stable SHA-256 across applies.
Determinism matters for two reasons. First, the data source's `sha256` output is what consumers (typically `hyperv_image_file` in literal_bytes mode) hash the bytes they place on the host against -- if the input map is unchanged but synthesis emits different bytes, every plan would surface phantom drift on the placement resource. Second, the runner-streamed deploy reuses hyperv_image_file's local_path-mode wire path; the host-side script verifies the streamed bytes' SHA against the runner-computed value and rejects mismatches as transport corruption. A non-deterministic builder would break both contracts.
kdomanski/iso9660 v0.4.0 produces a valid ISO9660 image but injects two kinds of non-determinism into the Primary Volume Descriptor (PVD) at sector 16 (file offset 0x8000):
- SystemIdentifier set to runtime.GOOS (varies by build OS).
- VolumeCreation / VolumeModification / VolumeEffective timestamps set to time.Now() (varies by clock).
Build post-processes these PVD fields at known ECMA-119 byte offsets to fixed values: SystemIdentifier becomes a constant string, all three timestamp fields become zero-byte timestamps (ECMA-119 8.4.26.1 permits all-zero as "no time recorded"). File data sectors and directory entries are already deterministic in v0.4.0 -- per-file RecordingTimestamp is zero-valued, and the staging-dir traversal walks entries in lexical order regardless of AddFile call order.
Index ¶
Constants ¶
const MaxVolumeLabelLen = 32
MaxVolumeLabelLen is the ECMA-119 PVD VolumeIdentifier limit (32 d-characters). Longer labels would be silently truncated by kdomanski/iso9660; rejecting at the API boundary surfaces the limit to callers (resource validators, tests) where it can produce a clean diagnostic.
Variables ¶
This section is empty.
Functions ¶
func Build ¶
Build synthesizes a deterministic ISO9660 volume with the given volume label and file set, returning the raw bytes.
`volumeLabel` must be 1-32 d-characters (A-Z, 0-9, underscore); empty or longer labels are rejected. The case-sensitivity of cloud-init's "cidata" lookup is handled by cloud-init itself reading the RockRidge extension, but kdomanski/iso9660 v0.4.0 does not emit RockRidge, so the PVD label is the only label cloud-init sees -- and cloud-init uppercases before comparing, so "cidata" and "CIDATA" both match. The resource layer normalizes user input.
`files` is sorted by Name before adding to the ISO so the staging-dir traversal lexical order doesn't depend on the caller's slice order. Empty file lists produce a valid empty-volume ISO (allowed by ECMA-119, useful as a regression test fixture).
Returns the full ISO bytes (typically 256 KiB-1 MiB for cidata seeds; kdomanski/iso9660 does not pre-allocate, so the output is sized to content). Memory cost: peak ~2x the output size during WriteTo's internal buffering. For the sub-MiB seeds this resource targets, that is acceptable; if multi-GiB ISOs ever land here, switch to streaming io.Writer and post-process via random-access on the on-disk file.
Types ¶
type File ¶
File is one entry to embed at the root of the synthesized ISO. Name is the filename as it appears on the volume; Content is the raw bytes (UTF-8 for cidata YAMLs, XML for autounattend, arbitrary bytes for any other use case).
Subdirectories are deliberately not exposed: the canonical NoCloud (cidata) and autounattend layouts both put files at the volume root, and v1 of data.hyperv_iso_volume mirrors that. Adding a hierarchical files map would force callers to think about path delimiters, depth limits, and ECMA-119 8-level-deep restrictions for marginal benefit.