git mirror - github.com/owenewans/holy - branch master
clone: https://src.holypkg.eu/holy/

file man/holygetiso.8

.TH HOLYGETISO 8 "September 2026" "Holy" "System Administration"
.SH NAME
holygetiso \- build and boot-test a Holy image from explicit inputs
.SH SYNOPSIS
.B holygetiso
.RB [ --check ]
.I CONFIG
.br
.B holygetiso --export-inputs
.I IMAGE_OUTPUT DIRECTORY
.SH DESCRIPTION
The current command drives the repository's bootstrap-image builder. Run it
from the Holy source directory after make. It accepts local or pinned-source core inputs and
pinned native source packages for additional applications. It rejects unknown sections, keys,
duplicate scalar keys, missing input paths and malformed quoting. It uses the
holy.conf lexer; configuration text is not executed by a shell. A top-level
"include PATH" reads another config relative to the containing file. Include
cycles and duplicate scalar keys across files fail.
.PP
The builder packages the core inputs, asks holyinstall and holypkg to install
them into a separate root, generates the documentation bundle and initramfs,
creates an ISO, then runs the QEMU boot contract. The output directory must
not exist. A successful exit requires a boot-tested image; the build log,
install preview, frozen plan, package hashes and VM report remain there.
The command writes one expanded effective config with resolved input paths.
Its SHA-256 is included in build.record before the boot plan is hashed. The
builder copies those exact bytes into output/inputs/image.conf and rejects a
change between validation and copying.
With --check, the command validates the config and existing input paths and
prints the effective config hash, target architecture, profile and output path without
starting a build.
.PP
--export-inputs copies the inputs, normalized packages, sealed native mirrors,
build record and frozen plans from an existing build output into a new directory.
It checks the input lock and source/install/boot plan hashes before copying.
SHA256SUMS records each copied file and is checked before the command succeeds.
The bundle preserves the exact package inputs for inspection or a repeated
experiment. host-tools.jsonl names each direct executable used by the builder,
its canonical path and SHA-256; the build record binds that file. The bundle
does not include the host compiler, QEMU, firmware, their dependency closure or
the Holy source checkout. The destination must not exist.
.SH CONFIGURATION
Paths are resolved relative to the config file. Existing input paths must
resolve at startup. The output path names a new directory; the ISO is written
as holy-ARCH.iso inside it. Supported sections and keys follow.
.TP
.B [image]
Required: arch (i686 or x86_64), output, kernel-version,
limine-dir, static-holypkg, static-holyinstall, static-cc, profile
(static-core or dual-libc), root-storage (ram, ext4 or gpt-ext4).
Choose one kernel-image local path or kernel-package ALIAS:PACKAGE from an
active pinned source. The source package must be named linux, match
kernel-version and target architecture, use libc nolibc, and contain
boot/vmlinuz. The builder preserves that .holy and source ID in the install
plan, and checks the extracted x86 kernel header before building the image.
make bootstrap-kernel can create that linux.holy from a selected local x86
kernel image and an optional modules staging tree. Its result enters an image
through an explicitly configured source catalog.
If the package contains usr/lib/modules/KERNEL_VERSION/kernel/drivers/net/dummy.ko
and its modules.dep entry, the builder packages a static module probe. QEMU
requires the guest to load dummy and find it in /proc/modules on each boot.
Without that module the report marks kernel-module-load untested.
Optional: glibc-cc, musl-cc, libc-boot-state, network-recovery,
install-test and install-firmware. Their supported combinations are documented
in holy-image(7). boot-test accepts required (default) or build-only. The
dual-libc profile requires musl-cc.
.TP
.B [packages]
Required: busybox, dinit and mdevd. The dual-libc profile also requires
glibc and musl. An installer test requires doas and storage-tools. Each
value is a local .holy path or a pinned source reference where supported.
The builder records original and
normalized artifact hashes separately. Repeated "add PATH" entries install
additional local .holy packages in the same frozen set plan. Their original
archives remain in output/inputs and the build record identifies each hash.
An "add ALIAS:PACKAGE" entry fetches a named package from a pinned native
source. The builder resolves requirements against all configured sealed
catalogs in a temporary root, then copies selected .holy artifacts into inputs
and binds each source ID in holyinstall's frozen set plan. A unique exact
provider can come from another source. Other explicit "add ALIAS:PACKAGE"
entries become candidates for the current package; unresolved ambiguity stops
the build. The busybox, dinit, mdevd, glibc and musl fields accept local
artifacts or ALIAS:PACKAGE from a pinned source. The builder records the
source ID and original digest, then normalizes each core artifact into a new
unsigned Holy package. On an x86_64 builder targeting i686, the resolver's
x86 placement decision is recorded for each selected x86 artifact. This does
not claim that the host can execute the i686 image. Doas and storage-tools
fields require local artifacts.
Added packages must target the image architecture or noarch; x86 packages are
also accepted in an x86_64 image. Duplicate package names fail before plan
generation. The package manager checks payload ownership and dependencies.
.PP
.B make source-ready-core
accepts OUTPUT, SOURCE_ALIAS, SOURCE_URL and the five *_PACKAGE input paths.
It copies the bootstrap archives, rebuilds their manifests with root ownership
inside a user namespace, and writes a sealed unsigned native repository plus
core-source.conf for inclusion in an image config. build.record links each new
artifact digest to its original digest. SOURCE_URL is provenance for this
local repository; the command does not publish files at that URL. This step
requires user namespaces and does not sign the resulting artifacts.
.TP
.B [resolver]
Optional "answers PATH" selects a holy-answers-1 file with source decisions
keyed by consumer artifact hash and requirement ID. "answers-sha256 DIGEST"
is required with it. holygetiso checks the digest during config validation,
then the builder copies the file to output/inputs/resolver-answers and checks
the digest again before using it. The build record and exported input lock
include that copy. An answer naming a source that does not offer the exact
requirement fails in holypkg; a changed consumer hash cannot reuse an old
answer. An unresolved choice stops the build with status 3.
.TP
.B [source NAME]
Each used native source requires type holy-http or holy-git, "url" and
"index-sha256" with the exact lowercase digest of the selected generation.
holy-http uses an HTTPS directory URL ending in slash. holy-git also requires
"commit" with a full lowercase Git object ID. The builder records the commit
in build.record and checks it when fetching or importing a mirror.
"ca-file" names an optional local CA file. "mirror PATH" selects
an existing sealed snapshot for an offline build. Its source ID, URL and
index must match the configured source and pin. The builder copies and
revalidates it under output/mirrors. "embed-mirror yes" also includes the
entire sealed catalog in the image root at
/var/cache/holypkg/image-mirrors/NAME. The source binding uses that
root-relative location so fetch can find it after the image boots. The
default is no: only selected packages enter the image cache, and the user
syncs the source after boot to obtain its current catalog.
mirror and ca-file cannot be combined.
"trust require" with "public-key PATH" verifies an Ed25519-signed catalog.
holygetiso resolves the PEM path relative to its containing config file and
freezes the raw public key in the effective config and source plan. Changing
the key bytes changes the effective config hash. A signed offline mirror must
carry a valid signature for that key. The key is checked again when a bound
mirror is queried.
The image config uses the holy.conf lexer but index-sha256 is specific to
holygetiso. The builder registers all listed sources and keeps the
verified mirrors in output/mirrors. Its record binds source IDs and index
digests. An index digest is a pin, not publisher signature evidence.
.TP
.B [docs]
Exactly one "include installed-man-pages" and
"output /usr/share/holy/llm.txt" are required. holypkg docs reads the
installed root and generates this file from its selected man pages.
.SH STATUS
The command returns 0 after a boot-tested build, 2 for invalid config, 6 for
missing inputs or host requirements, and 1 for other failures. The output
build.record says "result incomplete" when a build fails after the output
directory is created. If QEMU is missing, or boot-test is build-only, the
builder writes "result untested" after producing the image and returns 6.
A successful process exit alone does not certify
hardware, a desktop or all packages named in the Holy specification.
.SH LIMITS
This bootstrap command supports holy-http and holy-git sources. For additional
packages it uses holypkg's native resolver in a temporary root with every
pinned mirror bound. The resolver can select a unique exact provider from
another source. Explicitly listed packages from other sources become
candidate providers; unresolved ambiguity stops the build. The builder copies
only selected artifacts and their source IDs into the final install plan.
Boot core packages may come from a pinned native source. Full package policy and a portable export of
build tools remain open. The command stays in-tree while the source checkout
provides build tools and profiles.
.SH SEE ALSO
holy-image(7), holypkg(8), holyinstall(8), holy.conf(5)