Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

isokit

Pack first-boot config scripts (.sh / .ps1 / .cmd / .bat) — and, since 0.2.0, arbitrary payload files — into a config ISO: an ISO 9660 image with Joliet + Rock Ridge (real long filenames) plus a firstboot.manifest at the root. On a deployed VM the first-boot runner finds the disc by that manifest, runs the listed scripts in order, and (v2) stages the listed payload files for those scripts to consume.

API

  • build_script_iso(script_paths, output_path) -> list[str] — legacy firstboot-only packing. Emits a version-1 manifest ({"version": 1, "scripts": [...]}) and always will; its output is a compatibility contract with pinned consumers.
  • build_config_iso(output_path, *, scripts=(), files=(), volume_id=None, progress_cb=None, progress_opaque=None) -> IsoContents — generalized packing. scripts are UTF-8 text, EOL-normalized per suffix (CRLF for .ps1/.cmd/.bat, LF otherwise), executed by the runner in order. files are copied byte-for-byte (binaries welcome) and never executed. Emits a version-2 manifest.

Entries

Every scripts= / files= element is either a Path (packed under its own basename) or a (disc_name, source) pair, where source is a Path to stream from or str/bytes of in-memory content:

build_config_iso(
    out,
    scripts=[("10-hostname.ps1", rendered_text)],       # never touches a temp dir
    files=[("pki-executor.exe", agent_build_path)],     # renamed without copying
    volume_id="WEB01-CONFIG",
    progress_cb=lambda done, total, _: publish(done / total),
)

EOL normalization keys off the disc name's suffix, so renaming rendered.tmp to 10-hostname.ps1 still gets CRLF.

Errors

  • BundleError (also a ValueError) — the bundle is invalid: duplicate or reserved names, a name too long for Joliet, nothing to pack. Retrying will not help; reject the row.
  • IsoWriteError — the build failed for an environmental reason: disk full, unreadable payload, unwritable destination. The same inputs may succeed elsewhere; retry the row.

Both derive from IsoKitError. Writes are atomic — a failed build leaves the destination untouched rather than a truncated .iso.

Progress

progress_cb(bytes_done, bytes_total, progress_opaque) is called as the image is written. Exceptions it raises are logged and swallowed: progress reporting must not abort a build.

Version-2 manifest contract

{
  "version": 2,
  "scripts": ["10-hostname.ps1", "30-install.cmd"],
  "files":   ["orchestrator.exe"]
}

Load-bearing rules (the runners in VM-Setup-Scripts depend on them — coordinate releases):

  • Key order is exactly version, scripts, files, serialized json.dumps(..., indent=2) so each array entry sits on its own line. The legacy (v1) Linux runner parses scripts with a sed range over that block; this layout is what lets a v1 runner execute a v2 disc's scripts while silently ignoring files. The v1 Windows runner parses real JSON and tolerates the extra key natively.
  • Both keys are always present in v2, even when empty. A scripts-empty disc is legal but warned against: v1 runners reject it, v2 runners stage the files transiently and then discard them.
  • One flat root namespace: no duplicate basenames across scripts + files; nothing may be named firstboot.manifest.

Limits: 99 entries per list; one flat root namespace (no subdirectories); single files cap at 4 GiB − 1 (interchange level 3, no multi-extent); Joliet long names cap at 64 characters (checked up front and reported as a BundleError).

Concurrency

isokit holds no module state, does not depend on the working directory, and pycdlib is instance-per-call, so builds are safe in parallel across both threads and processes. This is covered by tests rather than asserted: 16-way thread-pool, 8-way process-pool, and a barrier-synchronised race of 8 builds into one directory.

Depends on pycdlib. Tests: uv run pytest.

Consumed as a versioned git dependency by the VM-Setup-Scripts superproject and the EC-PKI-Playground backend. Install editable for local dev: uv pip install -e .

Pure library logic — no argparse/print/sys.exit. Collecting paths and reporting output is the caller's concern (see the superproject's cli/).

About

Part of VM-Setup-Scripts: isokit library

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages