Two user-facing commands shipped in overlay/usr/local/bin/.
Wraps dnf+flatpak update flow and read-only health diagnostic.
Uses gum if available, plain output otherwise. No kickstart wiring
yet beyond chmod — full integration in v0.6.0 release.
Co-authored-by: veilor-org <admin@veilor.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* v0.5.1: gum installer + full veilor-os ks generation
Two changes, one commit (matches v0.5.1 milestone):
1. Swap whiptail → gum (charm.sh)
- Source /usr/share/veilor-os/assets/installer/colors.gum at top so all
prompts pick up branded GUM_* env vars.
- Render banner.txt via `gum style --border rounded`.
- Wrap every prompt behind prompt_choose / prompt_input / prompt_password
/ prompt_confirm / prompt_message / prompt_error helpers that dispatch
gum→whiptail based on `command -v gum`. Defensive: minimal images
without /usr/local/bin/gum still get a working TUI.
- Main menu items now use literal labels (case-matched), not 1..5 tags.
2. Generated kickstart now installs full veilor-os
Previously emitted a vanilla F43 KDE + ~12 hardening packages with no
overlay/scripts/branding. Now mirrors live ks (kickstart/veilor-os.ks
63-141) for %packages, plus:
- %post --nochroot copies overlay/, scripts/, assets/ from
/run/install/repo/veilor (single source — boot ISO mount path).
- %post (chroot) runs scripts/10-harden-base.sh, 20-harden-kernel.sh,
selinux/build-policy.sh, kde-theme-apply.sh.
- `chage -d 0 admin` so first login forces password change. (Account
itself is created by anaconda from the `user` directive — admin pw
collected via gum is passed through --plaintext.)
- `systemctl set-default graphical.target` (real install boots SDDM,
not the TTY1 installer like live).
- Drops live-only entries (livesys-scripts, anaconda-live, dracut-live,
isomd5sum, xorriso, livesys.service enables).
Tested: bash -n clean; ksvalidator on a substituted-placeholder copy
exits 0.
gum binary itself (/usr/local/bin/gum) is vendored by a separate
build-side change — not in this PR.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: escape sed special chars + reject & | / in passwords
Reviewer found a password like aA1!@#%^&*()_-+={}[] becomes
aA1!@#%^__ADMIN_PW__*()_-+={}[] because sed expands & to matched
pattern. Two layers of defense:
1. validate_pw rejects & | / newline at input
2. sed_escape() helper escapes any remaining special chars before
substitution
---------
Co-authored-by: veilor-org <admin@veilor.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Drops in branded assets the v0.5.1 installer rewrite (whiptail -> gum)
will consume: ASCII banner, sourceable GUM_* env-var palette matching
the veilor-black KDE color scheme, and an INSTALLER.md walkthrough.
The existing v0.5.0 veilor-installer script is intentionally untouched
so the swap can land in a separate, focused PR.
Co-authored-by: s8n-ru <279801990+s8n-ru@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* v0.5.1 build: vendor gum binary + graft /veilor/ onto ISO
- gum 0.17.0 pinned by sha256, downloaded into overlay/usr/local/bin/
so installer can use Charm.sh TUI primitives.
- After livecd-creator produces ISO, extract+re-pack with /veilor/
containing overlay+scripts+assets so installer-generated ks can
copy them into target system at install time.
* fix: extract original ISO boot stanza programmatically (no hardcoded paths)
Reviewer found `-e images/efiboot.img` was wrong — Fedora livecd-creator
places efiboot.img in isolinux/ not images/. Plus missing
--mbr-force-bootable + -partition_* flags would produce hybrid MBR/GPT
mismatch refused by some BIOS firmwares.
Fix: extract original ISO's exact boot stanza via
`xorriso -report_el_torito as_mkisofs` and replay it via eval.
Guarantees exact match, immune to upstream Fedora layout changes.
---------
Co-authored-by: veilor-org <admin@veilor.org>
Pre-existing shellcheck failure blocking all PR merges. Standard
"double-quote array expansions" fix. No behavior change.
Co-authored-by: veilor-org <admin@veilor.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Lint flagged false positives on audit reports + CHANGELOG that
self-reference forbidden strings as findings. Restrict scan to
kickstart/, overlay/, scripts/, assets/, build/ — actual ship state.
Co-authored-by: veilor-org <admin@veilor.org>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Bugs found by agent linter on v0.5.0-alpha:
1. logvol missing --size: ksvalidator rejected. Added --size=8192 --grow.
2. bootloader --location=mbr on UEFI: conflicts with /boot/efi part.
Switched to --location=none (anaconda auto-detects EFI vs BIOS).
3. lsblk awk truncated multi-word disk models ("WD PC SN740" → "WD").
Now collapses model spaces to underscores, preserves full string.
Also added mmcblk to disk regex (eMMC support).
4. Heredoc with $VAR expansion + passwords containing $/`/" corrupted
generated ks. Now: single-quoted heredoc + sed placeholder
substitution. Plus input validator rejects "$\` chars in passwords.
ksvalidator clean on sample generated ks.
bash -n clean.
CI build still in flight (3328ffb). This pushes a new commit; CI will
run again with these fixes. Net delay: zero (3328ffb's installer was
broken anyway, so its ISO unusable for install path).
- display-manager.service symlink: livecd-creator skips alias creation
vs Anaconda installer; without it sddm stays inactive at graphical.target
- admin user: replace `passwd -d` with throwaway pw `veilor` + chage -d 0
(SDDM rejects blank pw by default, breaks first-login flow)
Tested in QEMU v0.2.5: confirmed sddm enabled but inactive after boot,
and blank-pw login at SDDM returns "Login Failed".
Live ISO stalled at dracut for 5+min on KVM with init_on_alloc=1
init_on_free=1 — kernel zeroes every page on alloc/free, brutal in
virtualized memory. Keep slab_nomerge + lockdown=integrity +
randomize_kstack + vsyscall=none for live (cheap). Re-add memory
init flags on installed system via veilor-firstboot post-install
GRUB edit (planned v0.3).
Upstream bug in /usr/lib/python3.14/site-packages/imgcreate/live.py:
if self._isDracut:
args["rootlabel"] = "live:LABEL=%(fslabel)s" # WRONG
else:
args["rootlabel"] = "CDLABEL=%(fslabel)s"
For dracut path on EFI grub it writes `root=live:LABEL=...` but
dracut needs `live:CDLABEL=...` to look up ISO9660 by CD volume id.
Result: parse-livenet hook stalls indefinitely.
CI now sed-patches the file in-place before build. Reported upstream
livecd-tools as separate task.
- kde-theme-apply.sh: search /etc/os-release.d/veilor (where overlay
put it) before falling back to $REPO/overlay path. Rewire symlinks
cleanly: /etc/os-release → ../usr/lib/os-release.
- Kickstart: useradd admin in chroot %post since livecd-creator skips
the `user` directive (no installer phase). Blank pw + expired = forced
reset at first login same as before.
Found via debugfs: overlay copy succeeds (veilor-power, tuned profiles,
sshd-hardening, sudoers, systemd units all present in v0.2.1 rootfs) but
`mkdir + cp assets/scripts` aborted with set -eu — leaves /usr/share/
veilor-os missing → all chroot %post scripts fail. Switch to set +e on cp
plus persist trace log to /var/log/veilor-nochroot.log for next debug.
POSTTRANS ldconfig hit ENOSPC/ROFS — KDE install + dnf cache + scriptlet
working set exceeds 16G tmpfs. Move livecd-creator tmpdir to /var/lmc on
runner's host ext4 disk.
Agent A: missing livesys-scripts + anaconda-live = lorax can't build EFI/BOOT.
Agent B: livecd-creator ignores url=, only reads repo.repoList — added
explicit repo --name=fedora to feed it the base.
Both Fedora's own pipeline + livecd-creator now have what they need.
Live image plumbing in %post: enable livesys.service livesys-late.service
tmp.mount, reset machine-id.
Past grub2-mkimage. Failed at xorrisofs final ISO assembly because EFI/BOOT
dir not built — needs grub2-efi-x64-modules to compile standalone grubx64.efi.
CI made it through full install, configure, %post, squashfs build,
initrd rebuild — failed at final boot.iso wrap because grub2-mkimage
needed /usr/lib/grub/i386-pc/moddep.lst (BIOS legacy boot modules).
Hybrid BIOS+UEFI ISO requires both grub variants.
Local builds need fix-repo because host has stale libselinux vs newer pcre2.
CI fresh container has matched libs, fix-repo unnecessary and refs invalid
(file:///tmp/veilor-fix-repo not present in CI). sed strips that ks line.
CI builds in fresh Fedora 43 container — matched pcre2/libselinux/selinux-policy
versions, no fix-repo hack needed. Container starts every run from clean
state, no zombie collisions. Fastest path to first green ISO.