remove old python scripts and add new updated recipes

This commit is contained in:
Lukas Greve
2026-03-27 19:34:05 +01:00
parent e9615b524d
commit 464fd8c158
82 changed files with 3085 additions and 2067 deletions
-503
View File
@@ -1,503 +0,0 @@
"""CLI entry point for recipe generator.
This module handles the command-line interface for the recipe generator. It:
1. Parses command-line arguments and options
2. Selects the appropriate mode (validation, batch generation, single generation)
3. Sets up generators and validators with proper configuration
4. Orchestrates the workflow based on user input
5. Handles output and exit codes for integration with CI systems
The CLI supports three main modes:
- Single generation: Generate one recipe with specific options
- Batch generation: Generate many recipes from a manifest file
- Validation mode: Check existing recipes for errors
Exit codes:
- 0: Success
- 1: Validation errors or generation failed
- 2: Invalid arguments or missing files
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
from typing import List
import yaml
from manifest import ManifestProcessor
from recipe_generator import RecipeGenerator
from validators import (
ContentValidator,
SemanticValidator,
TemplateValidator,
validate_manifest,
)
def main() -> None:
"""Main entry point for recipe generator CLI.
This is the primary function that gets called when running the script.
It handles argument parsing, mode selection, and workflow orchestration.
Command-line arguments:
--ingredients (-i): Directory containing ingredient fragments (default: parent/ingredients)
--templates (-t): Path to templates YAML file (default: ./recipe_templates.yaml)
Batch mode flags:
--manifest (-m): Path to manifest YAML for batch generation
--output-dir (-d): Output directory for generated recipes (default: ./recipes)
--dry-run (-n): Show what would be generated without writing files
Single generation flags:
--type (-T): Recipe type to generate (e.g., virtual-desktop)
--output (-o): Output file path for single generation
Recipe parameters:
--version (-v): Fedora version (43 or rawhide, default: 43)
--desktop: Desktop environment (gnome or labwc, default: gnome)
--storage: Storage type (standard or encrypted, default: standard)
--security: Security mode (secure or devel, default: secure)
--cpu: CPU optimization (generic, amdcpu, or intelcpu)
--gpu: GPU passthrough (none or intelgpu, default: none)
Validation mode:
--validate (-V): Validate existing recipe files
--strict: Treat warnings as errors (CI mode)
Modes:
1. Validation mode (--validate): Check recipe files without generating new ones
2. Batch generation mode (--manifest): Generate many recipes from a manifest
3. Single generation mode (--type): Generate one recipe with specified options
4. Help mode: No arguments or --help shows usage information
"""
# Set up argument parser with descriptive help text
parser = argparse.ArgumentParser(
description='Generate Phyllome OS kickstart recipes from templates',
formatter_class=argparse.RawDescriptionHelpFormatter
)
# Calculate paths relative to this script's location
# SCRIPTS_DIR points to recipe-generator/
# PROJECT_ROOT points to phyllomeos/
SCRIPTS_DIR = Path(__file__).resolve().parent # noqa: N806 - Constant
PROJECT_ROOT = SCRIPTS_DIR.parent # noqa: N806 - Constant
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: ./recipe_templates.yaml)')
# Batch mode options
parser.add_argument('--manifest', '-m',
type=Path, help='Manifest YAML for batch generation')
parser.add_argument('--output-dir', '-d',
type=Path, default=SCRIPTS_DIR / 'recipes',
help='Output directory (batch generation, default: ./recipes)')
parser.add_argument('--dry-run', '-n',
action='store_true',
help='Show what would be generated without writing files')
parser.add_argument('--output', '-o',
type=Path, help='Output file (single generation)')
# Recipe customization parameters (default to safe/common values)
parser.add_argument('--version', '-v',
choices=['43', 'rawhide'], default='43',
help='Fedora version (default: 43)')
parser.add_argument('--desktop',
choices=['gnome', 'labwc'],
default='gnome',
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)')
# Parse arguments from command line
args = parser.parse_args()
# Initialize the recipe generator with loaded templates
generator = RecipeGenerator(args.templates)
# Initialize validators - they'll be used throughout the workflow
template_validator = TemplateValidator(generator.project_root)
content_validator = ContentValidator(generator.project_root)
semantic_validator = SemanticValidator()
# === VALIDATION MODE ===
# If --validate is specified, skip generation and just check existing recipes
if args.validate:
all_issues = validate_recipes(args.validate, content_validator, semantic_validator, args.strict)
handle_validation_results(all_issues, args.strict)
return
# === BATCH GENERATION MODE ===
# If --manifest is specified, generate many recipes from a manifest file
if args.manifest:
generate_from_manifest(args, generator)
return
# === SINGLE GENERATION MODE ===
# If --output is specified without --manifest, generate one recipe with the given options
# This makes --output without --manifest trigger single generation mode
if args.output and not args.manifest:
generate_single(args, generator)
return
# === NO MODE SPECIFIED ===
# Show help and exit with error
parser.print_help()
sys.exit(1)
def validate_recipes(recipe_paths: List[str], content_validator: ContentValidator,
semantic_validator: SemanticValidator, strict: bool) -> List:
"""Validate multiple recipes from file paths.
This function iterates through a list of recipe file paths, validates each one
for both content issues (duplicates, missing ingredients) and semantic issues
(kickstart syntax errors).
The validation process for each file:
1. Read the file content
2. Run ContentValidator to check ingredient existence and duplicates
3. Try to extract the Fedora version from content or filename
4. Run SemanticValidator (pykickstart parser) to check kickstart syntax
5. Collect all issues found
Args:
recipe_paths: List of file paths to validate
content_validator: ContentValidator instance for ingredient checks
semantic_validator: SemanticValidator instance for kickstart parsing
strict: If True, treat warnings as errors (exit with 1)
Returns:
List of (path, issues) tuples for files that have issues
Example: [('recipes/gnome.cfg', ['ERROR: Missing ingredient', 'Warning: ...'])]
"""
all_issues = []
for recipe_path in recipe_paths:
try:
# Validate content - check for duplicates and missing ingredients
content = Path(recipe_path).read_text(encoding='utf-8')
issues = content_validator.validate(content)
# Extract version from content or filename for semantic validation
filename = Path(recipe_path).stem
version = extract_version(content, filename)
if version:
semantic_issues = semantic_validator.validate(content, version)
issues.extend(semantic_issues)
else:
# Could not determine version, can't do semantic validation
issues.append("Warning: Could not determine version, "
"skipping semantic validation")
if issues:
# Only track files that have issues
all_issues.append((recipe_path, issues))
except FileNotFoundError:
print(f"Error: Recipe not found: {recipe_path}", file=sys.stderr)
sys.exit(2)
return all_issues
def extract_version(content: str, filename: str) -> str | None:
"""Extract Fedora version from recipe content or filename.
This function tries multiple heuristics to determine which Fedora version
a recipe is targeting. It checks the filename first, then falls back to
searching the content for version-specific patterns.
The method checks for:
1. Version in filename: patterns like _43_, -rawhide.cfg, _43.cfg
2. Version in content: repository paths like 'core-fedora-repo-43'
This is useful for batch operations where the version might not be
explicitly stated but can be inferred from naming conventions or content.
Args:
content: The content of the recipe file (as a string)
filename: Just the filename without path
Returns:
Version string ('43' or 'rawhide') if found, None otherwise
"""
import re
# Try to extract from filename first using regex
# Matches patterns like _43, -43, _rawhide, -rawhide, etc.
# The lookahead for .cfg|.yaml|$ ensures we don't match 43 in '431'
filename_match = re.search(r'(?:_|-)(43|rawhide)(?:_|-|.cfg|.yaml|$)', filename)
if filename_match:
return filename_match.group(1)
# Fall back to content inspection
# Check for Fedora repository paths that contain version info
for line in content.split('\n'):
if 'core-fedora-repo-43' in line:
return '43'
elif 'core-fedora-repo-rawhide' in line:
return 'rawhide'
if 'generic-43/repo' in line:
return '43'
elif 'generic-rawhide/repo' in line:
return 'rawhide'
return None
def handle_validation_results(all_issues: List, strict: bool) -> None:
"""Handle validation results and exit with appropriate code.
This function formats and displays validation results to the user,
then exits with the appropriate code based on the results and strict mode.
The output format:
- Group issues by file
- Show errors first (separate from warnings)
- Show summary totals at the end
Exit codes:
- 0: All files passed validation
- 1: Any issues found (or warnings in strict mode)
- 2: Error during processing
Args:
all_issues: List of (path, issues) tuples from validate_recipes()
strict: If True, warnings are treated as errors
"""
if all_issues:
# Display issues for each file that has problems
for path, issues in all_issues:
print(f"\n{path}:", file=sys.stderr)
# Count errors and warnings separately
error_count = sum(1 for i in issues if 'ERROR' in i or 'error' in i.lower())
warning_count = sum(1 for i in issues if 'Warning' in i or 'warning' in i.lower())
# Display errors (if any)
if error_count > 0:
for issue in issues:
if 'ERROR' in issue or 'error' in issue.lower():
print(f" {issue}", file=sys.stderr)
# Display warnings (if any)
if warning_count > 0:
for issue in issues:
if 'Warning' in issue or 'warning' in issue.lower():
print(f" {issue}", file=sys.stderr)
# Handle case where no issues match expected patterns
if error_count == 0 and warning_count == 0:
print(f" No issues found (file exists)", file=sys.stderr)
# Print summary
print(f"\nSummary:", file=sys.stderr)
print(f" - {len(all_issues)} recipe(s) checked", file=sys.stderr)
# Calculate totals across all files
total_errors = sum(len([i for i in issues if 'ERROR' in i or 'error' in i.lower()])
for _, issues in all_issues)
total_warnings = sum(len([i for i in issues if 'Warning' in i or 'warning' in i.lower()])
for _, issues in all_issues)
print(f" - {total_errors} error(s), {total_warnings} warning(s)", file=sys.stderr)
# In strict mode, warnings are treated as errors
if strict and total_warnings > 0:
print("\nStrict mode: Warnings treated as errors", file=sys.stderr)
sys.exit(1)
# Exit with error if any issues found
if total_errors > 0:
sys.exit(1)
else:
# All recipes validated successfully
print("All recipes validated successfully")
sys.exit(0)
def generate_from_manifest(args: argparse.Namespace, generator: RecipeGenerator) -> None:
"""Generate recipes in batch from a manifest file.
This function handles batch generation mode. It:
1. Loads and parses the manifest YAML file
2. Validates the manifest structure
3. Iterates through each recipe configuration in the manifest
4. Expands any variants with list values (cartesian product)
5. Generates each variant and writes to output files
6. Optionally runs validation or dry-run checks
The manifest YAML format:
recipes:
- name: virtual-desktop
variants:
- version: 43
desktop: gnome
storage: encrypted
- version: ["43", "rawhide"]
security: secure
The list-valued variants (like version) get expanded into all combinations.
Args:
args: Parsed command-line arguments containing paths and settings
generator: Pre-configured RecipeGenerator instance
"""
manifest_path = args.manifest
try:
# Load manifest YAML file
with open(manifest_path, encoding='utf-8') as f:
manifest = yaml.safe_load(f)
except FileNotFoundError:
print(f"Error: Manifest file not found: {manifest_path}", 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 structure before processing
manifest_processor = ManifestProcessor(generator.project_root)
errors = manifest_processor.validate(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 from the manifest
for recipe_config in manifest.get('recipes', []):
# No recipe_type needed - use the universal template directly
name = recipe_config.get('name', 'unnamed')
variants = recipe_config.get('variants', [])
# Expand list-valued variants (e.g., version: ["43", "rawhide"])
variants = generator.expand_variants(variants)
for variant in variants:
# Extract version and other modifiers from variant
version = variant['version']
modifiers = {k: v for k, v in variant.items() if k not in ['name', 'version']}
# name kept for manifest organization only, not passed to generator
# Generate the recipe content
content = generator.generate(version, **modifiers)
# Optional validation on generated content
if args.validate and not args.dry_run:
issues = content_validator.validate(content)
semantic_issues = semantic_validator.validate(content, version)
all_issues = issues + semantic_issues
if all_issues:
print(f"Validation issues for {name} {version}:", file=sys.stderr)
for issue in issues:
print(f" - {issue}", file=sys.stderr)
sys.exit(1)
# Generate output filename based on recipe parameters
filename = generator.generate_filename(version, **modifiers)
output_path = args.output_dir / filename
# Handle dry-run mode
if args.dry_run:
print(f"Would generate: {output_path}")
else:
# Actually write the file
print(f"Generating: {output_path}")
with open(output_path, 'w', encoding='utf-8') as f:
f.write(content)
def generate_single(args: argparse.Namespace, generator: RecipeGenerator) -> None:
"""Generate a single recipe with the specified parameters.
This function handles single recipe generation mode. It:
1. Constructs a modifiers dictionary from command-line arguments
2. Only includes non-default values (e.g., only adds 'encrypted' if storage is encrypted)
3. Generates the recipe content
4. Optionally validates the content
5. Outputs to a file or stdout based on arguments
Command-line parameter to modifier mapping:
--type -> recipe_type (required)
--version -> version (43 or rawhide)
--desktop -> desktop (gnome or labwc)
--storage -> storage (standard or encrypted)
--security -> security (secure or devel)
--cpu -> cpu (generic, amdcpu, or intelcpu)
--gpu -> gpu (none or intelgpu)
Args:
args: Parsed command-line arguments
generator: Pre-configured RecipeGenerator instance
"""
# Build modifiers dictionary from command-line arguments
# Only include non-default values to keep filenames clean
modifiers = {
'desktop': args.desktop if args.desktop 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,
}
# Remove Nones from modifiers
modifiers = {k: v for k, v in modifiers.items() if v is not None}
# Generate the recipe
content = generator.generate(args.version, **modifiers)
# Optional validation
if args.validate:
content_validator = ContentValidator(generator.project_root)
issues = content_validator.validate(content)
semantic_validator = SemanticValidator()
semantic_issues = semantic_validator.validate(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")
# Output the recipe
if args.output:
# Write to file
if args.dry_run:
print(f"Would write to: {args.output}")
else:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(content)
print(f"Generated: {args.output}")
else:
# Print to stdout
print(content)
@@ -132,6 +132,8 @@ pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
@@ -132,6 +132,8 @@ pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
@@ -106,6 +106,7 @@ glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -106,6 +106,7 @@ glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
@@ -29,7 +29,7 @@ url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&ar
# X Window System configuration information
xconfig --defaultdesktop=GNOME --startxonboot
# System bootloader configuration
bootloader --location=mbr --timeout=1
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
zerombr
# Partition clearing information
@@ -0,0 +1,140 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,140 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,139 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
usbutils
wget
%end
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,139 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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" --encrypted --mkfsoptions="-O encrypt,fast_commit"
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
usbutils
wget
%end
@@ -29,7 +29,7 @@ url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&ar
# X Window System configuration information
xconfig --defaultdesktop=GNOME --startxonboot
# System bootloader configuration
bootloader --location=mbr --timeout=1
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
zerombr
# Partition clearing information
@@ -132,6 +132,8 @@ pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
@@ -132,6 +132,8 @@ pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
@@ -106,6 +106,7 @@ glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -106,6 +106,7 @@ glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
@@ -29,7 +29,7 @@ url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&ar
# X Window System configuration information
xconfig --defaultdesktop=GNOME --startxonboot
# System bootloader configuration
bootloader --location=mbr --timeout=1
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
zerombr
# Partition clearing information
@@ -0,0 +1,140 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,140 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,139 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
usbutils
wget
%end
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,141 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -0,0 +1,139 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
@hardware-support
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
usbutils
wget
%end
@@ -29,7 +29,7 @@ url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&ar
# X Window System configuration information
xconfig --defaultdesktop=GNOME --startxonboot
# System bootloader configuration
bootloader --location=mbr --timeout=1
bootloader --location=mbr --timeout=1 --sdboot
# Clear the Master Boot Record
zerombr
# Partition clearing information
@@ -39,61 +39,6 @@ part /boot/efi --fstype="efi" --size=512 --fsoptions="umask=0077,shortname=winnt
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/vmm-post-scripts.log
# 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
%post --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
cat >> /mnt/sysimage/usr/share/glib-2.0/schemas/org.gnome.desktop.media-handling.gschema.override<< EOF
@@ -158,6 +103,61 @@ glib-compile-schemas /mnt/sysimage/usr/share/glib-2.0/schemas/
%end
%post --nochroot --logfile=/mnt/sysimage/root/vmm-post-scripts.log
# 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
%post --nochroot --logfile=/mnt/sysimage/root/hypervisor-amdcpu-post.log
sed -i 's/\(quiet\)/\1 iommu=pt rd.driver.pre=vfio-pci/i' /mnt/sysimage/etc/default/grub # Load kernel modules in GRUB.
@@ -195,6 +195,8 @@ pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
virt-manager
wget
@@ -0,0 +1,204 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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
bootloader --location=mbr --timeout=1
# Clear the Master Boot Record
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 --nochroot --logfile=/mnt/sysimage/root/gnome-desktop-post.log
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
%post --nochroot --logfile=/mnt/sysimage/root/vmm-post-scripts.log
# 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
%post --nochroot --logfile=/mnt/sysimage/root/hypervisor-intelcpu-post.log
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
%packages --exclude-weakdeps
@base-graphical
@core
bash-color-prompt
curl
dconf
dejavu-sans-mono-fonts
fedora-remix-logos
firefox
gdm
generic-logos
generic-release
generic-release-common
generic-release-notes
gnome-backgrounds.noarch
gnome-control-center
gnome-session-wayland-session
gnome-shell
gnome-terminal
gvfs-fuse
initial-setup
libusb
mozilla-ublock-origin.noarch
nano
nautilus
pciutils
pipewire-alsa
pipewire-jack-audio-connection-kit
pipewire-pulseaudio
qemu-guest-agent
spice-vdagent
usbutils
virt-manager
wget
%end
@@ -49,6 +49,8 @@ initial-setup
libusb
nano
pciutils
qemu-guest-agent
spice-vdagent
usbutils
wget
+57
View File
@@ -0,0 +1,57 @@
# Generated by pykickstart v3.69
#version=DEVEL
# Use text mode install
text
# Firewall configuration
firewall --enabled
# Run the Setup Agent on first boot
firstboot --reconfig
# Keyboard layouts
keyboard --xlayouts='ch (fr)'
# System language
lang en_US.UTF-8
# Network information
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
selinux --enforcing
# System services
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"
# System bootloader configuration
bootloader --location=mbr --timeout=1
# Clear the Master Boot Record
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"
%packages --exclude-weakdeps
@core
curl
fedora-remix-logos
generic-logos
generic-release
generic-release-common
generic-release-notes
initial-setup
libusb
nano
pciutils
qemu-guest-agent
spice-vdagent
usbutils
wget
%end
@@ -39,6 +39,7 @@ part / --fstype="ext4" --grow --label="root" --mkfsoptions="-O encrypt,fast_comm
%packages --exclude-weakdeps
@core
@hardware-support
curl
fedora-remix-logos
generic-logos
@@ -39,6 +39,7 @@ part / --fstype="ext4" --grow --label="root" --mkfsoptions="-O encrypt,fast_comm
%packages --exclude-weakdeps
@core
@hardware-support
curl
fedora-remix-logos
generic-logos
@@ -77,6 +77,7 @@ echo "options kvm_amd nested=1" >> /mnt/sysimage/etc/modprobe.d/kvm.conf # Add s
%packages --exclude-weakdeps
@core
@hardware-support
curl
fedora-remix-logos
generic-logos
@@ -77,6 +77,7 @@ echo "options kvm_intel nested=1" >> /mnt/sysimage/etc/modprobe.d/kvm.conf # Add
%packages --exclude-weakdeps
@core
@hardware-support
curl
fedora-remix-logos
generic-logos
-208
View File
@@ -1,208 +0,0 @@
"""Manifest loading and variant expansion.
This module provides functionality for processing manifest YAML files, which
are used in batch recipe generation mode. It has two main responsibilities:
1. Loading and Parsing Manifests
- Reads YAML files containing recipe configurations
- Validates basic structure of the manifest
2. Variant Expansion
- Converts compact manifest entries with list values into individual variants
- Uses cartesian product to generate all combinations
- Enables generating many recipes from a single manifest entry
Manifest Example:
recipes:
- name: desktop
variants:
- version: 43
desktop: gnome
storage: encrypted
- version: ["43", "rawhide"]
storage: ["standard", "encrypted"]
The above would generate 3 recipes (1 desktop + 2 rawhide variants).
With the universal template (proteus), recipes are generated using a single
template that supports all system types. The 'name' field is purely for
organization and doesn't affect the generated filenames.
The key insight is that list values in variants represent "multiple values for
this field", and we want to generate one recipe for each combination. This is
the classic cartesian product problem.
"""
from __future__ import annotations
from itertools import product
from pathlib import Path
from typing import Dict, List
import yaml
class ManifestProcessor:
"""Load and process recipe manifests.
This class handles the loading and processing of manifest YAML files.
A manifest is a YAML file that defines which recipes to generate and
what variations (variants) of each recipe to create.
Key features:
- Loads and parses YAML manifest files
- Validates manifest structure (schema-level checks)
- Expands variants with list values into all combinations
The variant expansion is particularly useful for generating multiple
versions (e.g., both Fedora 43 and rawhide) or multiple configurations
(e.g., both standard and encrypted storage) in a compact format.
"""
def __init__(self, project_root: Path):
"""Initialize the processor with project root path.
Args:
project_root: Path to the phyllomeos project root directory.
Not currently used but available for future enhancements.
"""
self.project_root = project_root
def load(self, path: Path) -> Dict:
"""Load and parse manifest YAML file.
This method reads a YAML file from disk and parses it into a Python
dictionary. It's a simple wrapper around yaml.safe_load that provides
error handling and a consistent interface.
Args:
path: Path to the manifest YAML file
Returns:
Parsed manifest as a dictionary
Raises:
FileNotFoundError: If the file doesn't exist
yaml.YAMLError: If the file contains invalid YAML
"""
with open(path, encoding='utf-8') as f:
return yaml.safe_load(f)
def validate(self, manifest: Dict) -> List[str]:
"""Validate manifest structure.
This method performs schema-level validation of a manifest dictionary.
It checks that:
1. The top-level 'recipes' key exists
2. Each recipe configuration has a 'name' field (for organization only)
3. Each recipe configuration has a 'variants' field
4. Each variant has a 'version' field
5. No 'recipe_type' field exists (old format, removed with universal template)
This is a basic structural check that catches obvious errors before
trying to process the manifest. It doesn't validate the content of
individual recipes (that's done by RecipeGenerator and validators).
Args:
manifest: The manifest dictionary to validate
Returns:
List of validation error strings (empty if valid)
"""
errors = []
# Check for required top-level key
if 'recipes' not in manifest:
errors.append("Manifest missing 'recipes' key")
return errors # Can't proceed without recipes
# Validate each recipe configuration
for recipe_config in manifest.get('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")
# Check for old recipe_type field (which is no longer used)
if 'recipe_type' in recipe_config:
errors.append(f"Recipe '{recipe_config.get('name', 'unnamed')}' "
"has 'recipe_type' field which is no longer used with universal template")
return errors
def expand_variants(self, variants: List[Dict]) -> List[Dict]:
"""Expand variants with list values into individual variants.
This is the core functionality of the manifest processor. It converts
a compact representation with list values into a complete list of
individual variants by generating the cartesian product.
Example Input:
[
{
'version': ['43', 'rawhide'],
'storage': ['standard', 'encrypted'],
'desktop': 'gnome'
},
{
'version': '43',
'security': 'devel'
}
]
Example Output:
[
{'version': '43', 'storage': 'standard', 'desktop': 'gnome'},
{'version': '43', 'storage': 'encrypted', 'desktop': 'gnome'},
{'version': 'rawhide', 'storage': 'standard', 'desktop': 'gnome'},
{'version': 'rawhide', 'storage': 'encrypted', 'desktop': 'gnome'},
{'version': '43', 'security': 'devel'}
]
How it works:
1. For each variant dictionary, separate list-valued keys from scalar keys
2. If there are no lists, keep the variant as-is
3. If there are lists, generate the cartesian product of all list values
4. For each combination, create a new variant with scalar values preserved
5. Return the complete list of expanded variants
This enables generating many recipes from a single compact manifest entry,
making it easy to generate variations across multiple dimensions.
Args:
variants: List of variant dictionaries, where some values may be lists
Returns:
Expanded list where each variant has only scalar (non-list) values
"""
expanded = []
for variant in variants:
# Separate list-valued keys from scalar keys
list_keys = {}
scalar_keys = {}
for key, value in variant.items():
if isinstance(value, list):
list_keys[key] = value
else:
scalar_keys[key] = value
if not list_keys:
# No lists to expand, keep variant as-is
expanded.append(variant)
continue
# Get the cartesian product of all list values
keys = list(list_keys.keys())
values_product = product(*[list_keys[k] for k in keys])
# Create a new variant for each combination
for combo in values_product:
new_variant = scalar_keys.copy()
for i, key in enumerate(keys):
new_variant[key] = combo[i]
expanded.append(new_variant)
return expanded
-42
View File
@@ -1,42 +0,0 @@
import subprocess
import re
# Get all package names from your config file
packages = []
with open('core-packages-hardware-support.cfg', 'r') as f:
for line in f:
if line.strip() and not line.startswith('#') and '#' not in line:
# Extract package name (everything before the first space or #)
package = line.strip().split('#')[0].strip()
if package and not package.startswith('%'):
packages.append(package)
# Get summaries using dnf info
summaries = {}
for package in packages:
try:
result = subprocess.run(['dnf', 'info', package],
capture_output=True, text=True, timeout=30)
if result.returncode == 0:
# Extract summary line
summary_match = re.search(r'Summary\s*:\s*(.+)', result.stdout)
if summary_match:
summaries[package] = summary_match.group(1).strip()
except Exception as e:
print(f"Error getting info for {package}: {e}")
# Now you can generate your updated package list with summaries
with open('core-packages-hardware-support.cfg', 'r') as f:
lines = f.readlines()
new_lines = []
for line in lines:
if line.strip() and not line.startswith('#') and not line.startswith('%'):
package = line.strip().split('#')[0].strip()
if package in summaries:
line = f"{package} # {summaries[package]}\n"
new_lines.append(line)
# Write back to file (or save as new file)
with open('updated-packages.cfg', 'w') as f:
f.writelines(new_lines)
-810
View File
@@ -1,810 +0,0 @@
"""Core recipe generation logic.
This module is the heart of the Phyllome OS kickstart recipe generation system.
It works like a sophisticated template engine that:
1. Reads template definitions from recipe_templates.yaml
2. Each template defines:
- Required ingredients (always included, like base system components)
- Modifiers (user choices like desktop environment, storage type)
- Optional ingredients (included based on modifier values)
- Versioned ingredients (Fedora version-specific paths)
- Conditional ingredients (complex logic based on multiple factors)
- Flags (boolean on/off switches for features)
3. When you call generate(), it:
- Looks up the template for your recipe type (e.g., "virtual-desktop")
- Processes all the modifier values you passed in
- Builds a list of %include directives pointing to ingredient fragments
- Returns a complete kickstart file with header and includes
Think of it as a "recipe assembler" - the templates are the master recipes,
modifiers are your customizations, and the output is a complete installation
script that pulls in the right ingredient fragments.
"""
from __future__ import annotations
from pathlib import Path
from typing import Dict, List
from validators import (
TemplateValidator,
ContentValidator,
SemanticValidator,
validate_manifest,
)
import yaml
# ASCII art banner displayed at the top of every generated recipe file.
# This decorative header identifies the output as a Phyllome OS kickstart recipe.
# The backslashes are escaped because they're inside a Python string.
HEADER_ASCII_ART = [
"# __ ____ ____ _____",
"# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \\/ ___/",
"# / __ \\/ __ \\/ / / / / / __ \\/ __ `__ \\/ _ \\ / / / /\\__ \\",
"# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /",
"# / .___/_/ /_/\\__, /_/_/\\____/_/ /_/ /_/\\___/ \\____//____/",
"# /_/ /____/",
"",
]
class RecipeGenerator:
"""Generate kickstart recipes from templates and modifiers.
This is the core class that powers the recipe generation system. It works by:
1. Loading template definitions from a YAML file (recipe_templates.yaml)
2. The template defines all the base ingredients and modifier options
3. Accepting version (Fedora version) and optional modifiers
4. Building a list of %include directives pointing to ingredient fragments
5. Outputting a complete kickstart file with header and includes
Think of it as a "recipe assembler" - the template is the master recipe,
modifiers are your customizations, and the output is a complete installation
script that pulls in the right ingredient fragments.
Example usage:
generator = RecipeGenerator(Path('recipe_templates.yaml'))
recipe = generator.generate('43', desktop='gnome', storage='encrypted')
# Returns a string containing the complete kickstart recipe
"""
def __init__(self, templates_file: Path):
"""Initialize RecipeGenerator.
Args:
templates_file: Path to the templates YAML file.
This should be the full path to recipe_templates.yaml.
"""
self.project_root = templates_file.parent.parent
self.templates = self._load_templates(templates_file)
def _load_templates(self, path: Path) -> Dict:
"""Load recipe templates from YAML file.
This method reads the templates YAML file and loads it as a single universal template.
The YAML file now contains the proteus template directly without a 'templates' wrapper.
Args:
path: Path to the templates YAML file (can be absolute or relative)
Returns:
The template dictionary (entire YAML content).
Example structure:
{
'name': 'proteus',
'description': 'Universal template...',
'required': {...},
'modifiers': {...},
'optional': {...},
'versioned': {...},
'conditional': {...},
'flags': {...}
}
Raises:
SystemExit: If the file is not found or contains invalid YAML
"""
try:
if path.is_absolute():
template_path = path
else:
# Resolve relative paths from project root
template_path = self.project_root / path
with open(template_path, encoding='utf-8') as f:
data = yaml.safe_load(f)
# Return the entire YAML content as the single universal template
return data
except FileNotFoundError:
print(f"Error: Templates file not found: {template_path}")
exit(2)
except yaml.YAMLError as e:
print(f"Error: Invalid YAML in {template_path}: {e}")
exit(2)
def generate(self, version: str, **modifiers) -> str:
"""Generate a complete kickstart recipe from a template with modifiers.
This is the main entry point for recipe generation. It takes a Fedora version
and any number of modifier options, then returns a complete kickstart file as a string.
Args:
version: Fedora version string, typically '43' or 'rawhide'.
This affects which versioned ingredients are included.
**modifiers: Keyword arguments for recipe customization:
- desktop: 'gnome' or 'labwc'
- storage: 'standard' or 'encrypted'
- security: 'secure' or 'devel'
- cpu: 'generic', 'amdcpu', or 'intelcpu'
- gpu: 'none' or 'intelgpu'
- guest_agents: True/False for virtualization tools
- And many others...
Returns:
A string containing the complete kickstart recipe, including:
- ASCII art header
- Description comment
- %include directives for all required and selected ingredients
Raises:
SystemExit: If the template is invalid or missing required ingredients
"""
template = self.templates
# Build the output in two parts:
# 1. Header with ASCII art and description
# 2. All the %include lines for ingredients
lines = self._build_header(template['description'])
lines.extend(self._build_includes(template, version, modifiers))
# Join all lines with newlines to create the final recipe string
return '\n'.join(lines)
generate_recipe = generate # Compatibility alias - old code may use this name
def _build_header(self, description: str) -> List[str]:
"""Build the ASCII art header and description for the recipe.
Creates the decorative banner that appears at the top of every generated
kickstart file. This helps identify the file as a Phyllome OS recipe and
describes what type of system it will install.
Args:
description: Human-readable description of the template
(e.g., "Universal template for generating kickstart recipes")
Returns:
List of strings representing the header lines, including:
- The ASCII art banner (from HEADER_ASCII_ART constant)
- A comment line with the template description
- An empty line to separate header from content
"""
header = HEADER_ASCII_ART.copy()
header.append(f"# {description}")
header.append("")
return header
def _build_includes(self, template: Dict, version: str, modifiers: Dict) -> List[str]:
"""Build %include lines from template and modifiers.
This is the most complex method in the class - it's the core logic that
determines which ingredient fragments get included in the final recipe.
The method processes six different types of ingredient sources:
1. REQUIRED: Always included, no conditions
Example: base system packages, partition layout
2. MODIFIERS: User-specified options that map to ingredient paths
Example: desktop='gnome' → ingredients/desktops/gnome.cfg
3. OPTIONAL: Included only if the modifier is present
Example: gpu='intelgpu' → ingredients/gpu/intel.cfg
4. VERSIONED: Paths with {version} placeholder substituted
Example: ingredients/repo/f{version}.cfg → ingredients/repo/f43.cfg
5. CONDITIONAL: Complex logic based on modifier values
Example: If security='devel', include development tools
6. FLAGS: Boolean on/off switches
Example: hardware_support=True → ingredients/hardware-detection.cfg
The 'seen' set prevents duplicate includes if multiple paths reference
the same ingredient.
Args:
template: The template dictionary for this recipe type
version: Fedora version string for versioned paths
modifiers: Dictionary of user-specified options
Returns:
List of %include directive strings, one per ingredient
"""
includes = []
seen = set() # Track which ingredients we've already added
# Add version to modifiers so templates can reference it
modifiers = modifiers.copy()
modifiers['version'] = version
# === 1. REQUIRED INGREDIENTS ===
# These are always included, regardless of user options
# The template uses nested dict structure: required[section][value] = path or [paths]
# For each section, use either:
# - A modifier value that overrides the default
# - The default value from the first/only key in the section
for section_name, section_config in template.get('required', {}).items():
if isinstance(section_config, dict):
# Find the value to use for this section
# Check modifiers first, then use default
default_value = None
override_value = None
# Get the default value (first key in dict, or only key)
keys = list(section_config.keys())
if keys:
default_value = keys[0]
# Check if any modifier overrides this section
for mod_key, mod_value in modifiers.items():
mod_key_normalized = mod_key.replace("_", "-")
if mod_key_normalized == section_name and isinstance(mod_value, str):
if mod_value in section_config:
override_value = mod_value
break
# Use override if available, otherwise use default
value_to_use = override_value if override_value else default_value
if value_to_use and value_to_use in section_config:
fragment_path = section_config[value_to_use]
if isinstance(fragment_path, list):
for fp in fragment_path:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif fragment_path and fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
# === 2. MODIFIER INGREDIENTS ===
# Process user-specified options like desktop, storage, security
for mod_key, mod_value in modifiers.items():
# Normalize key: convert underscores to hyphens for template lookup
# This allows Python-style snake_case (guest_agents) to match
# YAML-style kebab-case (guest-agents)
mod_key_normalized = mod_key.replace("_", "-")
if mod_key_normalized in template.get("modifiers", {}):
mod_key_to_use = mod_key_normalized
elif mod_key in template.get("modifiers", {}):
mod_key_to_use = mod_key
else:
# This modifier doesn't have a mapping in the template, skip it
continue
mod_config = template["modifiers"][mod_key_to_use]
# Handle nested dict modifiers with string values
# Example: mod_config = {'gnome': 'ingredients/gnome.cfg', 'labwc': 'ingredients/labwc.cfg'}
# mod_value = 'gnome'
# Result: include ingredients/gnome.cfg
if isinstance(mod_config, dict) and isinstance(mod_value, str):
if mod_value in mod_config:
fragment_path = mod_config[mod_value]
if isinstance(fragment_path, list):
# Some modifiers map to multiple ingredients
for fp in fragment_path:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif fragment_path and fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
# Handle list modifiers
# Example: User passes multiple values like hypervisor_type=['kvm', 'xen']
elif isinstance(mod_config, dict) and isinstance(mod_value, list):
for item in mod_value:
if item in mod_config:
fragment_path = mod_config[item]
if isinstance(fragment_path, list):
for fp in fragment_path:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif fragment_path and fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
# === 3. OPTIONAL INGREDIENTS ===
# Included based on modifier presence and value
# More flexible than modifiers - can handle complex nested structures
for opt_key, opt_config in template.get("optional", {}).items():
if opt_key in modifiers:
value = modifiers[opt_key]
# Case 1: opt_config is nested dict, value is string/int
# Example: opt_config = {'gnome': 'ingredients/gnome.cfg'}
# value = 'gnome'
if isinstance(opt_config, dict) and not isinstance(value, (dict, list)):
if value in opt_config:
fragment_path = opt_config[value]
if isinstance(fragment_path, list):
for fp in fragment_path:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif fragment_path and fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
# Case 2: opt_config is nested dict, value is dict
# Example: value = {'kvm': True, 'xen': False}
# Include ingredients for keys that are present
elif isinstance(opt_config, dict) and isinstance(value, dict):
for nested_key in value:
if nested_key in opt_config:
nested_value = opt_config[nested_key]
if isinstance(nested_value, list):
for fp in nested_value:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif nested_value is not None and nested_value not in seen:
includes.append(f"%include {nested_value}")
seen.add(nested_value)
# Case 3: opt_config is nested dict, value is boolean True
# Include ALL options when value is True
elif isinstance(opt_config, dict) and isinstance(value, bool) and value:
for nested_key, nested_value in opt_config.items():
if isinstance(nested_value, list):
for fp in nested_value:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif nested_value is not None and nested_value not in seen:
includes.append(f"%include {nested_value}")
seen.add(nested_value)
# Case 4: opt_config is list, value is boolean True
# Include all items in the list
elif isinstance(opt_config, list) and value is True:
for fragment_path in opt_config:
if fragment_path is not None and fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
# === 4. VERSIONED INGREDIENTS ===
# Paths that change based on Fedora version
# Example: 'repo': 'ingredients/repo/f{version}.cfg'
# Becomes: ingredients/repo/f43.cfg or ingredients/repo/frawhide.cfg
versioned = template.get('versioned', {})
for fragment_path in versioned.values():
# Substitute {version} placeholder with actual version
resolved_path = fragment_path.format(version=version)
if resolved_path not in seen:
includes.append(f"%include {resolved_path}")
seen.add(resolved_path)
# === 5. CONDITIONAL INGREDIENTS ===
# Similar to optional, but with different template structure
# Used for more complex conditional logic
conditional = template.get('conditional', {})
for mod_key, mod_config in conditional.items():
# Support both hyphenated and underscored key names
if mod_key.replace('-', '_') in modifiers:
value = modifiers[mod_key.replace('-', '_')]
elif mod_key in modifiers:
value = modifiers[mod_key]
else:
# This modifier wasn't provided, skip
continue
# Same four cases as optional section above
if isinstance(mod_config, dict) and not isinstance(value, (dict, list)):
if value in mod_config:
fragment_path = mod_config[value]
if isinstance(fragment_path, list):
for fp in fragment_path:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif fragment_path and fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
elif isinstance(mod_config, dict) and isinstance(value, dict):
for nested_key in value:
if nested_key in mod_config:
nested_value = mod_config[nested_key]
if isinstance(nested_value, list):
for fp in nested_value:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif nested_value is not None and nested_value not in seen:
includes.append(f"%include {nested_value}")
seen.add(nested_value)
elif isinstance(mod_config, dict) and isinstance(value, bool) and value:
for nested_key, nested_value in mod_config.items():
if isinstance(nested_value, list):
for fp in nested_value:
if fp is not None and fp not in seen:
includes.append(f"%include {fp}")
seen.add(fp)
elif nested_value is not None and nested_value not in seen:
includes.append(f"%include {nested_value}")
seen.add(nested_value)
elif isinstance(mod_config, list) and isinstance(value, bool) and value:
for fragment_path in mod_config:
if fragment_path is not None and fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
# === 6. FLAG INGREDIENTS ===
# Simple boolean on/off switches
# Example: hardware_support=True → include hardware detection
# Only includes when value is exactly True (not False or None)
for mod_key, mod_value in modifiers.items():
mod_key_normalized = mod_key.replace('_', '-')
if mod_key_normalized in template.get('flags', {}):
fragment_path = template['flags'][mod_key_normalized]
if mod_value is True:
if fragment_path not in seen:
includes.append(f"%include {fragment_path}")
seen.add(fragment_path)
return includes
def _get_modifier(self, modifiers: dict, key: str, default=None):
"""Get modifier value, checking both hyphenated and underscored versions.
This helper method handles the naming convention mismatch between:
- Python code: uses snake_case (e.g., guest_agents)
- YAML templates: use kebab-case (e.g., guest-agents)
It tries both versions so users can pass modifiers using either convention.
Args:
modifiers: Dictionary of modifier values
key: The key to look up (will try both this and the hyphenated version)
default: Value to return if key is not found
Returns:
The modifier value if found, otherwise the default
"""
if key in modifiers:
return modifiers[key]
alt_key = key.replace('_', '-')
if alt_key in modifiers:
return modifiers[alt_key]
return default
def generate_filename(self, version: str, **modifiers) -> str:
"""Generate recipe filename from parameters.
Creates a descriptive filename that encodes the recipe's configuration.
This allows users to identify what a recipe does just from its name.
Filename format (using Approach A - primary modifier first):
{primary_modifier}-{other_modifiers}-{version}.cfg
Examples:
- gnome_43.cfg (desktop=gnome is primary modifier)
- encrypted_43.cfg (storage=encrypted is primary modifier)
- server_43.cfg (initial_setup=server with no desktop)
- gnome_encrypted_43.cfg (when multiple modifiers are set)
The method prioritizes modifiers to create intuitive filenames:
- If `desktop` is present, it becomes the primary modifier
- Otherwise, `storage` or `initial_setup` can be primary
- `version` is always included at the end
Args:
version: Fedora version (e.g., '43' or 'rawhide')
**modifiers: All the modifier values that affect the recipe
Returns:
Filename string ending in .cfg
"""
# Build base parts - start with version (required)
parts = []
# Determine primary modifier (Approach A)
# If desktop is present, use it as primary modifier
desktop = self._get_modifier(modifiers, 'desktop')
if desktop:
parts.append(desktop)
# Add guest_agents suffix (for both True and False)
# Distinguishes between virtual machines and bare metal installs
guest_agents = self._get_modifier(modifiers, 'guest_agents')
if guest_agents is True:
parts.append('virtual')
elif guest_agents is False:
parts.append('bare-metal')
# Add hypervisor indicator if present
if modifiers.get('hypervisor'):
if modifiers.get('hypervisor') in ['base', 'desktop']:
if modifiers.get('desktop'):
parts.append('hypervisor-desktop')
else:
parts.append('hypervisor')
# Add hypervisor_type suffix
# For hypervisors, include the type (kvm, xen, etc.)
if modifiers.get('hypervisor_type'):
ht = modifiers.get('hypervisor_type')
if isinstance(ht, list):
# Multiple hypervisor types
for h in ht:
if h:
parts.append(h)
elif ht:
# Single hypervisor type
parts.append(ht)
# Add storage suffix (encrypted only, since standard is default)
# Standard storage is default, encrypted gets noted
storage = self._get_modifier(modifiers, 'storage')
if storage == 'encrypted':
parts.append('encrypted')
# Add hardware_support suffix (for True only)
# Hardware support detection is optional
hardware_support = self._get_modifier(modifiers, 'hardware_support')
if hardware_support is True:
parts.append('hardware-support')
# Add initial_setup suffix (non-server values)
# Server is default, other setup types get noted
initial_setup = self._get_modifier(modifiers, 'initial_setup')
if initial_setup and initial_setup != 'server':
parts.append(f'{initial_setup}-setup')
# Add bootloader suffix (systemd-boot only)
# Default bootloader doesn't get noted
bootloader = self._get_modifier(modifiers, 'bootloader')
if bootloader == 'systemd-boot':
parts.append('systemd-boot')
# Add version - always included at the end
parts.append(str(version))
# Join all parts with underscores and add .cfg extension
return '_'.join(parts) + '.cfg'
def expand_variants(self, variants: List[Dict]) -> List[Dict]:
"""Expand variants with list values into individual variants.
This method enables batch generation by converting compact manifest
entries with list values into all possible combinations.
Example input:
[
{
'version': ['43', 'rawhide'],
'storage': ['standard', 'encrypted'],
'desktop': 'gnome'
}
]
Example output (cartesian product = 2×2×1 = 4 variants):
[
{'version': '43', 'storage': 'standard', 'desktop': 'gnome'},
{'version': '43', 'storage': 'encrypted', 'desktop': 'gnome'},
{'version': 'rawhide', 'storage': 'standard', 'desktop': 'gnome'},
{'version': 'rawhide', 'storage': 'encrypted', 'desktop': 'gnome'}
]
This uses itertools.product to generate the cartesian product of all
list-valued keys, while preserving scalar values across all combinations.
Args:
variants: List of variant dictionaries, where some values may be lists
Returns:
Expanded list where each variant has only scalar (non-list) values
"""
from itertools import product as itertools_product
expanded = []
for variant in variants:
# Separate list-valued keys from scalar keys
list_keys = {}
scalar_keys = {}
for key, value in variant.items():
if isinstance(value, list):
list_keys[key] = value
else:
scalar_keys[key] = value
if not list_keys:
# No lists to expand, keep as-is
expanded.append(variant)
continue
# Get cartesian product of all list values
keys = list(list_keys.keys())
values_product = itertools_product(*[list_keys[k] for k in keys])
# Create a new variant for each combination
for combo in values_product:
new_variant = scalar_keys.copy()
for i, key in enumerate(keys):
new_variant[key] = combo[i]
expanded.append(new_variant)
return expanded
# === VALIDATION METHODS ===
# These are convenience wrappers that delegate to the validators module.
# They provide a unified API so callers can validate through the generator.
def validate_template(self, template: Dict) -> List[str]:
"""Validate template structure and fragment existence.
Checks that:
- Required keys are present (description, required)
- All referenced ingredient files actually exist on disk
- Versioned, conditional, and flag paths are valid
Args:
template: Template dictionary to validate
Returns:
List of validation error strings (empty if valid)
"""
validator = TemplateValidator(self.project_root)
return validator.validate(template)
def validate_manifest(self, manifest: Dict) -> List[str]:
"""Validate manifest structure.
Checks that the manifest has the required 'recipes' key and that
each recipe has required fields (name, variants with version).
Args:
manifest: Manifest dictionary to validate
Returns:
List of validation error strings (empty if valid)
"""
return validate_manifest(manifest)
def validate_recipe(self, content: str) -> List[str]:
"""Validate recipe content.
Checks that:
- No duplicate %include directives
- All referenced ingredient files exist
Args:
content: Recipe content string to validate
Returns:
List of validation error strings (empty if valid)
"""
validator = ContentValidator(self.project_root)
return validator.validate(content)
def validate_recipe_semantic(self, content: str, version: str) -> List[str]:
"""Validate recipe using pykickstart parser.
Uses the official pykickstart library to parse the recipe and check
for syntax errors, invalid directives, or semantic issues.
Args:
content: Recipe content string to validate
version: Fedora version for version-specific validation rules
Returns:
List of validation error strings (empty if valid)
"""
validator = SemanticValidator()
return validator.validate(content, version)
def get_ksversion(self, version: str) -> Optional[str]:
"""Map Phyllome OS version to pykickstart version string.
Pykickstart uses Fedora version naming (F42, F43, etc.).
This method converts Phyllome OS versions to the corresponding
kickstart version string.
Args:
version: Phyllome OS version (e.g., '43' or 'rawhide')
Returns:
Pykickstart version string (e.g., 'F42' for version 43)
or None for rawhide (uses latest development version)
"""
return SemanticValidator().get_ksversion(version)
def extract_version(self, content: str, filename: str) -> Optional[str]:
"""Extract Fedora version from recipe content or filename.
Uses multiple heuristics to determine which Fedora version a recipe
targets:
1. Check filename for version patterns (e.g., _43_, -rawhide.cfg)
2. Check content for version-specific repository paths
Args:
content: Recipe content string
filename: Recipe filename
Returns:
Version string ('43' or 'rawhide') or None if undetermined
"""
import re
# Try to extract from filename first
filename_match = re.search(r'(?:_|-)(43|rawhide)(?:_|-|.cfg|.yaml|$)', filename)
if filename_match:
return filename_match.group(1)
# Fall back to content inspection
for line in content.split('\n'):
if 'core-fedora-repo-43' in line:
return '43'
elif 'core-fedora-repo-rawhide' in line:
return 'rawhide'
if 'generic-43/repo' in line:
return '43'
elif 'generic-rawhide/repo' in line:
return 'rawhide'
return None
def extract_version_from_file(self, recipe_path: str, filename: str) -> Optional[str]:
"""Extract version from recipe file.
Convenience wrapper that reads the file and delegates to extract_version.
Args:
recipe_path: Path to the recipe file
filename: Filename (used for pattern matching)
Returns:
Version string or None
"""
content = Path(recipe_path).read_text(encoding='utf-8')
return self.extract_version(content, filename)
def validate_recipe_content(self, recipe_path: str) -> List[str]:
"""Validate recipe content from file path.
Reads a recipe file and validates its content for ingredient existence
and duplicate includes.
Args:
recipe_path: Path to the recipe file
Returns:
List of validation error strings
"""
content = Path(recipe_path).read_text(encoding='utf-8')
return self.validate_recipe(content)
def validate_recipe_semantic_from_file(self, recipe_path: str, version: str) -> List[str]:
"""Validate recipe from file path using pykickstart.
Reads a recipe file and validates it with the pykickstart parser.
Args:
recipe_path: Path to the recipe file
version: Fedora version for validation rules
Returns:
List of validation error strings
"""
content = Path(recipe_path).read_text(encoding='utf-8')
return self.validate_recipe_semantic(content, version)
+1 -1
View File
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -9,7 +9,7 @@
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -9,7 +9,7 @@
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include bootloader/systemd-boot.ks
%include storage/encrypted.ks
%include core/locale.ks
%include core/services.ks
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -19,6 +19,7 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
+1 -1
View File
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -9,7 +9,7 @@
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,26 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -0,0 +1,25 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
@@ -9,7 +9,7 @@
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include bootloader/systemd-boot.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
@@ -21,4 +21,4 @@
%include initial-setup/server/config.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include desktop/gnome/post-scripts.ks
@@ -19,9 +19,10 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/virtual-machine-manager/packages.ks
%include packages/virtual-machine-manager/post-scripts.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include hypervisor/amdcpu.ks
%include packages/virtual-machine-manager/packages.ks
%include packages/virtual-machine-manager/post-scripts.ks
%include hypervisor/amdcpu.ks
@@ -0,0 +1,28 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
%include desktop/gnome/config.ks
%include desktop/gnome/packages.ks
%include desktop/gnome/post-scripts.ks
%include packages/virtual-machine-manager/packages.ks
%include packages/virtual-machine-manager/post-scripts.ks
%include hypervisor/intelcpu.ks
@@ -18,4 +18,5 @@
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
@@ -18,4 +18,5 @@
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include initial-setup/server/config.ks
%include guest-agents/base.ks
@@ -18,4 +18,5 @@
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
@@ -0,0 +1,22 @@
# __ ____ ____ _____
# ____ / /_ __ __/ / /___ ____ ___ ___ / __ \/ ___/
# / __ \/ __ \/ / / / / / __ \/ __ `__ \/ _ \ / / / /\__ \
# / /_/ / / / / /_/ / / / /_/ / / / / / / __/ / /_/ /___/ /
# / .___/_/ /_/\__, /_/_/\____/_/ /_/ /_/\___/ \____//____/
# /_/ /____/
# Universal template to generate kickstart recipes for a server, a desktop or a hypervisor system
%include repo/fedora-43-mirrors.ks
%include core/base.ks
%include bootloader/grub.ks
%include storage/standard.ks
%include core/locale.ks
%include core/services.ks
%include core/network.ks
%include packages/core.ks
%include packages/fedora-remix.ks
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
@@ -19,7 +19,8 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include hypervisor/base/packages.ks
%include hypervisor/base/services.ks
%include hypervisor/base/post-scripts.ks
%include hypervisor/amdcpu.ks
%include hypervisor/amdcpu.ks
@@ -19,7 +19,8 @@
%include packages/hand-picked.ks
%include core/security/enabled.ks
%include initial-setup/server/config.ks
%include packages/hardware-support.ks
%include hypervisor/base/packages.ks
%include hypervisor/base/services.ks
%include hypervisor/base/post-scripts.ks
%include hypervisor/intelcpu.ks
%include hypervisor/intelcpu.ks
+1 -1
View File
@@ -25,7 +25,7 @@ recipes:
hardware-support: [true, false]
guest-agents: [true, false]
initial-setup: server
security: ["enabled", "disabled"]
security: enabled
# Server variants
- name: server
-416
View File
@@ -1,416 +0,0 @@
"""Validation logic for recipes and templates.
This module provides three layers of validation for Phyllome OS kickstart recipes:
1. TemplateValidator
- Validates the template YAML structure itself
- Checks that all referenced ingredient files actually exist on disk
- Validates required, versioned, conditional, optional, and flag paths
2. ContentValidator
- Validates the generated recipe content
- Checks for duplicate %include directives
- Verifies all referenced ingredients exist on disk
3. SemanticValidator
- Uses the official pykickstart library to parse recipes
- Checks for syntax errors and invalid kickstart directives
- Validates against Fedora version-specific kickstart rules
All validators return lists of warning/error strings. They don't raise exceptions
for minor issues; instead, they collect and report issues so callers can decide
how to handle them (warn, error, exit, etc.)
The separation allows for:
- Early detection of template issues (TemplateValidator)
- Detection of generation issues (ContentValidator)
- Detection of actual syntax errors (SemanticValidator)
"""
from __future__ import annotations
from pathlib import Path
from typing import Dict, List, Optional
from pykickstart.parser import KickstartParser
from pykickstart.version import makeVersion, DEVEL
class TemplateValidator:
"""Validate template structure and fragment existence.
This validator checks that:
1. Required template keys are present (description, required)
2. All ingredient paths referenced in the template exist on disk
3. The template structure matches expected format
It's typically used:
- During development to catch template errors early
- In CI/CD pipelines to validate templates before use
- Programmatically when loading templates
The validator doesn't check for semantic issues in the ingredients themselves -
it only verifies that they exist and are properly referenced.
"""
def __init__(self, project_root: Path):
"""Initialize the validator with project root path.
Args:
project_root: Path to the phyllomeos project root directory.
All ingredient paths in templates are relative to this.
"""
self.project_root = project_root
def validate(self, template: Dict) -> List[str]:
"""Validate template structure and fragment existence.
This method performs a comprehensive check of the template dictionary:
1. Required Keys Check:
- Verifies 'description' key exists (used in header)
- Verifies 'required' key exists (base ingredients)
2. Required Ingredients Check:
- Iterates through template['required'] nested dict structure
- For each section and value, checks if path(s) are valid
- Checks if the file actually exists
3. Modifier Ingredients Check:
- Checks template['modifiers'] structure
- For each modifier and value, checks referenced files exist
4. Optional Ingredients Check:
- Checks paths in template['optional']
- Verifies referenced files exist on disk
5. Versioned Ingredients Check:
- Checks paths in template['versioned']
- If the path contains {version}, it's deferred to generation time
- Otherwise checks if the resolved file exists
6. Flag Ingredients Check:
- Checks all paths in template['flags']
- Flags are simple boolean on/off switches
Args:
template: The entire template YAML content
Structure: {'name': str, 'description': str, 'required': {...}, ...}
Returns:
List of validation error strings (empty if valid)
Example: ['Missing required key: description', 'Required ingredient not found: ingredients/gnome.cfg']
"""
errors = []
# Check required keys at the template level
required_keys = ['description', 'required']
for key in required_keys:
if key not in template:
errors.append(f"Missing required key: {key}")
# Validate required ingredients exist on disk
for item in template.get('required', []):
if isinstance(item, dict):
# Dict format: {priority: path} or {condition: path}
fragment_path = list(item.values())[0]
else:
# Simple string path
fragment_path = item
# Resolve relative path from project root
full_path = self.project_root / fragment_path
if not full_path.exists():
errors.append(f"Required ingredient not found: {fragment_path}")
# Validate versioned ingredients exist on disk
# These are paths like 'ingredients/repo/f{version}.cfg'
# If the path has {version}, it'll be resolved at generation time
# Otherwise, check if it exists now
for key, fragment_path in template.get('versioned', {}).items():
if '{version}' in fragment_path:
# Will be resolved at generation time
continue
full_path = self.project_root / fragment_path
if not full_path.exists():
errors.append(f"Versioned ingredient not found: {fragment_path}")
# Validate conditional ingredients exist on disk
# Conditional ingredients depend on modifier values
conditional = template.get('conditional', {})
for modifier, modifier_config in conditional.items():
if isinstance(modifier_config, dict):
# Dict format: {'value': 'path'} or {'value': ['path1', 'path2']}
for value, fragment_path in modifier_config.items():
if fragment_path is None:
# None means "don't include anything for this value"
continue
if isinstance(fragment_path, list):
# List of paths (e.g., multiple ingredients for this value)
for fp in fragment_path:
if fp is not None:
full_path = self.project_root / fp
if not full_path.exists():
errors.append(f"Conditional ingredient not found: {fp} (in list for {modifier}={value})")
else:
full_path = self.project_root / fragment_path
if not full_path.exists():
errors.append(f"Conditional ingredient not found: {fragment_path} (for {modifier}={value})")
# Validate flag ingredients exist on disk
# Flags are simple boolean on/off switches
for key, fragment_path in template.get('flags', {}).items():
if fragment_path is None:
continue
full_path = self.project_root / fragment_path
if not full_path.exists():
errors.append(f"Flag ingredient not found: {fragment_path}")
return errors
class ContentValidator:
"""Validate recipe content for ingredient existence and duplicates.
This validator checks the content of a generated recipe file:
1. Duplicate Include Detection:
- Scans for all %include directives
- Tracks which ingredient paths have been seen
- Reports if the same path appears multiple times
- This prevents redundant loading and potential conflicts
2. Ingredient Existence Check:
- For each %include directive, Verifies the referenced file exists
- Uses project_root to resolve relative paths
- Reports missing files so generators can catch issues early
The validator is designed to run on generated recipes, not templates.
It's lighter than TemplateValidator and runs during generation to
catch issues immediately.
"""
def __init__(self, project_root: Path):
"""Initialize the validator with project root path.
Args:
project_root: Path to the phyllomeos project root directory.
All ingredient paths are relative to this.
"""
self.project_root = project_root
def validate(self, content: str) -> List[str]:
"""Validate recipe content for issues.
This method parses the recipe content string and checks for:
1. Duplicate Includes:
- Extracts all %include directives
- Tracks seen paths in a set
- Reports if a path appears more than once
- Duplicates are problematic because they slow down generation
and can cause conflicts in the final kickstart file
2. Missing Ingredients:
- For each %include directive, checks if the file exists
- Path is resolved relative to project_root
- Reports missing files that would cause generation to fail
- This catches typos in template paths before runtime
The validation is "best effort" - it doesn't raise exceptions for
minor issues but collects all problems to report them together.
Args:
content: The recipe content string to validate
Contains %include directives and other kickstart code
Returns:
List of validation warning strings (empty if valid)
Example: ['Duplicate include: ingredients/gnome.cfg', 'Missing ingredient: ingredients/unknown.cfg']
"""
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:
# Malformed include line, skip
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]
ingredient_path = self.project_root / path
if not ingredient_path.exists():
issues.append(f"Missing ingredient: {path}")
return issues
class SemanticValidator:
"""Validate recipe using pykickstart parser.
This is the most thorough validator - it actually parses the recipe
as a kickstart file and checks for syntax errors and semantic issues.
It uses the pykickstart library, which is the same library Anaconda uses
to parse kickstart files. This means it catches:
- Syntax errors in kickstart directives
- Invalid options or values
- Incompatible directives for the target Fedora version
- Other structural issues
The validator is lenient about include resolution issues (file not found)
because those are expected - the actual ingredient files are included
during the installation, not at generation time.
Version Mapping:
- '43' -> pykickstart F42 (Phyllome OS 43 is based on Fedora 42)
- 'rawhide' -> DEVEL (development version, uses latest rules)
- This accounts for the fact that Phyllome OS lags Fedora by one version
"""
def validate(self, content: str, version: str) -> List[str]:
"""Validate recipe using pykickstart parser.
This method attempts to parse the recipe content as a kickstart file
using the pykickstart library. It:
1. Maps Phyllome OS version to pykickstart version string
2. Creates a KickstartParser with the appropriate version
3. Attempts to parse the content
4. Catches and reports any parsing errors
The parser is configured to be lenient about missing includes
(file not found errors) because those are expected - the ingredients
are resolved at installation time, not generation time.
Args:
content: The recipe content string to validate
version: Phyllome OS version string ('43' or 'rawhide')
Determines which kickstart version rules to apply
Returns:
List of validation error strings (empty if valid)
Only reports actual validation errors, not file missing errors
"""
issues = []
try:
# Get pykickstart version string
ks_version_str = self.get_ksversion(version)
if ks_version_str:
# Create version-specific parser
ks_version = makeVersion(ks_version_str)
else:
# Use development version for rawhide
ks_version = makeVersion(DEVEL)
# Parse the content
parser = KickstartParser(ks_version)
parser.readKickstartFromString(content)
except Exception as e:
# Only report actual validation errors, not include resolution issues
err_str = str(e)
if 'Unable to open input kickstart file' not in err_str:
# This is a real validation error, not a missing include
issues.append(f"Validation error: {err_str}")
return issues
def get_ksversion(self, version: str) -> Optional[str]:
"""Map Phyllome OS version to pykickstart version string.
This helper method converts Phyllome OS version strings to the
corresponding pykickstart version strings.
Pykickstart uses Fedora version naming:
- F42, F43, etc. for stable releases
- DEVEL for development versions
Phyllome OS version mapping:
- Phyllome OS 43 is based on Fedora 42, so use F42
- Phyllome OS 44 is based on Fedora 43, so use F43
- The pattern: F(Phyllome_OS_version - 1)
For rawhide, we use None which tells pykickstart to use the
latest development version.
Args:
version: Phyllome OS version string ('43' or 'rawhide')
Returns:
Pykickstart version string ('F42', 'F43', etc.) or None for rawhide
"""
if version == 'rawhide':
return None
else:
# Phyllome OS 43 -> Fedora 42 -> F42
return f'F{int(version) - 1}'
def validate_manifest(manifest: Dict) -> List[str]:
"""Validate manifest structure.
This function validates the high-level structure of a manifest YAML file.
It checks that the manifest has the required sections and that each recipe
configuration has the necessary fields.
The manifest structure:
recipes:
- name: virtual-desktop
variants:
- version: 43
desktop: gnome
- version: rawhide
storage: encrypted
Validation checks:
1. 'recipes' key exists at top level
2. Each recipe config has 'name' key
3. Each recipe config has 'variants' key
4. Each variant has 'version' key
This is a schema-level validation that catches structural errors before
trying to process the manifest. It's less detailed than template validation
but catches the most obvious problems early.
Args:
manifest: The manifest dictionary to validate
Returns:
List of validation error strings (empty if valid)
Example: ["Manifest missing 'recipes' key", "Recipe 'virtual-desktop' variant missing 'version'"]
"""
errors = []
# Check for required top-level key
if 'recipes' not in manifest:
errors.append("Manifest missing 'recipes' key")
return errors # Can't continue without recipes
# Validate each recipe configuration
for recipe_config in manifest.get('recipes', []):
if 'name' not in recipe_config:
errors.append("Recipe config missing 'name' key")
if 'variants' not in recipe_config:
# Recipe doesn't have variants, can't validate further
errors.append(f"Recipe '{recipe_config.get('name', 'unnamed')}' "
"missing 'variants' key")
else:
# Each variant must have version
for variant in recipe_config.get('variants', []):
if 'version' not in variant:
errors.append(f"Recipe '{recipe_config['name']}' variant missing 'version'")
return errors