Runs `livemedia-creator --no-virt --make-disk` directly on the host to
produce a disk image any VM manager can consume (e.g. via virtpull's
`virtpull local ... --wonder-vm NAME`), instead of deploy.sh's live
virt-install/libvirt session.
An earlier version wrapped this in `mock`, mirroring
.gitea/workflows/build-iso.yaml's ISO build. That doesn't work for
--make-disk: mock's chroot has no live systemd-udevd, so udev never
populates properties for the loop device livemedia-creator creates,
and blivet's device scan crashes. --make-iso never hits this since it
never touches block devices. Reproduced identically on Fedora 44 and
43 mock chroots, confirmed fixed by running directly on the host
instead (root required, for /dev/loop-control access).
Also fixes two real kickstart incompatibilities with the --no-virt
disk-image path (applied to a scratch copy, not the shared
ingredients): the `text` display-mode directive (needed for
virt-install's netinstall console) conflicts with livemedia-creator's
own display handling, and `part / --grow` with no explicit --size
crashes livemedia-creator's upfront disk-size calculation (works fine
under virt-install, which pre-creates the disk at a known size
instead) — now configurable via --root-size.
New --extra-ks FILE flag layers one-off local content (e.g. a bespoke
user/rootpw override) onto the scratch copy without touching tracked
ingredients, following the README's existing "bespoke dish not part
of the matrix" pattern.
Factored deploy/deploy-distro.sh's dish-picker into deploy/select-dish.sh,
shared by both scripts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add cryptsetup, tpm2-tools and tpm2-tss to every encrypted dish so the
initrd can be rebuilt with TPM2 support. A guarded %pre stashes a
preseeded LUKS passphrase from the kickstart, and a guarded %post
enrolls PCR 7-bound auto-unlock via systemd-cryptenroll, switches
crypttab to tpm2-device=auto and regenerates the initrd. Without a
preseeded passphrase or a TPM device the enrollment is skipped and the
system keeps the regular passphrase prompt.
Same fix as cd4302c for intelcpu: the bare sed against /etc/default/grub
missed systemd-boot and already-generated GRUB+BLS boot entries. Update
every kernel-argument surface idempotently, guarded by file existence:
/etc/kernel/cmdline, /etc/default/grub, and the options line of every
/boot/loader/entries/*.conf. Guard the nested=1 append as well.
Anaconda always creates /etc/kernel/cmdline, even on GRUB+BLS installs, so
the previous if/else misdetected systemd-boot on GRUB systems: the IOMMU
arguments landed in /etc/kernel/cmdline after GRUB+BLS boot entries had
already been generated from it, and never reached the running kernel
(observed on thinkpad and nuc6i7kyb).
Instead of branching on one file, update every kernel-argument surface
idempotently, guarded by existence: /etc/kernel/cmdline (kernel-install
source for systemd-boot and GRUB+BLS future kernels), /etc/default/grub
(grub.cfg flows), and the options line of every already-generated
/boot/loader/entries/*.conf (same shape under both systemd-boot and
GRUB+BLS). Guard the nested=1 append as well.
- storage/biosboot.ks: GPT disk label with a 2 MiB BIOS boot partition,
no ESP (pure legacy layout); registered as the 'biosboot' storage choice
- recipe_templates.yaml: make the desktop hypervisor a superset of the
base hypervisor so GNOME hypervisor dishes get libvirtd + virt-manager
- recipes_manifest.yaml: enable the desktop-hypervisor group targeting
Fedora 44 (gnome, biosboot, grub, security enabled, gnome initial-setup,
hardware-support, intelcpu)
- initial-setup/gnome/config.ks: apply the vendor.conf fix (truncate and
append skip=privacy / providers=local-first!) as an enabled %post
- tests: update BASE_FRAGMENTS fixture to core-explicit.ks (follow-up to
ccf4f9d)
With --exclude-weakdeps, two packages that nothing else hard-requires were
being silently dropped from the installed system:
- dbus-daemon (provides /usr/bin/dbus-run-session): gdm-wayland-session
needs it to spawn the per-session D-Bus bus. Only anaconda-core requires
it, and that is not installed into the target system.
- systemd-pam (provides pam_systemd.so): 'systemd' merely recommends it.
Without pam_systemd, PAM 'optional' session rules fail silently, login
sessions never register with logind, user@.service never starts, and the
session bus lacks org.freedesktop.systemd1.
Result of either gap: gdm logs 'Session never registered, failing' five
times, then 'maximum number of display failures reached. Giving up.' and
the screen stays black — on VMs and bare metal alike (laptop bug).
Both packages validated live on a Fedora 44 guest; dnf5 check passes.
generic-release conflicts with fedora-release and generic-logos conflicts
with fedora-logos, so dishes shipping the remix packages cannot coexist
with @core pulling Fedora branding — the RPM transaction fails at prepare
time. Replace @core with the explicit core package list (mandatory +
default, plus basesystem/kernel/dhcp-client), add fedora-repos explicitly,
and deselect fedora-release/fedora-logos; the remix packages provide
system-release, system-release(44) and system-logos instead.
Verified on nuc6i7kyb: a Fedora 44 GNOME hypervisor desktop VM installed
cleanly from this configuration (982-package resolution scratch-tested
before the install).
- uncomment the hypervisor recipe, targeting Fedora 44 with
systemd-boot, hardware-support and the intelcpu variant
- make intelcpu.ks bootloader-aware: with systemd-boot kernel
arguments must go to /etc/kernel/cmdline, not /etc/default/grub
- add fedora-44-mirrors ingredient and register it in the repository choices
- expand the desktop variant matrix to [43, 44, rawhide] (48 dishes)
- bump CI workflows and deploy fallback URL to Fedora 44
- cover both release repositories in tests
- both ISO workflows run the new single 'make all' pipeline (they
previously referenced the removed recipe-generator/ directory and
nonexistent live kickstarts) and build from the generated
desktop_43_standard_grub_gnome_guest-agents dish
- README: document the data-driven cooking pipeline (manifest +
templates + make all), generated build products, and updated
deploy/dish examples
- deploy.sh now runs 'make all' in cook/ before deploying, since dishes
are build products no longer tracked in git; failures show the make
output and abort
- deploy-distro.sh selects dishes by the *guest-agents* marker (the new
naming replaced the virtual* prefix) and uses --os-variant
fedora-unknown instead of the stale fedora41 pin
Replace the hardcoded TEMPLATES dict and the ksflatten-relative wrapper
with a single data-driven pipeline:
- recipe_templates.yaml becomes the single source of truth with three
sections: base (always included), choices (exactly-one per category,
the invariant pykickstart cannot check) and features (additive flags
or one-of values)
- generate_recipe.py is a pure YAML consumer: it resolves ingredients,
renders dishes via pykickstart in-process (no ksflatten binary, no
%include path munging), lints the invariants pykickstart cannot check
(exactly-one per choice category, known keys, existing fragments,
unique filenames) and validates every generated dish
- dish names are derived by a generic rule with canonical category order
from the templates, independent of YAML key order; no committed
generated files means no name burn-in
- recipes/ and dishes/ become gitignored build products; the 68 tracked
generated files (already out of sync with the manifest) are removed
- delete dead ingredients (section-data/, validation/, initial-setup/
desktop/, live/hypervisor.ks, rpmfusion-nonfree.ks), the stale
all-ingredients.cfg (replaced by 'make inventory') and the
bin/generate-recipe and bin/ksflatten-relative wrappers
- Makefile: single 'make all' step plus lint, validate, inventory, test
- add 16 pytest tests covering expansion, selection, naming, lint and
flatten/validate round-trips
- create generate_recipe.py for universal template recipe generation
- support cartesian product expansion from recipes_manifest.yaml
- generate 72 unique recipes with proper filename disambiguation
- update Makefile with simplified validation using ksflatten
- keep ksflatten-relative script as-is for dish flattening
The generator reads recipe_templates.yaml and recipes_manifest.yaml to
produce recipe files that ksflatten then flattens into final dishes.
- Move storage options from 'modifiers' to 'required' in recipe_templates.yaml
- Changed required.storage from {'ext4': storage/standard.ks} to {'standard': ..., 'encrypted': ...}
- Removed storage from modifiers section
- This ensures storage: encrypted recipes include only storage/encrypted.ks
- Updated generated recipes and dishes to reflect the fix
- Transition from multi-template (install/live recipe types) to single universal template (proteus)
- Remove recipe_type parameter from RecipeGenerator
- Update manifest format (remove recipe_type field)
- Simplify CLI (remove --type argument, use --output for single generation)
- Filename generation now uses primary modifier as first component
- Move recipe-generator/ to cook/ for cleaner structure
- Fix ksflatten-relative path conversion to handle all %include paths
- Fix validation exit code to only fail on actual errors
- All recipes now generate and flatten successfully via make all
Simplify RecipeGenerator.__init__() to accept only templates_file parameter.
The old two-argument pattern RecipeGenerator(ingredients_dir, templates_file)
is no longer supported. All existing code already uses the new single-argument
style.
Changes:
- Remove ingredients_dir_or_templates parameter
- Remove backward compatibility logic
- Remove unused Optional import
- Update DEVELOPMENT.md example
Migration: Change RecipeGenerator(Path('ingredients'), Path('templates.yaml'))
to RecipeGenerator(Path('templates.yaml'))
The manifest uses hyphenated keys (guest-agents, hardware-support) but the filename
generation was looking for underscored keys, causing 16 variants to overwrite 4 files.
Added _get_modifier() helper to normalize both key formats and added _bare-metal suffix
for False values of guest_agents, ensuring unique filenames for all variant combinations.
This restores the intended 24 distinct variants from the manifest and adds support for
all modifiers (bootloader, initial-setup, desktop, security, storage, guest_agents, hardware_support).
- Removed deduplication logic from cli.py
- All 24 variants now processed (some overwrite with same filename)
- manifests: Added comments explaining cartesian product and filename behavior
- tests: Updated assertions for correct filename generation order
- Added 3 new tests for guest_agents and hardware_support modifiers
- Split generate_recipe.py into cli.py, recipe_generator.py, validators.py, manifest.py
- Removed override logic - modifiers now add fragments rather than replace
- Added filename deduplication to prevent overwriting recipes
- Updated CI workflows and tests to use new module structure
- Made pykickstart a hard dependency
- Removed ingredients/ directory support (only fragments/*.ks now used)
- New layout: 5 modules (~990 lines) vs single 769-line file
- Remove DEPRECATED_COMMANDS dictionary
- Remove _check_deprecated_commands() method
- Remove deprecated command checks from validation
- Remove test methods for deprecated commands
- Remove DEPRECATED_COMMANDS documentation reference
This shifts responsibility for tracking deprecated kickstart commands away
from the recipe generator, as this is not its primary role.
- Add version to required section in install and live templates
- Set 43 as default version (overridable via modifiers)
- Update CLI default from rawhide to 43