feat: Phase 2 (fragment migration), Phase 3 (testing infrastructure), Phase 4 (CI/CD)

Phase 2: Fragment Migration
- Migrated 42 ingredients to 54 fine-grained fragments
- Replaced %include with %ksappend syntax
- Created organized fragment structure (platform/generic-43, platform/generic-rawhide, shared/)
- Updated generator to use fragment paths
- All 16 manifest variants generate successfully

Phase 3: Testing Infrastructure
- Created containerized test runner (tests/container/)
- Added integration test suite (tests/integration/)
- Created golden master fixtures (tests/fixtures/expected_recipes/)
- 41 tests passing (36 unit + 5 integration)
- 54 fragments, 16 recipes validated

Phase 4: CI/CD Integration
- 5 new workflows: validate-recipes, validate-fragments, test-generation, container-tests, build-iso
- Added validation gates before ISO builds
- Works with existing fedora-runner-image
- Local testing support via act_runner
This commit is contained in:
Lukas Greve
2026-03-24 21:27:29 +01:00
parent a0a5de31cc
commit 5e8afd7d6f
113 changed files with 2973 additions and 224 deletions
+44 -44
View File
@@ -1,75 +1,75 @@
name: release
name: build-iso
on:
on:
push:
branches:
- main # Or your desired branch
branches: [main]
release:
types: [published]
jobs:
checkout:
runs-on: fedora-cloud-42
defaults:
run:
shell: bash
container:
validate:
runs-on: fedora
container:
image: git.phyllo.me/devops/fedora-runner-image:latest
steps:
- uses: https://git.phyllo.me/devops/checkout@v5
with:
fetch-depth: 0
- name: Install dependencies
run: |
pip install PyYAML pykickstart
- name: Generate all recipes
run: |
cd scripts
python3 generate_recipe.py \
--manifest recipes_manifest.yaml \
--output-dir ../recipes/
- name: Validate recipes (strict mode)
run: |
cd scripts
python3 generate_recipe.py --validate ../recipes/*.cfg --strict
build-iso:
needs: validate
runs-on: fedora-cloud-42
container:
image: git.phyllo.me/devops/fedora-runner-image:latest
steps:
- uses: https://git.phyllo.me/devops/checkout@v5
with:
fetch-depth: 0
- name: Initialize mock
run: |
mock -r fedora-43-x86_64 --init
- name: Install required packages
run: |
mock -r fedora-43-x86_64 --install lorax-lmc-novirt vim-minimal pykickstart livecd-tools
- name: Copy configuration file to mock
run: |
mock -r fedora-43-x86_64 --copyin dishes/live-server.cfg /builddir
mock -r fedora-43-x86_64 --copyin recipes/live-server_rawhide.cfg /builddir
- name: Build ISO with livemedia-creator
run: |
mock -r fedora-43-x86_64 --shell --enable-network --isolation=simple << 'EOF'
cd /builddir
livemedia-creator --ks live-server.cfg --no-virt --resultdir /var/lmc --project live-desktop-hypervisor --make-iso --volid live-desktop-hypervisor --iso-only --iso-name server-43.iso --releasever 43 --macboot
livemedia-creator --ks live-server_rawhide.cfg --no-virt --resultdir /var/lmc --project live-server --make-iso --volid live-server --iso-only --iso-name server-43.iso --releasever 43 --macboot
EOF
- name: Upload ISO as artifact
uses: actions/upload-artifact@v3
with:
name: server-43.iso
path: /var/lmc/server-43.iso
if-no-files-found: error
- name: Create Release
if: github.ref == 'refs/heads/main'
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: iso-build-${{ github.run_number }}
release_name: ISO Build ${{ github.run_number }}
body: |
Build artifact from workflow run ${{ github.run_number }}
ISO file: server-43.iso
draft: false
prerelease: false
- name: Upload ISO to Release
if: github.ref == 'refs/heads/main'
uses: actions/upload-release-asset@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: /var/lmc/server-43.iso
asset_name: server-43.iso
asset_content_type: application/x-iso9660-image
- name: Cleanup mock environment
if: always()
run: |
@@ -0,0 +1,54 @@
name: release
on:
push:
tags:
- "v*.*.*"
env:
FEDORA_VERSION: 43
KICKSTART_FILE: live-desktop-hypervisor
jobs:
checkout:
runs-on: fedora
defaults:
run:
shell: bash
steps:
- uses: https://git.phyllo.me/devops/checkout@v5
with:
fetch-depth: 0
- name: Initialize mock
run: |
mock -r fedora-${{ env.FEDORA_VERSION }}-x86_64 --init
- name: Install required packages
run: |
mock -r fedora-${{ env.FEDORA_VERSION }}-x86_64 --install lorax-lmc-novirt vim-minimal pykickstart livecd-tools
- name: Copy configuration file to mock
run: |
mock -r fedora-${{ env.FEDORA_VERSION }}-x86_64 --copyin dishes/${{ env.KICKSTART_FILE }} /builddir
- name: Build ISO with livemedia-creator
run: |
mock -r fedora-${{ env.FEDORA_VERSION }}-x86_64 --shell --enable-network --isolation=simple << 'EOF'
cd /builddir
livemedia-creator --ks ${{ env.KICKSTART_FILE }}.cfg --no-virt --resultdir /var/lmc --project ${{ env.KICKSTART_FILE }} --make-iso --volid ${{ env.KICKSTART_FILE }} --iso-only --iso-name ${{ env.KICKSTART_FILE }}-${{ env.FEDORA_VERSION }}.iso --releasever ${{ env.FEDORA_VERSION }} --macboot
EOF
- name: Release
uses: https://git.phyllo.me/devops/action-gh-release@v2
if: github.ref_type == 'tag'
with:
files: /var/lib/mock/fedora-${{ env.FEDORA_VERSION }}-x86_64/root/var/lmc/${{ env.KICKSTART_FILE }}-${{ env.FEDORA_VERSION }}.iso
draft: false
prerelease: false
- name: Cleanup mock environment
if: always()
run: |
mock -r fedora-${{ env.FEDORA_VERSION }}-x86_64 --clean
+38
View File
@@ -0,0 +1,38 @@
name: container-tests
on:
push:
paths:
- 'tests/**/*.py'
- 'tests/container/**'
pull_request:
paths:
- 'tests/**/*.py'
jobs:
test:
runs-on: fedora
container:
image: git.phyllo.me/devops/fedora-runner-image:latest
steps:
- uses: https://git.phyllo.me/devops/checkout@v5
with:
fetch-depth: 0
- name: Build test container
run: |
cd scripts
podman build -t phyllo/test-runner ../tests/container/
- name: Run tests in container
run: |
podman run --rm -v $(pwd):/phyllomeos:ro phyllo/test-runner
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: container-test-results
path: _pytest_cache/
if-no-files-found: ignore
+51
View File
@@ -0,0 +1,51 @@
name: test-generation
on:
push:
paths:
- 'scripts/**/*.py'
- 'scripts/**/*.yaml'
- 'fragments/**/*.ks'
pull_request:
paths:
- 'scripts/**/*.py'
- 'scripts/**/*.yaml'
jobs:
generate:
runs-on: fedora
container:
image: git.phyllo.me/devops/fedora-runner-image:latest
steps:
- uses: https://git.phyllo.me/devops/checkout@v5
with:
fetch-depth: 0
- name: Install dependencies
run: |
pip install PyYAML pykickstart
- name: Generate all variants
run: |
cd scripts
python3 generate_recipe.py \
--manifest recipes_manifest.yaml \
--output-dir ../recipes/
- name: Verify 16 recipes created
run: |
count=$(ls recipes/*.cfg | wc -l)
if [ $count -ne 16 ]; then
echo "Expected 16 recipes, got $count"
exit 1
fi
echo "✓ Generated $count recipes"
- name: Upload generated recipes
uses: actions/upload-artifact@v3
with:
name: generated-recipes
path: recipes/
if-no-files-found: error
retention-days: 7
+42
View File
@@ -0,0 +1,42 @@
name: validate-fragments
on:
push:
paths:
- 'fragments/**/*.ks'
pull_request:
paths:
- 'fragments/**/*.ks'
jobs:
validate:
runs-on: fedora
container:
image: git.phyllo.me/devops/fedora-runner-image:latest
steps:
- uses: https://git.phyllo.me/devops/checkout@v5
with:
fetch-depth: 0
- name: Install pykickstart
run: pip install pykickstart
- name: Validate all fragments
run: |
errors=0
for fragment in $(find fragments -name "*.ks"); do
if python3 -c "
from pykickstart.parser import KickstartParser
from pykickstart.version import makeVersion, DEVEL
parser = KickstartParser(makeVersion(DEVEL))
parser.readKickstart(open('$fragment').read())
" 2>/dev/null; then
echo "✓ $fragment"
else
echo "✗ $fragment"
errors=$((errors + 1))
fi
done
echo "Fragment validation complete: $errors errors"
exit $errors
+50
View File
@@ -0,0 +1,50 @@
name: validate-recipes
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
validate:
runs-on: fedora
container:
image: git.phyllo.me/devops/fedora-runner-image:latest
steps:
- uses: https://git.phyllo.me/devops/checkout@v5
with:
fetch-depth: 0
- name: Install dependencies
run: |
pip install PyYAML pytest pykickstart
- name: Generate all recipes
run: |
cd scripts
make generate-recipes
- name: Validate recipes (strict mode)
run: |
cd scripts
python3 generate_recipe.py --validate ../recipes/*.cfg --strict
- name: Run unit tests
run: |
cd scripts
make test
- name: Run integration tests
run: |
cd scripts
make test-integration
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: test-results
path: _pytest_cache/
if-no-files-found: ignore
+4 -16
View File
@@ -1,4 +1,4 @@
# Generated by pykickstart v3.66
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
@@ -14,8 +14,6 @@ lang en_US.UTF-8
network --bootproto=dhcp --device=link --hostname=phyllome-alpha --activate
# Shutdown after installation
shutdown
repo --name="fedora" --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&arch=x86_64
repo --name="updates" --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=updates-released-f43&arch=x86_64
#Root password
rootpw --lock
# SELinux configuration
@@ -24,8 +22,6 @@ selinux --enforcing
services --enabled="NetworkManager,systemd-resolved"
# System timezone
timezone Europe/Zurich --utc
# Use network installation
url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&arch=x86_64"
# X Window System configuration information
xconfig --defaultdesktop=GNOME --startxonboot
# System bootloader configuration
@@ -35,17 +31,9 @@ zerombr
# Partition clearing information
clearpart --all --initlabel
# Disk partitioning information
part /boot/efi --fstype="efi" --size=512 --fsoptions="umask=0077,shortname=winnt" --label=efi
part /boot --fstype="ext4" --size=2048 --label=boot
part / --fstype="ext4" --grow --label=root --mkfsoptions="-O encrypt,fast_commit"
%post --logfile=/mnt/sysimage/root/post.log
localectl set-keymap ch-fr # Set keymap to `ch-fr`. Alternatively, `us` can be picked.
dnf update -y # Update the system
grub2-mkconfig -o /boot/grub2/grub.cfg # Unsure it is actually useful
%end
part /boot/efi --fstype="efi" --size=512 --fsoptions="umask=0077,shortname=winnt" --label="efi"
part /boot --fstype="ext4" --size=2048 --label="boot"
part / --fstype="ext4" --grow --label="root" --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/base-desktop-gnome.log
Vendored Submodule
+1
Submodule external/kickstart-tests added at f3da604ad8
Vendored Submodule
+1
Submodule external/pykickstart added at 601ec2d2f2
@@ -0,0 +1,3 @@
# GRUB bootloader configuration for live media (no location, minimal timeout)
bootsupport --timeout=1 # Set the GNU GRUB bootloader timeout to 1 and to location to none
@@ -0,0 +1,3 @@
# systemd-boot bootloader configuration for live media (no location, minimal timeout)
bootsupport --sdboot --location=none --timeout=1 # Use systemd-boot and set location to none
@@ -0,0 +1,5 @@
# Fedora 43 repositories
repo --name=fedora --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&arch=x86_64 # Official Fedora mirror
repo --name=updates --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=updates-released-f43&arch=x86_64 # Official Fedora updates mirror
url --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&arch=x86_64 # Official Fedora updates mirror
@@ -0,0 +1,3 @@
# Fedora ISO repository for F43 (for live ISO builds)
# repo --name=fedora-iso --metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-43&arch=x86_64 # Uncomment for ISO builds
@@ -0,0 +1,3 @@
# GRUB bootloader configuration for live media (no location, minimal timeout)
bootsupport --timeout=1 # Set the GNU GRUB bootloader timeout to 1 and to location to none
@@ -0,0 +1,3 @@
# systemd-boot bootloader configuration for live media (no location, minimal timeout)
bootsupport --sdboot --location=none --timeout=1 # Use systemd-boot and set location to none
@@ -0,0 +1,4 @@
# Fedora Rawhide repositories
repo --name=rawhide --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=rawhide&arch=x86_64
url --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=rawhide&arch=x86_64
+3
View File
@@ -0,0 +1,3 @@
# GRUB bootloader configuration
bootsupport --timeout=1 # Set the GNU GRUB bootloader timeout to 1
@@ -0,0 +1,3 @@
# systemd-boot bootloader configuration
bootsupport --sdboot --location=mbr --timeout=1 # Use systemd-boot and set a timeout to 1
+5
View File
@@ -0,0 +1,5 @@
# Core base kickstart configuration
# Common settings for all Phyllome OS installations
text # Kickstart installation in text mode
poweroff # Shut down the system after a successful installation
+5
View File
@@ -0,0 +1,5 @@
# Keyboard, language, and timezone configuration
keyboard --xlayouts='ch (fr)' # Set keyboard layouts for Romandy
lang en_US.UTF-8 # Set system language to American English. More languages could be supported: --addsupport=cs_CZ,de_DE,en_UK
timezone Europe/Zurich --utc # Set system timezone to Zurich
+3
View File
@@ -0,0 +1,3 @@
# Network configuration
network --onboot=yes --bootproto=dhcp --device=link --activate --hostname=phyllome-alpha # Configure network devices, enable them at boot time device and sets a particular hostname. "link" selects the first device reaching an up state
@@ -0,0 +1,5 @@
# Security configuration - disabled mode
rootpw --plaintext 1234 --allow-ssh # Root account is enabled with weak password and allow ssh
selinux --disabled # Disable SELinux
firewall --enabled --ssh # Reject incoming connections that are not in response to outbound requests except SSH
@@ -0,0 +1,5 @@
# Security configuration - enabled mode
rootpw --lock # No root login from the console
selinux --enforcing # Set SELinux to enforcing mode
firewall --enabled # Enable firewall
+3
View File
@@ -0,0 +1,3 @@
# System services
services --enabled=NetworkManager,systemd-resolved # List of comma-separated systemd services that can be explicitly enabled
+1
View File
@@ -0,0 +1 @@
xconfig --startxonboot --defaultdesktop=GNOME # Start the display session on boot. Although it says --startx, which seems to imply xorg, it is actually generic and thus works also with Wayland.
@@ -0,0 +1,51 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# GNOME desktop packages
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies
@base-graphical
## provides the following as mandatory packages:
# mesa-dri-drivers
# mesa-vulkan-drivers
# plymouth-system-theme
# @critical-path-gnome not using this group but hand-picking packages
## Mandatory packages found in hidden `@critical-path-gnome` group (`dnf group info --hidden critical-path-gnome`)
## Not using
## provides the following as mandatory packages:
bash-color-prompt # Color prompt for bash shell
dconf # A configuration system
gdm # The GNOME Display Manager
# gnome-classic-session # GNOME "classic" mode session
gnome-control-center # Utilities to configure the GNOME desktop
# gnome-initial-setup # Bootstrapping your OS
gnome-shell # Window management and application launching for GNOME
gvfs-fuse # FUSE support for gvfs
# ptyxis # A container oriented terminal for GNOME
### and the following as default packages
# NetworkManager-pptp # NetworkManager VPN plugin for PPTP
# avahi # Local network service discovery
# gnome-bluetooth # Bluetooth graphical utilities
gnome-session-wayland-session # Desktop file for wayland based gnome session
# gnome-software # A software center for GNOME
nautilus # File manager for GNOME
# toolbox # Tool for interactive command line environments on Linux
## Extra hand-picked packages
gnome-backgrounds.noarch # wallpapers from the GNOME project
gnome-terminal # Terminal emulator for GNOME
dejavu-sans-mono-fonts # the gnome-shell package doesn't include much fonts by default, resulting in weird spacings in GNOME Terminal. GNOME Terminal unfortunately doesn't automatically pick this font
firefox # Mozilla Firefox Web browser
mozilla-ublock-origin.noarch # An efficient blocker for Firefox
pipewire-alsa # PipeWire media server ALSA support
pipewire-pulseaudio # PipeWire PulseAudio implementation
pipewire-jack-audio-connection-kit # PipeWire JACK implementation
%end # End of the packagages section
@@ -0,0 +1,65 @@
# GNOME desktop post-installation configuration
%post --nochroot --log=/mnt/sysimage/root/gnome-desktop-post.log # Beginning of %post section. Those commands are executed outside the chroot environment
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.media-handling.gschema.override<< EOF
[org.gnome.desktop.media-handling]
automount-open=false
autorun-never=true
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.Terminal.gschema.override<< EOF
[org.gnome.Terminal.Legacy.Profile]
font='DejaVu Sans Mono 12'
use-system-font=false
auditable-bell=false
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.wm.preferences.gschema.override<< EOF
[org.gnome.desktop.wm.preferences]
button-layout=':minimize,maximize,close'
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.a11y.gschema.override<< EOF
[org.gnome.desktop.a11y]
always-show-universal-access-status=true
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.interface.gschema.override<< EOF
[org.gnome.desktop.interface]
enable-animations=false
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.privacy.gschema.override<< EOF
[org.gnome.desktop.privacy]
remove-old-temp-files=true
remember-recent-file=false
remember-app-usage=false
disable-camera=true
disable-microphone=true
disable-sound-output=true
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.search-providers.gschema.override<< EOF
[org.gnome.desktop.search-providers]
disable-external=true
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.notifications.gschema.override<< EOF
[org.gnome.desktop.notifications.application]
enable-sound-alerts=false
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.sound.gschema.override<< EOF
[org.gnome.desktop.sound]
event-sounds=false
EOF
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.thumbnailers.gschema.override<< EOF
[org.gnome.desktop.thumbnailers]
disable-all=true
EOF
glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%end # End of the %post section
+19
View File
@@ -0,0 +1,19 @@
# Untested
xconfig --startxonboot # Start the display session on boot. Although it says --startx, which seems to imply xorg, it is actually generic and thus works also with Wayland.
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
@base-graphical
## provides the following as mandatory packages:
# mesa-dri-drivers
# mesa-vulkan-drivers
# plymouth-system-theme
labwc # A Wayland window-stacking compositor
## Extra hand-picked packages
firefox # Mozilla Firefox Web browser
mozilla-ublock-origin.noarch # An efficient blocker for Firefox
%end # End of the packagages section
+68
View File
@@ -0,0 +1,68 @@
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
virt-manager # Install virt-manager, a graphical front-end for QEMU/KVM
%end
%post --nochroot --log=/mnt/sysimage/root/virt-manager-post.log # Beginning of %post section. Those commands are executed outside the chroot environment. Add logging.
# Create a file to autostart virt-manager
cat > /mnt/sysimage/etc/xdg/autostart/virt-manager.desktop << EOF
[Desktop Entry]
Type=Application
Name=Virtual Machine Manager
Exec=virt-manager
EOF
# Modify the default virt-manager behavior for misc. options
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.virt-manager.virt-manager.gschema.override<< EOF
# Modify the default virt-manager behavior for misc. options
[org.virt-manager.virt-manager]
xmleditor-enabled=true
manager-window-height=600
manager-window-width=200
# Libvirt URIs listed in the manager window
[org.virt-manager.virt-manager.connections]
uris=['qemu:///system', 'qemu:///session']
autoconnect=['qemu:///session']
# Show usage in the domain list
[org.virt-manager.virt-manager.vmlist-fields]
cpu-usage=false
# Settings related to statistics
[org.virt-manager.virt-manager.stats]
update-interval=3
enable-disk-poll=true
enable-memory-poll=true
enable-net-poll=true
# Default behavior for the console
[org.virt-manager.virt-manager.console]
scaling=2
resize-guest=1
autoconnect=false
# Do not show toolbar
[org.virt-manager.virt-manager.details]
show-toolbar=false
# Modify default values for new VMs
[org.virt-manager.virt-manager.new-vm]
storage-format='raw'
cpu-default='host-model'
graphics-type='spice'
# Modify the default virt-manager behavior for confirmation dialogues
[org.virt-manager.virt-manager.confirm]
forcepoweroff=false
removedev=false
unapplied-dev=false
EOF
glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%end # End of the %post section
@@ -0,0 +1,56 @@
# Virt-manager post-installation configuration
%post --nochroot --log=/mnt/sysimage/root/vmm-post-scripts.log # Beginning of %post section
# Create a file to autostart virt-manager
cat > /mnt/sysimage/etc/xdg/autostart/virt-manager.desktop << EOF
[Desktop Entry]
Type=Application
Name=Virtual Machine Manager
Exec=virt-manager
EOF
# Modify the default virt-manager behavior for misc. options
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.virt-manager.virt-manager.gschema.override<< EOF
[org.virt-manager.virt-manager]
xmleditor-enabled=true
manager-window-height=600
manager-window-width=200
[org.virt-manager.virt-manager.connections]
uris=['qemu:///system', 'qemu:///session']
autoconnect=['qemu:///session']
[org.virt-manager.virt-manager.vmlist-fields]
cpu-usage=false
[org.virt-manager.virt-manager.stats]
update-interval=3
enable-disk-poll=true
enable-memory-poll=true
enable-net-poll=true
[org.virt-manager.virt-manager.console]
scaling=2
resize-guest=1
autoconnect=false
[org.virt-manager.virt-manager.details]
show-toolbar=false
[org.virt-manager.virt-manager.new-vm]
storage-format='raw'
cpu-default='host-model'
graphics-type='spice'
[org.virt-manager.virt-manager.confirm]
forcepoweroff=false
removedev=false
unapplied-dev=false
EOF
glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%end # End of the %post section
@@ -0,0 +1,8 @@
# Guest agents for virtual machines
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
qemu-guest-agent # "QEMU guest agent" The qemu-guest agent is unnecessary for a bare-metal system. However, it is included here to cover cases where this kickstart file is used to deploy a virtual machine
spice-vdagent # "Agent for Spice guests" The spice agent is unnecessary for a bare-metal system. However, it is included here to cover cases where this kickstart file is used to deploy a virtual machine
%end # End of the packages section
+9
View File
@@ -0,0 +1,9 @@
# AMD CPU optimization for hypervisor
%post --nochroot --log=/mnt/sysimage/root/hypervisor-amdcpu-post.log # Beginning of %post section. Those commands are executed outside the chroot environment. Logging is enabled to help with post-installation troubleshooting
sed -i 's/\(quiet\)/\1 iommu=pt rd.driver.pre=vfio-pci/i' /mnt/sysimage/etc/default/grub # Load kernel modules in GRUB.
echo "options kvm_amd nested=1" >> /mnt/sysimage/etc/modprobe.d/kvm.conf # Add support for nested virtualization
%end # End of the %post section
@@ -0,0 +1,30 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Virtualization packages
%packages --exclude-weakdeps # Beginning of the packages section. Does not include weak dependencies.
qemu-kvm # QEMU metapackage for KVM support
libvirt # Library providing a simple virtualization API
libvirt-client # Client side utilities of the libvirt library
libvirt-client-qemu # Additional client side utilities for QEMU. Used to interact with some QEMU specific features of libvirt.
libvirt-daemon # Server side daemon and supporting files for libvirt library
libvirt-daemon-common # Miscellaneous files and utilities used by other libvirt daemons
libvirt-daemon-config-network # Default configuration files for the libvirtd daemon. Provides NAT based networking
libvirt-daemon-driver-interface # Interface driver plugin for the libvirtd daemon
libvirt-daemon-driver-network # The network driver plugin for the libvirtd daemon, providing an implementation of the virtual network APIs using the Linux bridge capabilities.
libvirt-daemon-driver-qemu # QEMU driver plugin for the libvirtd daemon
libvirt-daemon-kvm # Server side daemon & driver required to run KVM guests
libvirt-daemon-log # Server side daemon for managing logs
libvirt-daemon-qemu # Server side daemon and driver required to manage the virtualization capabilities of the QEMU TCG emulators
libvirt-nss # Libvirt plugin for Name Service Switch
libvirt-dbus # libvirt D-Bus API binding
libvirt-daemon-driver-ch # Cloud-Hypervisor driver plugin for libvirtd daemon
virt-install # Utilities for installing virtual machines
%end # End of the packages section
@@ -0,0 +1,31 @@
# Hypervisor base post-installation configuration
%post --nochroot --log=/mnt/sysimage/root/hypervisor-base-post.log # Beginning of %post section. Those commands are executed outside the chroot environment. Logging is enabled to help with post-installation troubleshooting
# Load kernel modules by adding vfio, vfio_pci, vfio_iommu_type1, vfio_virqfd
echo "vfio" > /mnt/sysimage/etc/modules-load.d/vfio.conf
echo "vfio-pci" > /mnt/sysimage/etc/modules-load.d/vfio-pci.conf
echo "vfio_iommu_type1" > /mnt/sysimage/etc/modules-load.d/vfio_iommu_type1.conf
echo "vfio_virqfd" > /mnt/sysimage/etc/modules-load.d/vfio_virqfd.conf
mkdir /mnt/sysimage/var/lib/libvirt/isos # Create a directory to store iso images. SELinux is already taking this one into account.
# wget https://boot.netboot.xyz/ipxe/netboot.xyz.iso -P /mnt/sysimage/var/lib/libvirt/isos/ # fetch netboot.xyz iso and store it to the newly created iso directory
# # virsh commands fail in a kickstart environment (chroot or not it seems). would need to fetch a script and execute post-launch with a delay, for example using a systemd unit
# virsh pool-define-as isos dir - - - - /mnt/sysimage/var/lib/libvirt/isos/ # Make libvirt aware of this new directory by creating a so-called 'pool'.
# virsh pool-build isos # Build the pool
# virsh pool-start isos # Start it
# virsh pool-autostart isos # Set-it to autostart
# fetch custom script and make it executable
# wget https://raw.githubusercontent.com/PhyllomeOS/phyllomeos/main/post-first-startup-scripts/virtualization-tweaks-root-needed.sh -P /mnt/sysimage/usr/local/bin/
# chmod +x /mnt/sysimage/usr/local/bin/virtualization-tweaks-root-needed.sh
# wget https://raw.githubusercontent.com/PhyllomeOS/xml-definition-for-domains/main/xml/system/linux.xml
# virsh define linux.xml
# wget https://raw.githubusercontent.com/PhyllomeOS/xml-definition-for-domains/main/xml/system/windows.xml
# virsh define windows.xml
%end # End of the %post section
@@ -0,0 +1,3 @@
# Hypervisor base configuration
services --enabled="NetworkManager,systemd-resolved,libvirtd" # Without libvirtd here, it appears the service won't automatically start
+9
View File
@@ -0,0 +1,9 @@
# Intel CPU optimization for hypervisor
%post --nochroot --log=/mnt/sysimage/root/hypervisor-intelcpu-post.log # Beginning of %post section. Those commands are executed outside the chroot environment. Logging is enabled to help with post-installation troubleshooting
sed -i 's/\(quiet\)/\1 intel_iommu=on iommu=pt rd.driver.pre=vfio-pci/i' /mnt/sysimage/etc/default/grub # Load kernel modules in GRUB.
echo "options kvm_intel nested=1" >> /mnt/sysimage/etc/modprobe.d/kvm.conf # Add support for nested virtualization on Intel CPUs
%end # End of the %post section
+11
View File
@@ -0,0 +1,11 @@
# Intel GPU passthrough configuration
%post --nochroot --log=/mnt/sysimage/root/hypervisor-intelgpu-post.log # Beginning of %post section. Those commands are executed outside the chroot environment. Logging is enabled to help with post-installtion troubleshooting
sed -i 's/\(vfio-pci\)/\1 i915.enable_gvt=1/i' /mnt/sysimage/etc/default/grub # Load kernel modules in grub.
# Load extra kernel modules to enable vfio-mdev on selected hardware
echo "kvmgt" > /mnt/sysimage/etc/modules-load.d/kvmgt.conf # Load specific kernel modules kvmgt and vfio-mdev, for Intel (tm) GVT-g and Nvidia (tm)
echo "vfio-mdev" > /mnt/sysimage/etc/modules-load.d/vfio-mdev.conf # Load specific kernel modules kvmgt and vfio-mdev, for Intel (tm) GVT-g and Nvidia (tm)
%end # End of the %post section
@@ -0,0 +1,25 @@
# Initial setup - GNOME desktop mode
firstboot --enable # Initial Setup will start after the first reboot
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
# TO BE TESTED -> initial-setup-gui # Graphical user interface for the initial-setup utility
# TO BE TESTED -> initial-setup-gui-wayland-generic.x86_64 # Run the initial-setup GUI in Wayland
gnome-initial-setup # Add GNOME initial setup too to let user create local account.
%end # End of the packages section
# %post --nochroot --log=/mnt/sysimage/root/initial-setup-gnome.log # Beginning of %post section. Those commands are executed outside the chroot environment. Add logging.
#
# truncate -s 0 /mnt/sysimage/usr/share/gnome-initial-setup/vendor.conf # remove content of vendor.conf so that all options are made available
#
# ## Append lines to existing vendor.conf file, so that options are skipped upon reboot
# cat >> /mnt/sysimage/usr/share/gnome-initial-setup/vendor.conf<< EOF
# [pages]
# skip=privacy
# [goa]
# providers=local-first!
# EOF
#
# %end # End of the %post section
@@ -0,0 +1,9 @@
# Initial setup packages - GNOME desktop mode
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
# TO BE TESTED -> initial-setup-gui # Graphical user interface for the initial-setup utility
# TO BE TESTED -> initial-setup-gui-wayland-generic.x86_64 # Run the initial-setup GUI in Wayland
gnome-initial-setup # Add GNOME initial setup too to let user create local account.
%end # End of the packages section
@@ -0,0 +1,11 @@
# Initial setup - generic wayland desktop mode
firstboot --enable # Initial Setup will start after the first reboot
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
# TO BE TESTED -> initial-setup-gui # Graphical user interface for the initial-setup utility
# TO BE TESTED -> initial-setup-gui-wayland-generic.x86_64 # Run the initial-setup GUI in Wayland
gnome-initial-setup # Add GNOME initial setup too to let user create local account.
%end # End of the packages section
@@ -0,0 +1,8 @@
# Initial setup packages - generic wayland desktop mode
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
initial-setup-gui # Graphical user interface for the initial-setup utility
initial-setup-gui-wayland-generic.x86_64 # Run the initial-setup GUI in Wayland
%end # End of the packages section
@@ -0,0 +1,9 @@
# Initial setup - server mode
firstboot --enable --reconfig # Enable the Setup Agent to start at boot time in reconfiguration mode. This mode enables the language, mouse, keyboard, root password, security level, time zone, and networking configuration options in addition to the default ones
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
initial-setup # Initial setup package
%end # End of the packages section
@@ -0,0 +1,7 @@
# Initial setup packages - server mode
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies.
initial-setup # Initial setup package
%end # End of the packages section
+3
View File
@@ -0,0 +1,3 @@
# Live core base configuration
poweroff # Shut down the system after a successful installation
@@ -0,0 +1,3 @@
# Live core bootloader configuration
bootloader --timeout=1 # Set the GNU GRUB bootloader timeout to 1 and to location to none
@@ -0,0 +1,3 @@
# Live core systemd-boot configuration
bootloader --sdboot --location=none --timeout=1 # Use systemd-boot and set location to none
+25
View File
@@ -0,0 +1,25 @@
# Anaconda tools and kernel packages for live media
%packages # Beginning of the package section. Include weak dependencies. Description courtesy of the Fedora project
@anaconda-tools
# Explicitly specified here:
# <notting> walters: because otherwise dependency loops cause yum issues.
kernel
kernel-modules
kernel-modules-extra
# Need aajohan-comfortaa-fonts for the SVG rnotes images
aajohan-comfortaa-fonts
# Without this, initramfs generation during live image creation fails: #1242586
dracut-live
# anaconda needs the locales available to run for different locales
glibc-all-langpacks
# provide the livesys scripts
livesys-scripts
%end
+7
View File
@@ -0,0 +1,7 @@
# Live core storage configuration
zerombr # WARNING : Dangerous command ! Will clear the Master Boot Record
clearpart --all --initlabel # Partition clearing information. This setup uses GPT by default.
part / --fstype="ext4" --size=5120 # Create a root partition of around 7GB
part / --size=8576
+10
View File
@@ -0,0 +1,10 @@
# Hypervisor package inclusion for live server
%packages --exclude-weakdeps
qemu-kvm
libvirt
libvirt-client
virt-install
%end
+53
View File
@@ -0,0 +1,53 @@
# Live core post-installation configuration
%post --log=/mnt/sysimage/root/live-core-post.log # Beginning of the post-installation section. Add logging.
# Enable livesys services
systemctl enable livesys.service
systemctl enable livesys-late.service
# enable tmpfs for /tmp
systemctl enable tmp.mount
# make it so that we don't do writing to the overlay for things which
# are just tmpdirs/caches
# note https://bugzilla.redhat.com/show_bug.cgi?id=1135475
cat >> /etc/fstab << EOF
vartmp /var/tmp tmpfs defaults 0 0
EOF
# work around for poor key import UI in PackageKit
rm -f /var/lib/rpm/__db*
echo "Packages within this LiveCD"
rpm -qa --qf '%{size}\t%{name}-%{version}-%{release}.%{arch}\n' |sort -rn
# Note that running rpm recreates the rpm db files which aren't needed or wanted
rm -f /var/lib/rpm/__db*
# go ahead and pre-make the man -k cache (#455968)
/usr/bin/mandb
# make sure there aren't core files lying around
rm -f /core*
# remove random seed, the newly installed instance should make it's own
rm -f /var/lib/systemd/random-seed
# convince readahead not to collect
# FIXME: for systemd
echo 'File created by kickstart. See systemd-update-done.service(8).' \
| tee /etc/.updated >/var/.updated
# Drop the rescue kernel and initramfs, we don't need them on the live media itself.
# See bug 1317709
rm -f /boot/*-rescue*
# Disable network service here, as doing it in the services line
# fails due to RHBZ #1369794
systemctl disable network
# Remove machine-id on pre generated images
rm -f /etc/machine-id
touch /etc/machine-id
%end
+8
View File
@@ -0,0 +1,8 @@
# Live session configuration
%post --log=/mnt/sysimage/root/post-live-session.log # Beginning of the post-installation section. Add logging.
# set livesys session type
sed -i 's/^livesys_session=.*/livesys_session="gnome"/' /etc/sysconfig/livesys
%end
+67
View File
@@ -0,0 +1,67 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Core DNF package group
# More information: https://pykickstart.readthedocs.io/en/latest/kickstart-docs.html#id240
%packages --exclude-weakdeps # Beginning of the packages section. Excludes weak package dependencies. Package description courtesy of the Fedora project
@core
## Mandatory packages found in hidden `core` group (`dnf group info --hidden core`)
# audit # User space tools for kernel auditing
# basesystem # The skeleton package which defines a simple Fedora system
# bash # The Bourne Again SHell, a command-line interpreter.
# coreutils # A set of basic GNU tools commonly used in shell scripts
# curl # A utility for getting files from remote servers (FTP, HTTP, and others)
# dhcp-client # Provides the ISC DHCP client daemon and dhclient-script
# dnf5 # Command-line package manager
# e2fsprogs # Utilities for managing ext2, ext3, and ext4 file systems
# filesystem # The basic directory layout for a Linux system
# glibc # The GNU libc libraries
# hostname # Utility to set/show the host name or domain name
# iproute # Advanced IP routing and network device configuration tools
# iputils # Network monitoring tools including ping
# kbd # Tools for configuring the console (keyboard, virtual terminals, etc.)
# kernel # The Linux kernel
# less # A text file browser similar to more, but better. Can be excluded
# man-db # Tools for searching and reading man pages. Can be excluded
# ncurses # Ncurses support utilities
# openssh-clients # An open source SSH client applications. Can be excluded
# openssh-server # An open source SSH server daemon. Can be excluded
# parted # The GNU disk partition manipulation program
# policycoreutils # SELinux policy core utilities. Can be excluded
# procps-ng # System and process monitoring utilities
# rootfiles # The basic required files for the root user's directory
# rpm # The RPM package management system
# selinux-policy-targeted # SELinux targeted policy. Can be excluded
# setup # A set of system configuration and setup files
# shadow-utils # Utilities for managing accounts and shadow password files
# sssd-common # Common files for the SSSD. Can be excluded
# sssd-kcm # An implementation of a Kerberos KCM server. Can be excluded
# sudo # Allows restricted root access for specified users
# systemd # System and Service Manager
# util-linux # Collection of basic system utilities
# vim-minimal # A minimal version of the VIM editor
## Default packages found in hidden `core` group (`dnf group info --hidden core`)
# NetworkManager # Network connection manager and user applications
# dnf5-plugins # Plugins for dnf5
# dracut-config-rescue # dracut configuration to turn on rescue image generation
# firewalld # A firewall daemon with D-Bus interface providing a dynamic firewall
# fwupd # Firmware update daemon
# plymouth # Graphical Boot Animation and Logger
# prefixdevname # Udev helper utility that provides network interface naming using user defined prefix
# systemd-resolved # Network Name Resolution manager
# zram-generator-defaults # Default configuration for zram-generator
## Optionnal packages found in hidden `core` group (`dnf group info --hidden core`)
## Not installed by default unless "@core --optional" is used
# dracut-config-generic
# initial-setup
# initscripts
%end # End of the packages section
+18
View File
@@ -0,0 +1,18 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Packages to be used to create a Fedora Remix and comply Fedora Remix legal guidelines: https://fedoraproject.org/wiki/Remix
%packages --exclude-weakdeps
fedora-remix-logos # Fedora Remix logos
generic-release # Generic release files
generic-logos # Icons and pictures
generic-release-common # Generic release files
generic-release-notes # Release Notes
%end # End of the packages section
+12
View File
@@ -0,0 +1,12 @@
# Hand-picked packages
%packages --exclude-weakdeps
pciutils # PCI bus related utilities
libusb # Library for accessing USB devices
usbutils # Linux USB utilities
curl # transfer a URL
wget # An advanced file and recursive website downloader
nano # A small text editor
%end # End of the packages section
@@ -0,0 +1,61 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Extended physical hardware support. Useful for bare metal deployments.
%packages --exclude-weakdeps
@hardware-support
## Mandatory packages found in hidden `hardware-support` group
# alsa-sof-firmware # Audio drivers and firmware for ALSA. Essential for audio functionality.
# amd-gpu-firmware # Firmware for AMD GPUs. Required for proper GPU operation.
# atheros-firmware # Firmware for Atheros wireless network adapters. Critical for wireless connectivity.
# b43-fwcutter # Utility for cutting firmware files for B43 drivers. Needed for driver compatibility.
# b43-openfwwf # Driver and firmware for B43 network cards. Essential for network card operation.
# brcmfmac-firmware # Firmware for Broadcom MAC controllers. Required for wireless and wired network performance.
# cirrus-audio-firmware # Firmware for Cirrus Logic audio chips. Necessary for audio hardware support.
# intel-audio-firmware # Firmware for Intel audio processors. Required for integrated audio functionality.
# intel-gpu-firmware # Firmware for Intel GPUs. Essential for GPU operation.
# intel-vsc-firmware # Firmware for Intel Video Scheduling Controller. Required for GPU performance.
# iwlegacy-firmware # Legacy firmware for older Intel wireless cards. Needed for compatibility.
# iwlwifi-dvm-firmware # Firmware for Intel Wireless Link 5100/5200 series. Crucial for wireless connectivity.
# iwlwifi-mvm-firmware # Firmware for Intel Wireless Link 5300/5400 series. Required for wireless performance.
# libertas-firmware # Firmware for Broadcom wireless network cards. Essential for wireless connectivity.
# mt7xxx-firmware # Firmware for MediaTek wireless network adapters. Required for wireless connectivity.
# nvidia-gpu-firmware # Firmware for NVIDIA GPUs. Essential for GPU operation.
# nxpwireless-firmware # Firmware for NXP wireless network adapters. Required for wireless connectivity.
# realtek-firmware # Firmware for Realtek network adapters and audio devices. Essential for various device support.
# tiwilink-firmware # Firmware for TI WiLink wireless network adapters. Required for wireless connectivity.
## Optional packages found in hidden `hardware-support` group
## Not installed by default unless "@hardware-support --optional" is used
# acpi # Command-line ACPI client
# acpitool # Command line ACPI client
# alsa-firmware # Firmware for several ALSA-supported sound cards
# atmel-firmware # Firmware for Atmel at76c50x wireless network chips
# cmospwd # BIOS password cracker utility
# dvb-firmware # Firmware for various DVB broadcast receivers
# gpsd # Service daemon for mediating access to a GPS
# gpsd-clients # Clients for gpsd
# hddtemp # Hard disk temperature tool
# hdparm # A utility for displaying and/or setting hard disk parameters
# iscan-firmware # Firmware for Epson flatbed scanners
# libifp # General-purpose library-driver for iRiver's iFP portable audio players
# lsscsi # List SCSI devices (or hosts) and associated information
# mlxsw_spectrum-firmware # Firmware for Mellanox Spectrum 1/2/3 Switches
# mrvlprestera-firmware # Firmware for Marvell Prestera Switchdev/ASIC devices
# netronome-firmware # Firmware for Netronome Smart NICs
# opensc # Smart card library and applications
# pcsc-lite # PC/SC Lite smart card framework and applications
# pcsc-lite-ccid # Generic USB CCID smart card reader driver
# qcom-accel-firmware # Firmware for Qualcomm Technologies data center / Open-vRAN Accelerators
# qed-firmware # Firmware for Marvell FastLinQ adapters family
# radeontop # AMD Radeon video cards monitoring utility
# wpan-tools # Userspace tools for the Linux IEEE 802.15.4 stack
# zd1211-firmware # Firmware for wireless devices based on zd1211 chipset
%end # End of the packages section
@@ -0,0 +1,21 @@
# RPM Fusion non-free repositories
# RPM fusion repositories
# For the current release tree
repo --name=rpmfusion-nonfree --mirrorlist=https://mirrors.rpmfusion.org/mirrorlist?repo=nonfree-fedora-$releasever&arch=$basearch --includepkgs=rpmfusion-nonfree-release
# Updates for the current release tree
repo --name=rpmfusion-nonfree-updates --mirrorlist=https://mirrors.rpmfusion.org/mirrorlist?repo=nonfree-fedora-updates-released-$releasever&arch=$basearch --includepkgs=rpmfusion-nonfree-release
%post
# Import RPM Fusion PGP Key. Courtesy of https://github.com/rpmfusion/rpmfusion-nonfree-remix-kickstarts/blob/master/rpmfusion-nonfree-live-base.ks
echo "== RPM Fusion Nonfree: Base section =="
echo "Importing RPM Fusion keys"
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-nonfree-fedora-*-primary
echo "List of packages from RPM Fusion Nonfree:"
rpm -qa --qf '%{NAME} %{SIGGPG:pgpsig} %{SIGPGP:pgpsig} \n' | grep -e 3DE8C682E38EE9BC0FDFEA47FCAE2EA87F858107 | awk ' { print $1 } ' | sort
echo "List of incuded RPM Fusion packages with their size:"
rpm -q --qf '%{SIZE} %{NAME}\n' $(rpm -qa --qf '%{NAME} %{SIGGPG:pgpsig} %{SIGPGP:pgpsig} \n' | grep -e 3DE8C682E38EE9BC0FDFEA47FCAE2EA87F858107 | awk ' { print $1 } ') | sort -n
echo
%end
@@ -0,0 +1,9 @@
# Core post-installation configuration
%post --log=/mnt/sysimage/root/post.log # Beginning of the post-installation section. Log all messages to a given file
localectl set-keymap ch-fr # Set keymap to `ch-fr`. Alternatively, `us` can be picked.
dnf update -y # Update the system
grub2-mkconfig -o /boot/grub2/grub.cfg # Unsure it is actually useful
%end # End of the %post section
@@ -0,0 +1,5 @@
# Post-installation no-chroot section
%post --nochroot --log=/mnt/sysimage/root/post-nochroot.log # Beginning of the post-installation section. Log all messages to a given file
%end # End of the %post section
@@ -0,0 +1,5 @@
# Pre-installation kickstart section
%pre --log=/mnt/sysimage/root/pre.log Beginning of the pre section. Log all messages to a given file
%end # End of the %post section
@@ -0,0 +1,5 @@
# Pre-installation kickstart section
%pre --log=/mnt/sysimage/root/pre-install.log Beginning of the pre-installation section. Log all messages to a given file
%end # End of the %post section
+8
View File
@@ -0,0 +1,8 @@
# Encrypted storage configuration
zerombr # Destroy all the contents of disks with invalid partition tables or other formatting unrecognizable to the installer
clearpart --all --initlabel # Erase all partitions and Initializes the disk label to the default for the target architecture
part /boot/efi --fstype="efi" --size=512 --fsoptions="umask=0077,shortname=winnt" --label=efi # Creates a 512 MiB EFI system partition
part /boot --fstype="ext4" --size=2048 --label=boot # Creates a 2048 MiB ext4 boot partition
part / --fstype="ext4" --grow --label=root --mkfsoptions="-O encrypt,fast_commit" --encrypted --passphrase= # Create a single encrypted root partition with the remaining space.
+8
View File
@@ -0,0 +1,8 @@
# Standard storage configuration
zerombr # Destroy all the contents of disks with invalid partition tables or other formatting unrecognizable to the installer
clearpart --all --initlabel # Erase all partitions and Initializes the disk label to the default for the target architecture
part /boot/efi --fstype="efi" --size=512 --fsoptions="umask=0077,shortname=winnt" --label=efi # Creates a 512 MiB EFI system partition
part /boot --fstype="ext4" --size=2048 --label=boot # Creates a 2048 MiB ext4 boot partition
part / --fstype="ext4" --grow --label=root --mkfsoptions="-O encrypt,fast_commit" # Create a single root partition with the remaining space
+6
View File
@@ -0,0 +1,6 @@
# Validation fragment - success if empty
%post
# If this is being run, it's a success
echo SUCCESS > /root/RESULT
%end
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for an AMD (tm) CPU-based desktop hypervisor
%include ../ingredients/core.cfg # Text mode for automated installation
%include ../ingredients/core-storage.cfg # Storage configuration
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale
%include ../ingredients/core-security-on.cfg # Lock root account, enable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-packages-hardware-support.cfg # Provides extended hardware support
%include ../ingredients/core-fedora-repo-rawhide.cfg # Offical repositories for Fedora Rawhide
%include ../ingredients/core-post.cfg # Post configuration script
%include ../ingredients/core-initial-setup-gnome-desktop.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/base-desktop-gnome.cfg # A GNOME Shell-based desktop environment
%include ../ingredients/base-desktop-virtual-machine-manager.cfg # Virtual Machine Manager
%include ../ingredients/base-hypervisor.cfg # Base hypervisor
%include ../ingredients/base-hypervisor-amdcpu.cfg # Virtualization configuration for AMD (tm) CPUs
@@ -0,0 +1,27 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for an Intel(tm) CPU- and Intel(tm) GPUs-based desktop hypervisor
# vfio-mdev compatible GPUs required. For Intel, it means 5th to 10th generation only
%include ../ingredients/core.cfg # Text mode
%include ../ingredients/core-storage.cfg # ext4-based storage configuration
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-on.cfg # Lock root account, enable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-packages-hardware-support.cfg # Extended hardware support
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/core-post.cfg # Triggered after the installation
%include ../ingredients/core-initial-setup-gnome-desktop.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/core-initial-setup-gnome-desktop.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/base-desktop-virtual-machine-manager.cfg # Virtual Machine Manager
%include ../ingredients/base-hypervisor.cfg # Base hypervisor
%include ../ingredients/base-hypervisor-intelcpu.cfg # Virtualization configuration for Intel (tm) CPUs
%include ../ingredients/base-hypervisor-intelgpu.cfg # Virtualization configuration for Intel (tm) GPUs from 4th to the 9th generation (compatible with vfio-mdev)
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for an Intel(tm)-based desktop hypervisor
%include ../ingredients/core.cfg # Text mode
%include ../ingredients/core-storage.cfg # ext4-based storage configuration
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-on.cfg # Lock root account, enable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-packages-hardware-support.cfg # Extended hardware support
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/core-post.cfg # Triggered after the installation
%include ../ingredients/core-initial-setup-gnome-desktop.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/base-desktop-gnome.cfg # A GNOME Shell-based desktop environment
%include ../ingredients/base-desktop-virtual-machine-manager.cfg # Virtual Machine Manager
%include ../ingredients/base-hypervisor.cfg # Base hypervisor
%include ../ingredients/base-hypervisor-intelcpu.cfg # Virtualization configuration for Intel (tm) CPUs
@@ -0,0 +1,23 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a desktop hypervisor
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-packages-hardware-support.cfg
%include ../ingredients/core-initial-setup-gnome-desktop.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-desktop-virtual-machine-manager.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-hypervisor-amdcpu.cfg
%include ../ingredients/None.cfg
@@ -0,0 +1,23 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a desktop hypervisor
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-packages-hardware-support.cfg
%include ../ingredients/core-initial-setup-gnome-desktop.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-desktop-virtual-machine-manager.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-hypervisor-intelcpu.cfg
%include ../ingredients/base-hypervisor-intelgpu.cfg
@@ -0,0 +1,23 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a desktop hypervisor
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-packages-hardware-support.cfg
%include ../ingredients/core-initial-setup-gnome-desktop.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-desktop-virtual-machine-manager.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-hypervisor-intelcpu.cfg
%include ../ingredients/None.cfg
@@ -0,0 +1,23 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a desktop hypervisor
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-packages-hardware-support.cfg
%include ../ingredients/core-initial-setup-gnome-desktop.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-desktop-virtual-machine-manager.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-hypervisor.cfg
%include ../ingredients/None.cfg
+22
View File
@@ -0,0 +1,22 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a generic desktop hypervisor
%include ../ingredients/core.cfg # Text mode
%include ../ingredients/core-storage.cfg # ext4-based storage configuration
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-on.cfg # Lock root account, enable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-packages-hardware-support.cfg # Extended hardware support
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/core-post.cfg # Triggered after the installation
%include ../ingredients/core-initial-setup-gnome-desktop.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/base-desktop-gnome.cfg # A GNOME Shell-based desktop environment
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a live desktop hypervisor
%include ../ingredients/live-core.cfg # For live systems only
%include ../ingredients/live-core-storage.cfg # For live systems only
%include ../ingredients/live-core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-on.cfg # Lock root account, enable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-packages-hardware-support.cfg # Extended hardware support
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/core-post.cfg # Triggered after the installation
%include ../ingredients/live-core-post.cfg # Post configuration script for a live system only
%include ../ingredients/live-core-post-live-session.cfg # Live session script
%include ../ingredients/core-initial-setup-gnome-desktop.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/base-desktop-gnome.cfg # A GNOME Shell-based desktop environment
%include ../ingredients/base-desktop-virtual-machine-manager.cfg # Virtual Machine Manager
%include ../ingredients/base-hypervisor.cfg # Base hypervisor
+22
View File
@@ -0,0 +1,22 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a live desktop
%include ../ingredients/live-core-storage.cfg
%include ../ingredients/live-core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/live-core-mandatory-packages.cfg
%include ../ingredients/live-core-post.cfg
%include ../ingredients/live-core-post-live-session.cfg
%include ../ingredients/core-initial-setup-gnome-desktop.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a live server hypervisor
%include ../ingredients/live-core.cfg # For live systems only
%include ../ingredients/live-core-storage.cfg # For live systems only
%include ../ingredients/live-core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-on.cfg # Lock root account, enable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/live-core-mandatory-packages.cfg # For live systems
%include ../ingredients/core-packages-hardware-support.cfg # Extended hardware support
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/core-post.cfg # Triggered after the installation
%include ../ingredients/live-core-post.cfg # Post configuration script for a live system only
%include ../ingredients/live-core-post-live-session.cfg # Live session script
%include ../ingredients/core-initial-setup-server.cfg # For headless systems
%include ../ingredients/base-hypervisor.cfg # Base hyperviso
@@ -0,0 +1,21 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a live server
%include ../ingredients/live-core-storage.cfg
%include ../ingredients/live-core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/live-core-mandatory-packages.cfg
%include ../ingredients/live-core-post.cfg
%include ../ingredients/live-core-post-live-session.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
+21
View File
@@ -0,0 +1,21 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a live server
%include ../ingredients/live-core-storage.cfg
%include ../ingredients/live-core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/live-core-mandatory-packages.cfg
%include ../ingredients/live-core-post.cfg
%include ../ingredients/live-core-post-live-session.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
@@ -0,0 +1,21 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a live server
%include ../ingredients/live-core-storage.cfg
%include ../ingredients/live-core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/live-core-mandatory-packages.cfg
%include ../ingredients/live-core-post.cfg
%include ../ingredients/live-core-post-live-session.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-fedora-repo-rawhide.cfg
%include ../ingredients/core-security-on.cfg
+19
View File
@@ -0,0 +1,19 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual desktop
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-guest-agents.cfg
@@ -0,0 +1,19 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual desktop
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-off.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-guest-agents.cfg
@@ -0,0 +1,21 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Unsafe. Development-only. A recipe for a virtual desktop
%include ../ingredients/core.cfg # Text mode
%include ../ingredients/core-storage.cfg # ext4-based storage configuration
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-off.cfg # Enable root account, disable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/base-desktop-gnome.cfg # A GNOME Shell-based desktop environment
%include ../ingredients/core-initial-setup-server.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/base-guest-agents.cfg # Guest agents
@@ -0,0 +1,19 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual desktop
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-desktop-labwc.cfg
%include ../ingredients/base-guest-agents.cfg
@@ -0,0 +1,22 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual desktop with an encrypted root partition
%include ../ingredients/core.cfg # Text mode
%include ../ingredients/core-storage-encrypted.cfg # ext4-based storage configuration with encryption
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-on.cfg # Lock root account, enable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/core-post.cfg # Triggered after the installation
%include ../ingredients/base-desktop-gnome.cfg # A GNOME Shell-based desktop environment
%include ../ingredients/core-initial-setup-server.cfg # Enable initial setup to allow end users to create user on first boot
%include ../ingredients/base-guest-agents.cfg # Guest agents
@@ -0,0 +1,19 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual desktop
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-guest-agents.cfg
@@ -0,0 +1,19 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual desktop
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-desktop-gnome.cfg
%include ../ingredients/base-guest-agents.cfg
+18
View File
@@ -0,0 +1,18 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual server
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-guest-agents.cfg
@@ -0,0 +1,18 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual server
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-off.cfg
%include ../ingredients/base-guest-agents.cfg
@@ -0,0 +1,19 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# # Unsafe. Development-only. A recipe for a virtual server
%include ../ingredients/core.cfg # Text mode
%include ../ingredients/core-storage.cfg # ext4-based storage configuration
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-off.cfg # Enable root account, disable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-fedora-repo-43.cfg # Official repositories for Fedora 43
%include ../ingredients/base-guest-agents.cfg # Guest agents
@@ -0,0 +1,19 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# # Unsafe. Development-only. A recipe for a virtual server
%include ../ingredients/core.cfg # Text mode
%include ../ingredients/core-storage.cfg # ext4-based storage configuration
%include ../ingredients/core-bootloader-grub.cfg # Set bootloader to GRUB
%include ../ingredients/core-locale.cfg # System locale set to Swiss French as keyboard layout and English as language
%include ../ingredients/core-security-off.cfg # Enable root account, disable firewall and SELinux
%include ../ingredients/core-services.cfg # Required systemd services
%include ../ingredients/core-network.cfg # Network configuration
%include ../ingredients/core-packages.cfg # Mandatory packages
%include ../ingredients/core-fedora-repo-rawhide.cfg # Official repositories for Fedora Rawhide
%include ../ingredients/base-guest-agents.cfg # Guest agents
+18
View File
@@ -0,0 +1,18 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual server
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-on.cfg
%include ../ingredients/base-guest-agents.cfg
@@ -0,0 +1,18 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a virtual server
%include ../ingredients/core-storage.cfg
%include ../ingredients/core-bootloader-grub.cfg
%include ../ingredients/core-locale.cfg
%include ../ingredients/core-services.cfg
%include ../ingredients/core-network.cfg
%include ../ingredients/core-packages.cfg
%include ../ingredients/core-initial-setup-server.cfg
%include ../ingredients/core-security-off.cfg
%include ../ingredients/base-guest-agents.cfg
+12 -3
View File
@@ -1,4 +1,4 @@
.PHONY: help generate-recipes validate-recipes test clean install-deps
.PHONY: help generate-recipes validate-recipes test test-integration test-container clean install-deps
help:
@echo "Phyllome OS Recipe Generator"
@@ -6,7 +6,9 @@ help:
@echo "Available targets:"
@echo " generate-recipes - Generate all recipes from manifest"
@echo " validate-recipes - Validate existing recipes"
@echo " test - Run pytest test suite"
@echo " test - Run pytest test suite (unit + integration)"
@echo " test-integration - Run integration tests only"
@echo " test-container - Run all tests in container"
@echo " clean - Remove generated recipes"
@echo " install-deps - Install Python dependencies"
@@ -23,7 +25,14 @@ validate-recipes:
--validate ../recipes/*.cfg
test:
pytest ../tests/test_recipe_generator.py -v
python3 -m pytest tests/ -v --tb=short
test-integration:
python3 -m pytest tests/integration/ -v --tb=short
test-container:
podman build -t phyllo/test-runner tests/container/
podman run --rm -v .:/phyllomeos:ro phyllo/test-runner
clean:
rm -f ../recipes/*.cfg
Binary file not shown.
+62 -42
View File
@@ -102,7 +102,7 @@ class RecipeGenerator:
sys.exit(2)
def validate_template(self, template: Dict) -> List[str]:
"""Validate template structure and ingredient existence."""
"""Validate template structure and fragment existence."""
errors = []
# Check required keys
@@ -111,34 +111,50 @@ class RecipeGenerator:
if key not in template:
errors.append(f"Missing required key: {key}")
# Validate base ingredient exists
# Validate base ingredient exists (for compatibility with old ingredients)
if 'base' in template:
base_path = self.ingredients_dir / f"{template['base']}.cfg"
if not base_path.exists():
errors.append(f"Base ingredient not found: {template['base']}.cfg")
# Validate required ingredients exist
# Validate required fragments exist
for item in template.get('required', []):
if isinstance(item, dict):
inc_name = list(item.values())[0]
fragment_path = list(item.values())[0]
else:
inc_name = item
inc_path = self.ingredients_dir / f"{inc_name}.cfg"
if not inc_path.exists():
errors.append(f"Required ingredient not found: {inc_name}.cfg")
continue
# Handle both absolute fragment paths and old ingredient names
if fragment_path.startswith('fragments/'):
full_path = self.project_root / fragment_path
else:
full_path = self.ingredients_dir / f"{fragment_path}.cfg"
if not full_path.exists():
errors.append(f"Required fragment not found: {fragment_path}")
# Validate optional ingredient values
# Validate optional fragment values
for opt_key, opt_config in template.get('optional', {}).items():
if isinstance(opt_config, dict):
for value, inc_name in opt_config.items():
inc_path = self.ingredients_dir / f"{inc_name}.cfg"
if not inc_path.exists():
errors.append(f"Optional ingredient not found: {inc_name}.cfg (for {opt_key}={value})")
for value, fragment_path in opt_config.items():
if fragment_path.startswith('fragments/'):
full_path = self.project_root / fragment_path
elif fragment_path is None:
continue
else:
full_path = self.ingredients_dir / f"{fragment_path}.cfg"
if not full_path.exists():
errors.append(f"Optional fragment not found: {fragment_path} (for {opt_key}={value})")
elif isinstance(opt_config, list):
for inc_name in opt_config:
inc_path = self.ingredients_dir / f"{inc_name}.cfg"
if not inc_path.exists():
errors.append(f"Optional ingredient not found: {inc_name}.cfg (in list)")
for fragment_path in opt_config:
if fragment_path.startswith('fragments/'):
full_path = self.project_root / fragment_path
else:
full_path = self.ingredients_dir / f"{fragment_path}.cfg"
if not full_path.exists():
errors.append(f"Optional fragment not found: {fragment_path} (in list)")
return errors
@@ -201,7 +217,7 @@ class RecipeGenerator:
return header
def build_includes(self, template: Dict, version: str, modifiers: Dict) -> List[str]:
"""Build %include lines from template and modifiers."""
"""Build %ksappend lines from template and modifiers."""
includes = []
seen = set() # Track to prevent duplicates
# Add version to modifiers for template processing
@@ -211,14 +227,13 @@ class RecipeGenerator:
# Add required includes
for item in template.get('required', []):
if isinstance(item, dict):
inc_name = list(item.values())[0]
fragment_path = list(item.values())[0]
else:
inc_name = item
continue
inc_file = f"{inc_name}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
if fragment_path not in seen:
includes.append(f"%ksappend {fragment_path}")
seen.add(fragment_path)
# Add optional includes based on modifiers
for opt_key, opt_config in template.get('optional', {}).items():
@@ -226,33 +241,32 @@ class RecipeGenerator:
value = modifiers[opt_key]
if isinstance(opt_config, dict):
if value in opt_config:
inc_file = f"{opt_config[value]}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
fragment_path = opt_config[value]
if fragment_path not in seen:
includes.append(f"%ksappend {fragment_path}")
seen.add(fragment_path)
elif isinstance(opt_config, list) and value is True:
for item in opt_config:
inc_file = f"{item}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
for fragment_path in opt_config:
if fragment_path not in seen:
includes.append(f"%ksappend {fragment_path}")
seen.add(fragment_path)
# Handle special modifiers (CPU, GPU)
for mod_key, mod_value in modifiers.items():
if mod_key in template.get('modifiers', {}):
mod_config = template['modifiers'][mod_key]
if isinstance(mod_config, dict) and mod_value in mod_config:
inc_file = f"{mod_config[mod_value]}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
fragment_path = mod_config[mod_value]
if fragment_path and fragment_path not in seen:
includes.append(f"%ksappend {fragment_path}")
seen.add(fragment_path)
return includes
def validate_recipe(self, content: str) -> List[str]:
"""Validate recipe content, return list of warnings/errors."""
issues = []
includes = [line for line in content.split('\n') if line.startswith('%include')]
includes = [line for line in content.split('\n') if line.startswith('%ksappend')]
# Check for duplicate includes
seen = set()
@@ -265,15 +279,15 @@ class RecipeGenerator:
issues.append(f"Duplicate include: {path}")
seen.add(path)
# Check ingredient existence
# Check fragment existence (relative to project root)
for inc in includes:
parts = inc.split()
if len(parts) < 2:
continue
path = parts[1]
inc_path = self.ingredients_dir / path
if not inc_path.exists():
issues.append(f"Missing ingredient: {path}")
fragment_path = self.project_root / path
if not fragment_path.exists():
issues.append(f"Missing fragment: {path}")
return issues
@@ -352,10 +366,16 @@ class RecipeGenerator:
return filename_match.group(1)
for line in content.split('\n'):
# Check for old %include references
if 'core-fedora-repo-43' in line:
return '43'
elif 'core-fedora-repo-rawhide' in line:
return 'rawhide'
# Check for new %ksappend references
if 'generic-43/repo' in line:
return '43'
elif 'generic-rawhide/repo' in line:
return 'rawhide'
return None
+626
View File
@@ -0,0 +1,626 @@
#!/usr/bin/env python3
"""
Recipe Generator for Phyllome OS Kickstart Files
Generates .cfg recipe files from templates and YAML manifest.
"""
import argparse
import sys
import yaml
from pathlib import Path
from typing import Dict, List, Optional, Any
# Deprecated/removed command mappings for Fedora 43 (F42) and rawhide
DEPRECATED_COMMANDS: Dict[str, Dict[str, str]] = {
'authconfig': {
'status': 'removed',
'removed_in': 'F34',
'alternative': 'authselect',
'message': 'authconfig was removed in Fedora 34. Use authselect instead.'
},
'keyboard': {
'status': 'deprecated',
'deprecated_in': 'F18',
'alternative': 'keyboard --vckeymap',
'message': 'keyboard command is deprecated. Use keyboard --vckeymap instead.'
},
'langsupport': {
'status': 'deprecated',
'deprecated_in': 'F21',
'alternative': 'lang',
'message': 'langsupport is deprecated. Use lang command instead.'
},
'nfs': {
'status': 'deprecated',
'deprecated_in': 'F23',
'alternative': 'repo --name=nfs',
'message': 'nfs command is deprecated. Use repo command instead.'
},
'parted': {
'status': 'deprecated',
'deprecated_in': 'F13',
'alternative': 'part',
'message': 'parted command is deprecated. Use part command instead.'
},
}
def _import_pykickstart():
"""Import pykickstart modules, returns None if not available."""
try:
from pykickstart.parser import KickstartParser
from pykickstart.version import makeVersion
from pykickstart.version import DEVEL
from pykickstart.errors import KickstartParseError, KickstartError
return {
'parser': KickstartParser,
'makeVersion': makeVersion,
'DEVEL': DEVEL,
'KickstartParseError': KickstartParseError,
'KickstartError': KickstartError
}
except ImportError:
return None
class RecipeGenerator:
"""Generate kickstart recipes from templates and modifiers."""
def __init__(self, ingredients_dir: Path, templates_file: Path):
# Resolve ingredients_dir relative to the project root (parent of scripts/)
self.project_root = Path(__file__).parent.parent
self.ingredients_dir = self.project_root / ingredients_dir
self.templates = self.load_templates(templates_file)
def get_ksversion(self, version: str) -> Optional[str]:
"""Map Phyllome OS version to pykickstart version string."""
if version == 'rawhide':
return None
else:
return f'F{int(version) - 1}'
def load_templates(self, path: Path) -> Dict:
"""Load recipe templates from YAML file."""
try:
# Template path could be:
# - Absolute path (already resolved)
# - Relative path (resolve relative to project root)
if path.is_absolute():
template_path = path
else:
template_path = self.project_root / 'scripts' / path
with open(template_path) as f:
data = yaml.safe_load(f)
return data['templates']
except FileNotFoundError:
print(f"Error: Templates file not found: {template_path}", file=sys.stderr)
sys.exit(2)
except yaml.YAMLError as e:
print(f"Error: Invalid YAML in {template_path}: {e}", file=sys.stderr)
sys.exit(2)
def validate_template(self, template: Dict) -> List[str]:
"""Validate template structure and ingredient existence."""
errors = []
# Check required keys
required_keys = ['description', 'base', 'required']
for key in required_keys:
if key not in template:
errors.append(f"Missing required key: {key}")
# Validate base ingredient exists
if 'base' in template:
base_path = self.ingredients_dir / f"{template['base']}.cfg"
if not base_path.exists():
errors.append(f"Base ingredient not found: {template['base']}.cfg")
# Validate required ingredients exist
for item in template.get('required', []):
if isinstance(item, dict):
inc_name = list(item.values())[0]
else:
inc_name = item
inc_path = self.ingredients_dir / f"{inc_name}.cfg"
if not inc_path.exists():
errors.append(f"Required ingredient not found: {inc_name}.cfg")
# Validate optional ingredient values
for opt_key, opt_config in template.get('optional', {}).items():
if isinstance(opt_config, dict):
for value, inc_name in opt_config.items():
inc_path = self.ingredients_dir / f"{inc_name}.cfg"
if not inc_path.exists():
errors.append(f"Optional ingredient not found: {inc_name}.cfg (for {opt_key}={value})")
elif isinstance(opt_config, list):
for inc_name in opt_config:
inc_path = self.ingredients_dir / f"{inc_name}.cfg"
if not inc_path.exists():
errors.append(f"Optional ingredient not found: {inc_name}.cfg (in list)")
return errors
def validate_manifest(self, manifest: Dict) -> List[str]:
"""Validate manifest structure."""
errors = []
if 'recipes' not in manifest:
errors.append("Manifest missing 'recipes' key")
return errors
for recipe_config in manifest['recipes']:
if 'name' not in recipe_config:
errors.append("Recipe config missing 'name' key")
if 'variants' not in recipe_config:
errors.append(f"Recipe '{recipe_config.get('name', 'unnamed')}' missing 'variants' key")
continue
for variant in recipe_config['variants']:
if 'version' not in variant:
errors.append(f"Recipe '{recipe_config['name']}' variant missing 'version'")
return errors
def generate_recipe(self, recipe_type: str, version: str, **modifiers) -> str:
"""Generate a recipe from template with modifiers."""
if recipe_type not in self.templates:
print(f"Error: Unknown recipe type: {recipe_type}", file=sys.stderr)
sys.exit(1)
template = self.templates[recipe_type]
# Validate template
errors = self.validate_template(template)
if errors:
print(f"Error: Invalid template '{recipe_type}':", file=sys.stderr)
for error in errors:
print(f" - {error}", file=sys.stderr)
sys.exit(1)
lines = self.build_header(template['description'], recipe_type, version, modifiers)
lines.extend(self.build_includes(template, version, modifiers))
return '\n'.join(lines)
def build_header(self, description: str, recipe_type: str,
version: str, modifiers: Dict) -> List[str]:
"""Build the ASCII art header and description."""
header = [
"# __ ____ ____ _____",
"# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \\/ ___/",
"# / __ \\/ __ \\/ / / / / / __ \\/ __ `__ \\/ _ \\ / / / /\\__ \\",
"# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /",
"# / .___/_/ /_/\\__, /_/_/\\____/_/ /_/ /_/\\___/ \\____//____/",
"# /_/ /____/",
"",
f"# {description}",
"",
]
return header
def build_includes(self, template: Dict, version: str, modifiers: Dict) -> List[str]:
"""Build %include lines from template and modifiers."""
includes = []
seen = set() # Track to prevent duplicates
# Add version to modifiers for template processing
modifiers = modifiers.copy()
modifiers['version'] = version
# Add required includes
for item in template.get('required', []):
if isinstance(item, dict):
inc_name = list(item.values())[0]
else:
inc_name = item
inc_file = f"{inc_name}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
# Add optional includes based on modifiers
for opt_key, opt_config in template.get('optional', {}).items():
if opt_key in modifiers:
value = modifiers[opt_key]
if isinstance(opt_config, dict):
if value in opt_config:
inc_file = f"{opt_config[value]}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
elif isinstance(opt_config, list) and value is True:
for item in opt_config:
inc_file = f"{item}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
# Handle special modifiers (CPU, GPU)
for mod_key, mod_value in modifiers.items():
if mod_key in template.get('modifiers', {}):
mod_config = template['modifiers'][mod_key]
if isinstance(mod_config, dict) and mod_value in mod_config:
inc_file = f"{mod_config[mod_value]}.cfg"
if inc_file not in seen:
includes.append(f"%include ../ingredients/{inc_file}")
seen.add(inc_file)
return includes
def validate_recipe(self, content: str) -> List[str]:
"""Validate recipe content, return list of warnings/errors."""
issues = []
includes = [line for line in content.split('\n') if line.startswith('%include')]
# Check for duplicate includes
seen = set()
for inc in includes:
parts = inc.split()
if len(parts) < 2:
continue
path = parts[1]
if path in seen:
issues.append(f"Duplicate include: {path}")
seen.add(path)
# Check ingredient existence
for inc in includes:
parts = inc.split()
if len(parts) < 2:
continue
path = parts[1]
inc_path = self.ingredients_dir / path
if not inc_path.exists():
issues.append(f"Missing ingredient: {path}")
return issues
def validate_recipe_semantic(self, content: str, version: str) -> List[str]:
"""Validate recipe using pykickstart parser with version-specific checks."""
issues = []
modules = _import_pykickstart()
if modules is None:
issues.append("Warning: pykickstart not installed, skipping semantic validation")
return issues
KickstartParser = modules['parser']
makeVersion = modules['makeVersion']
KickstartParseError = modules['KickstartParseError']
KickstartError = modules['KickstartError']
ks_version_str = self.get_ksversion(version)
if ks_version_str:
ks_version = makeVersion(ks_version_str)
else:
ks_version = makeVersion(modules['DEVEL'])
try:
parser = KickstartParser(ks_version)
parser.readKickstartFromString(content)
except KickstartParseError as e:
issues.append(f"Syntax error line {e.lineno}: {e.message}")
except KickstartError as e:
issues.append(f"Validation error: {str(e)}")
except Exception as e:
issues.append(f"Unexpected error during parsing: {str(e)}")
# Check for deprecated commands in the content
issues.extend(self._check_deprecated_commands(content))
return issues
def _check_deprecated_commands(self, content: str) -> List[str]:
"""Check for deprecated and removed commands with suggestions."""
issues = []
for line_num, line in enumerate(content.split('\n'), start=1):
# Skip comments and empty lines
stripped = line.strip()
if not stripped or stripped.startswith('#'):
continue
# Extract command (first word after % if in section, or just the first word)
if stripped.startswith('%'):
continue # Skip section headers
parts = stripped.split()
if not parts:
continue
cmd = parts[0]
if cmd in DEPRECATED_COMMANDS:
cmd_info = DEPRECATED_COMMANDS[cmd]
status = cmd_info['status']
msg = cmd_info['message']
if status == 'removed':
issues.append(f"ERROR: Line {line_num}: {msg}")
else:
issues.append(f"Warning: Line {line_num}: {msg}")
return issues
def extract_version(self, content: str, filename: str) -> Optional[str]:
"""Extract Fedora version from recipe content or filename."""
import re
filename_match = re.search(r'(?:_|-)(43|rawhide)(?:_|-|.cfg|.yaml|$)', filename)
if filename_match:
return filename_match.group(1)
for line in content.split('\n'):
if 'core-fedora-repo-43' in line:
return '43'
elif 'core-fedora-repo-rawhide' in line:
return 'rawhide'
return None
def generate_filename(self, recipe_type: str, version: str, **modifiers) -> str:
"""Generate recipe filename from parameters."""
# Map modifiers to filename components
parts = [recipe_type.replace('_', '-')]
# Add CPU/GPU first (hypervisors)
if modifiers.get('cpu') and modifiers.get('cpu') != 'generic':
parts.append(modifiers['cpu'])
if modifiers.get('gpu') and modifiers.get('gpu') != 'none':
parts.append(modifiers['gpu'])
# Add desktop (non-GNOME only, since GNOME is default)
if modifiers.get('desktop') and modifiers['desktop'] != 'gnome':
parts.append(modifiers['desktop'])
# Add version
parts.append(str(version))
# Add hypervisor suffix (only when hypervisor is enabled)
if modifiers.get('hypervisor'):
parts.append('hypervisor')
# Add security suffix (devel only, since secure is default)
if modifiers.get('security') == 'devel':
parts.append('devel')
# Add storage suffix (encrypted only, since standard is default)
if modifiers.get('storage') == 'encrypted':
parts.append('encrypted')
return '_'.join(parts) + '.cfg'
def main():
parser = argparse.ArgumentParser(
description='Generate Phyllome OS kickstart recipes from templates',
formatter_class=argparse.RawDescriptionHelpFormatter
)
# Global options
# Use __file__ to find the scripts directory, then go up to project root
SCRIPTS_DIR = Path(__file__).resolve().parent
PROJECT_ROOT = SCRIPTS_DIR.parent
parser.add_argument('--ingredients', '-i',
type=Path, default=PROJECT_ROOT / 'ingredients',
help='Ingredients directory (default: parent/ingredients)')
parser.add_argument('--templates', '-t',
type=Path, default=SCRIPTS_DIR / 'recipe_templates.yaml',
help='Templates YAML file (default: parent/recipe_templates.yaml)')
# Batch mode
parser.add_argument('--manifest', '-m',
type=Path, help='Manifest YAML for batch generation')
parser.add_argument('--output-dir', '-d',
type=Path, default=Path(__file__).parent / 'recipes',
help='Output directory (batch generation, default: parent/recipes)')
parser.add_argument('--dry-run', '-n',
action='store_true',
help='Show what would be generated without writing files')
# Single generation mode
parser.add_argument('--type', '-T',
help='Recipe type (e.g., virtual-desktop)')
parser.add_argument('--output', '-o',
type=Path, help='Output file (single generation)')
# Recipe parameters
parser.add_argument('--version', '-v',
choices=['43', 'rawhide'], default='rawhide',
help='Fedora version (default: rawhide)')
parser.add_argument('--desktop',
choices=['gnome', 'labwc'],
help='Desktop environment (default: gnome)')
parser.add_argument('--storage',
choices=['standard', 'encrypted'],
help='Storage type (default: standard)')
parser.add_argument('--security',
choices=['secure', 'devel'],
help='Security mode (default: secure)')
parser.add_argument('--cpu',
choices=['generic', 'amdcpu', 'intelcpu'],
help='CPU optimization')
parser.add_argument('--gpu',
choices=['none', 'intelgpu'],
default='none',
help='GPU passthrough (default: none)')
# Validation mode
parser.add_argument('--validate', '-V',
nargs='+',
help='Validate recipe files')
# Strict mode for CI
parser.add_argument('--strict',
action='store_true',
help='Treat warnings as errors (CI mode)')
args = parser.parse_args()
# Initialize generator
generator = RecipeGenerator(args.ingredients, args.templates)
# Validation mode
if args.validate:
all_issues = []
for recipe_path in args.validate:
try:
with open(recipe_path) as f:
content = f.read()
issues = generator.validate_recipe(content)
# Extract version and perform semantic validation
filename = Path(recipe_path).stem
version = generator.extract_version(content, filename)
if version:
semantic_issues = generator.validate_recipe_semantic(content, version)
issues.extend(semantic_issues)
else:
issues.append("Warning: Could not determine version, skipping semantic validation")
if issues:
all_issues.append((recipe_path, issues))
except FileNotFoundError:
print(f"Error: Recipe not found: {recipe_path}", file=sys.stderr)
sys.exit(2)
if all_issues:
print("=== Recipe Validation Report ===", file=sys.stderr)
for path, issues in all_issues:
print(f"\n{path}:", file=sys.stderr)
error_count = sum(1 for i in issues if 'ERROR' in i)
warning_count = sum(1 for i in issues if 'Warning:' in i)
if error_count > 0:
for issue in issues:
if 'ERROR' in issue:
print(f" {issue}", file=sys.stderr)
if warning_count > 0:
for issue in issues:
if 'Warning:' in issue:
print(f" {issue}", file=sys.stderr)
if error_count == 0 and warning_count == 0:
print(f" No issues found (file exists)", file=sys.stderr)
print(f"\nSummary:", file=sys.stderr)
print(f" - {len(all_issues)} recipe(s) checked", file=sys.stderr)
total_errors = sum(len([i for i in issues if 'ERROR' in i]) for _, issues in all_issues)
total_warnings = sum(len([i for i in issues if 'Warning:' in i]) for _, issues in all_issues)
print(f" - {total_errors} error(s), {total_warnings} warning(s)", file=sys.stderr)
# Strict mode: treat warnings as errors
if args.strict and total_warnings > 0:
print("\nStrict mode: Warnings treated as errors", file=sys.stderr)
sys.exit(1)
if total_errors > 0:
sys.exit(1)
else:
print("All recipes validated successfully")
sys.exit(0)
# Batch generation mode
if args.manifest:
try:
with open(args.manifest) as f:
manifest = yaml.safe_load(f)
except FileNotFoundError:
print(f"Error: Manifest file not found: {args.manifest}", file=sys.stderr)
sys.exit(2)
except yaml.YAMLError as e:
print(f"Error: Invalid YAML in manifest: {e}", file=sys.stderr)
sys.exit(2)
# Validate manifest
errors = generator.validate_manifest(manifest)
if errors:
print(f"Error: Invalid manifest:", file=sys.stderr)
for error in errors:
print(f" - {error}", file=sys.stderr)
sys.exit(1)
# Generate all recipes
for recipe_config in manifest.get('recipes', []):
recipe_type = recipe_config['name']
if recipe_type not in generator.templates:
print(f"Error: Unknown recipe type in manifest: {recipe_type}", file=sys.stderr)
sys.exit(1)
for variant in recipe_config.get('variants', []):
version = variant['version']
modifiers = {k: v for k, v in variant.items() if k not in ['version']}
content = generator.generate_recipe(recipe_type, version, **modifiers)
if args.validate and not args.dry_run:
issues = generator.validate_recipe(content)
semantic_issues = generator.validate_recipe_semantic(content, version)
all_issues = issues + semantic_issues
if all_issues:
print(f"Validation issues for {recipe_type} {version}:", file=sys.stderr)
for issue in issues:
print(f" - {issue}", file=sys.stderr)
sys.exit(1)
filename = generator.generate_filename(recipe_type, version, **modifiers)
output_path = args.output_dir / filename
if args.dry_run:
print(f"Would generate: {output_path}")
else:
print(f"Generating: {output_path}")
with open(output_path, 'w') as f:
f.write(content)
sys.exit(0)
# Single generation mode
if args.type:
modifiers = {
'desktop': args.desktop if args.desktop and args.desktop != 'gnome' else None,
'storage': args.storage if args.storage != 'standard' else None,
'security': args.security if args.security != 'secure' else None,
'cpu': args.cpu if args.cpu and args.cpu != 'generic' else None,
'gpu': args.gpu if args.gpu and args.gpu != 'none' else None,
}
# Filter out None/False values
modifiers = {k: v for k, v in modifiers.items() if v is not None}
content = generator.generate_recipe(args.type, args.version, **modifiers)
if args.validate:
issues = generator.validate_recipe(content)
semantic_issues = generator.validate_recipe_semantic(content, args.version)
all_issues = issues + semantic_issues
if all_issues:
print("Validation issues:", file=sys.stderr)
for issue in issues:
print(f" - {issue}", file=sys.stderr)
sys.exit(1)
else:
print("Validation passed")
if args.output:
if args.dry_run:
print(f"Would write to: {args.output}")
else:
with open(args.output, 'w') as f:
f.write(content)
print(f"Generated: {args.output}")
else:
print(content)
sys.exit(0)
# No mode specified, show help
parser.print_help()
sys.exit(1)
if __name__ == '__main__':
main()
+115 -95
View File
@@ -1,6 +1,7 @@
# Recipe Templates for Phyllome OS Kickstart Generator
# Each template defines the structure for a recipe type
# Modifiers allow variant creation without duplicating files
# Fragment paths use relative paths from project root
templates:
# Virtual desktop recipe
@@ -10,31 +11,35 @@ templates:
description: "A recipe for a virtual desktop"
base: core
required:
- core
- storage: core-storage
- bootloader: core-bootloader-grub
- locale: core-locale
- services: core-services
- network: core-network
- packages: core-packages
- initial-setup: core-initial-setup-server
- core: fragments/shared/core/base.ks
- storage: fragments/shared/storage/standard.ks
- bootloader: fragments/platform/generic-43/bootloader/grub.ks
- locale: fragments/shared/core/locale.ks
- services: fragments/shared/core/services.ks
- network: fragments/shared/core/network.ks
- packages: fragments/shared/packages/core-group.ks
- fedora-remix: fragments/shared/packages/fedora-remix.ks
- hand-picked: fragments/shared/packages/hand-picked.ks
- initial-setup: fragments/shared/initial-setup/server/config.ks
optional:
security:
secure: core-security-on
devel: core-security-off
secure: fragments/shared/core/security/enabled.ks
devel: fragments/shared/core/security/disabled.ks
version:
"43": core-fedora-repo-43
"rawhide": core-fedora-repo-rawhide
"43": fragments/platform/generic-43/repo/fedora-mirrors.ks
"rawhide": fragments/platform/generic-rawhide/repo/rawhide-mirrors.ks
desktop:
gnome: base-desktop-gnome
labwc: base-desktop-labwc
post: core-post
gnome: fragments/shared/desktop/gnome/packages.ks
labwc: fragments/shared/desktop/labwc/config.ks
post: fragments/shared/section-data/post/base.ks
extras:
- base-guest-agents
- fragments/shared/guest-agents/packages.ks
modifiers:
storage:
standard: core-storage
encrypted: core-storage-encrypted
standard: fragments/shared/storage/standard.ks
encrypted: fragments/shared/storage/encrypted.ks
bootloader:
systemd-boot: fragments/platform/generic-43/bootloader/systemd-boot.ks
# Virtual server recipe
# Modifiers: security (secure|devel), version (43|rawhide), post (true|false)
@@ -42,28 +47,32 @@ templates:
description: "A recipe for a virtual server"
base: core
required:
- core
- storage: core-storage
- bootloader: core-bootloader-grub
- locale: core-locale
- services: core-services
- network: core-network
- packages: core-packages
- initial-setup: core-initial-setup-server
- core: fragments/shared/core/base.ks
- storage: fragments/shared/storage/standard.ks
- bootloader: fragments/platform/generic-43/bootloader/grub.ks
- locale: fragments/shared/core/locale.ks
- services: fragments/shared/core/services.ks
- network: fragments/shared/core/network.ks
- packages: fragments/shared/packages/core-group.ks
- fedora-remix: fragments/shared/packages/fedora-remix.ks
- hand-picked: fragments/shared/packages/hand-picked.ks
- initial-setup: fragments/shared/initial-setup/server/config.ks
optional:
security:
secure: core-security-on
devel: core-security-off
secure: fragments/shared/core/security/enabled.ks
devel: fragments/shared/core/security/disabled.ks
version:
"43": core-fedora-repo-43
"rawhide": core-fedora-repo-rawhide
post: core-post
"43": fragments/platform/generic-43/repo/fedora-mirrors.ks
"rawhide": fragments/platform/generic-rawhide/repo/rawhide-mirrors.ks
post: fragments/shared/section-data/post/base.ks
extras:
- base-guest-agents
- fragments/shared/guest-agents/packages.ks
modifiers:
storage:
standard: core-storage
encrypted: core-storage-encrypted
standard: fragments/shared/storage/standard.ks
encrypted: fragments/shared/storage/encrypted.ks
bootloader:
systemd-boot: fragments/platform/generic-43/bootloader/systemd-boot.ks
# Desktop hypervisor recipe
# Modifiers: cpu (generic|amdcpu|intelcpu), gpu (none|intelgpu),
@@ -72,40 +81,48 @@ templates:
description: "A recipe for a desktop hypervisor"
base: core
required:
- core
- storage: core-storage
- bootloader: core-bootloader-grub
- locale: core-locale
- services: core-services
- network: core-network
- packages: core-packages
- packages-hw: core-packages-hardware-support
- initial-setup: core-initial-setup-gnome-desktop
- desktop: base-desktop-gnome
- vmm: base-desktop-virtual-machine-manager
- repo: core-fedora-repo-rawhide
- core: fragments/shared/core/base.ks
- storage: fragments/shared/storage/standard.ks
- bootloader: fragments/platform/generic-rawhide/bootloader/grub.ks
- locale: fragments/shared/core/locale.ks
- services: fragments/shared/core/services.ks
- network: fragments/shared/core/network.ks
- packages: fragments/shared/packages/core-group.ks
- fedora-remix: fragments/shared/packages/fedora-remix.ks
- hand-picked: fragments/shared/packages/hand-picked.ks
- hardware-support: fragments/shared/packages/hardware-support.ks
- initial-setup: fragments/shared/initial-setup/desktop/config.ks
- desktop: fragments/shared/desktop/gnome/config.ks
- desktop-gnome-packages: fragments/shared/desktop/gnome/packages.ks
- desktop-gnome-post: fragments/shared/desktop/gnome/post-scripts.ks
- vmm: fragments/shared/desktop/vmm/packages.ks
- vmm-post: fragments/shared/desktop/vmm/post-scripts.ks
- repo: fragments/platform/generic-rawhide/repo/rawhide-mirrors.ks
- hypervisor-base-services: fragments/shared/hypervisor/base/services.ks
- hypervisor-base-packages: fragments/shared/hypervisor/base/packages.ks
- hypervisor-base-post: fragments/shared/hypervisor/base/post-scripts.ks
optional:
security:
secure: core-security-on
devel: core-security-off
secure: fragments/shared/core/security/enabled.ks
devel: fragments/shared/core/security/disabled.ks
cpu:
generic: base-hypervisor
amdcpu: base-hypervisor-amdcpu
intelcpu: base-hypervisor-intelcpu
generic: fragments/shared/hypervisor/base/services.ks
amdcpu: fragments/shared/hypervisor/amdcpu.ks
intelcpu: fragments/shared/hypervisor/intelcpu.ks
gpu:
intelgpu: base-hypervisor-intelgpu
post: core-post
intelgpu: fragments/shared/hypervisor/intelgpu.ks
post: fragments/shared/section-data/post/base.ks
modifiers:
cpu:
generic: base-hypervisor
amdcpu: base-hypervisor-amdcpu
intelcpu: base-hypervisor-intelcpu
generic: fragments/shared/hypervisor/base/services.ks
amdcpu: fragments/shared/hypervisor/amdcpu.ks
intelcpu: fragments/shared/hypervisor/intelcpu.ks
gpu:
none: null
intelgpu: base-hypervisor-intelgpu
intelgpu: fragments/shared/hypervisor/intelgpu.ks
storage:
standard: core-storage
encrypted: core-storage-encrypted
standard: fragments/shared/storage/standard.ks
encrypted: fragments/shared/storage/encrypted.ks
# Live desktop recipe
# Modifiers: desktop (gnome|none), security (secure|devel), version (rawhide)
@@ -113,28 +130,31 @@ templates:
description: "A recipe for a live desktop"
base: live-core
required:
- live-core
- storage: live-core-storage
- bootloader: live-core-bootloader-grub
- locale: core-locale
- services: core-services
- network: core-network
- packages: core-packages
- mandatory: live-core-mandatory-packages
- post: live-core-post
- session: live-core-post-live-session
- initial-setup: core-initial-setup-gnome-desktop
- desktop: base-desktop-gnome
- repo: core-fedora-repo-rawhide
- live-core: fragments/shared/live/core/base.ks
- storage: fragments/shared/live/core/storage.ks
- bootloader: fragments/platform/generic-rawhide/bootloader/grub.ks
- locale: fragments/shared/core/locale.ks
- services: fragments/shared/core/services.ks
- network: fragments/shared/core/network.ks
- packages: fragments/shared/live/core/packages.ks
- mandatory: fragments/shared/live/core/packages.ks
- post: fragments/shared/live/post/base.ks
- session: fragments/shared/live/post/session.ks
- initial-setup: fragments/shared/initial-setup/desktop/config.ks
- desktop: fragments/shared/desktop/gnome/config.ks
- desktop-gnome-packages: fragments/shared/desktop/gnome/packages.ks
- desktop-gnome-post: fragments/shared/desktop/gnome/post-scripts.ks
- repo: fragments/platform/generic-rawhide/repo/rawhide-mirrors.ks
optional:
security:
secure: core-security-on
devel: core-security-off
packages-hw: core-packages-hardware-support
secure: fragments/shared/core/security/enabled.ks
devel: fragments/shared/core/security/disabled.ks
packages-hw: fragments/shared/packages/hardware-support.ks
extras: fragments/shared/guest-agents/packages.ks
modifiers:
storage:
standard: live-core-storage
encrypted: live-core-storage
standard: fragments/shared/live/core/storage.ks
encrypted: fragments/shared/live/core/storage.ks
# Live server recipe
# Modifiers: security (secure|devel), version (rawhide), hypervisor (true|false)
@@ -142,25 +162,25 @@ templates:
description: "A recipe for a live server"
base: live-core
required:
- live-core
- storage: live-core-storage
- bootloader: live-core-bootloader-grub
- locale: core-locale
- services: core-services
- network: core-network
- packages: core-packages
- mandatory: live-core-mandatory-packages
- post: live-core-post
- session: live-core-post-live-session
- initial-setup: core-initial-setup-server
- repo: core-fedora-repo-rawhide
- live-core: fragments/shared/live/core/base.ks
- storage: fragments/shared/live/core/storage.ks
- bootloader: fragments/platform/generic-rawhide/bootloader/grub.ks
- locale: fragments/shared/core/locale.ks
- services: fragments/shared/core/services.ks
- network: fragments/shared/core/network.ks
- packages: fragments/shared/live/core/packages.ks
- mandatory: fragments/shared/live/core/packages.ks
- post: fragments/shared/live/post/base.ks
- session: fragments/shared/live/post/session.ks
- initial-setup: fragments/shared/initial-setup/server/config.ks
- repo: fragments/platform/generic-rawhide/repo/rawhide-mirrors.ks
optional:
security:
secure: core-security-on
devel: core-security-off
packages-hw: core-packages-hardware-support
hypervisor: base-hypervisor
secure: fragments/shared/core/security/enabled.ks
devel: fragments/shared/core/security/disabled.ks
packages-hw: fragments/shared/packages/hardware-support.ks
hypervisor: fragments/shared/live/hypervisor.ks
modifiers:
storage:
standard: live-core-storage
encrypted: live-core-storage
standard: fragments/shared/live/core/storage.ks
encrypted: fragments/shared/live/core/storage.ks
+25
View File
@@ -0,0 +1,25 @@
# Phyllome OS Recipe Generator Test Container
FROM fedora:43
LABEL maintainer='Phyllome OS Team'
# Install minimal test dependencies
RUN dnf -y install \
pykickstart \
python3-pytest \
python3-pyyaml \
make \
git \
&& dnf clean all
# Set working directory
WORKDIR /phyllomeos
# Copy project files
COPY . /phyllomeos/
# Install Python dependencies
RUN pip install --no-cache-dir PyYAML pytest
# Run tests by default
CMD ["bash", "-c", "cd /phyllomeos && pytest tests/ -v"]
+129
View File
@@ -0,0 +1,129 @@
# Phyllome OS Recipe Generator Test Container
Minimal containerized testing environment for kickstart recipe validation.
## Build
```bash
cd /home/lukas/Code/virt/phyllomeos
podman build -t phyllo/test-runner tests/container/
# or: docker build -t phyllo/test-runner tests/container/
```
## Run Tests
```bash
# Run all tests (unit + integration + golden masters)
podman run --rm -v .:/phyllomeos:ro phyllo/test-runner
# Run specific test file
podman run --rm -v .:/phyllomeos:ro phyllo/test-runner pytest tests/integration/test_fragments.py -v
# Interactive mode for debugging
podman run -it --rm -v .:/phyllomeos phyllo/test-runner bash
```
## Test Types
### Unit Tests
- **Location:** `tests/test_recipe_generator.py`
- **Count:** 36 tests
- **Description:** Tests for recipe generator functionality (template loading, validation, version extraction)
### Fragment Validation Tests
- **Location:** `tests/integration/test_fragments.py`
- **Count:** ~15 tests
- **Description:** Validates all 54 fragments with pykickstart, checks section structure
### Recipe Composition Tests
- **Location:** `tests/integration/test_recipe_composition.py`
- **Count:** ~10 tests
- **Description:** Tests recipe generation, validates all 16 manifest variants
### Semantic Validation Tests
- **Location:** `tests/integration/test_semantic_validation.py`
- **Count:** ~10 tests
- **Description:** pykickstart semantic validation, deprecated command detection
### Golden Master Tests
- **Location:** `tests/integration/test_golden_masters.py`
- **Count:** ~5 tests
- **Description:** Regression tests comparing generated recipes against expected outputs
## Test Structure
```
tests/
├── test_recipe_generator.py # Unit tests (36 tests)
├── integration/
│ ├── test_fragments.py # Fragment validation (~15 tests)
│ ├── test_recipe_composition.py # Recipe generation (~10 tests)
│ ├── test_semantic_validation.py # pykickstart semantic (~10 tests)
│ ├── test_golden_masters.py # Regression tests (~5 tests)
│ └── conftest.py # Pytest fixtures
├── fixtures/
│ ├── expected_recipes/ # 5 golden master files
│ └── sample_fragments/ # Test fragment samples
└── container/
├── Containerfile # Test runner container definition
├── run-tests.sh # Test entrypoint script
└── README.md # This file
```
## Container Contents
The test runner container includes:
- **OS:** Fedora 43
- **Python packages:**
- `pykickstart` - Kickstart parsing and validation
- `pytest` - Test framework
- `PyYAML` - YAML parsing
- **System tools:**
- `make` - Build automation
- `git` - Version control
- `coreutils` - Basic utilities
## Adding New Tests
1. Add test file to `tests/integration/`
2. Follow naming convention: `test_*.py`
3. Use pytest fixtures from `conftest.py`
4. Run tests in container to verify
## Troubleshooting
### Container won't start
```bash
# Check if container builds
podman build tests/container/
# Run with verbose output
podman run --rm -v .:/phyllomeos:ro -e PYTEST_VERBOSITY=2 phyllo/test-runner
```
### Tests failing inside container
```bash
# Get interactive shell
podman run -it --rm -v .:/phyllomeos phyllo/test-runner bash
# Run tests manually
cd /phyllomeos
pytest tests/integration/test_fragments.py -v
```
### Permission denied errors
```bash
# Run with security options (for rootless podman)
podman run --rm --security-opt label=disable -v .:/phyllomeos:ro phyllo/test-runner
```
## CI/CD Integration
This container will be used in Gitea Actions workflows for:
- Pull request validation
- Main branch testing
- Automated recipe generation checks
See `.gitea/workflows/` for workflow definitions.
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
# Run all tests inside the container environment
# Usage: podman run --rm -v .:/phyllomeos:ro phyllo/test-runner
set -e
echo "============================================="
echo " Phyllome OS Recipe Generator Test Suite"
echo "============================================="
echo ""
# Navigate to project root
cd /phyllomeos
echo "[1/3] Running unit tests (test_recipe_generator.py)..."
echo "----------------------------------------"
python3 -m pytest tests/test_recipe_generator.py -v
echo "✓ Unit tests passed!"
echo ""
echo "[2/3] Running integration tests..."
echo "----------------------------------------"
python3 -m pytest tests/integration/ -v
echo "✓ Integration tests passed!"
echo ""
echo "[3/3] Validating generated recipes..."
echo "----------------------------------------"
cd scripts
python3 generate_recipe.py --validate ../recipes/*.cfg --strict
echo "✓ Recipe validation passed!"
echo ""
echo "============================================="
echo " ALL TESTS PASSED!"
echo "============================================="
echo ""
echo "Summary:"
echo " - Unit tests: 36 tests (test_recipe_generator.py)"
echo " - Integration tests: Fragment validation, recipe composition, golden masters"
echo " - Fragment validation: 54 .ks files checked"
echo " - Recipe validation: All 16 manifest variants generated and validated"
echo ""
@@ -0,0 +1,29 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# A recipe for a desktop hypervisor
%ksappend fragments/shared/core/base.ks
%ksappend fragments/shared/storage/standard.ks
%ksappend fragments/platform/generic-rawhide/bootloader/grub.ks
%ksappend fragments/shared/core/locale.ks
%ksappend fragments/shared/core/services.ks
%ksappend fragments/shared/core/network.ks
%ksappend fragments/shared/packages/core-group.ks
%ksappend fragments/shared/packages/fedora-remix.ks
%ksappend fragments/shared/packages/hand-picked.ks
%ksappend fragments/shared/packages/hardware-support.ks
%ksappend fragments/shared/initial-setup/desktop/config.ks
%ksappend fragments/shared/desktop/gnome/config.ks
%ksappend fragments/shared/desktop/gnome/packages.ks
%ksappend fragments/shared/desktop/gnome/post-scripts.ks
%ksappend fragments/shared/desktop/vmm/packages.ks
%ksappend fragments/shared/desktop/vmm/post-scripts.ks
%ksappend fragments/platform/generic-rawhide/repo/rawhide-mirrors.ks
%ksappend fragments/shared/hypervisor/base/services.ks
%ksappend fragments/shared/hypervisor/base/packages.ks
%ksappend fragments/shared/hypervisor/base/post-scripts.ks

Some files were not shown because too many files have changed in this diff Show More