Build cloud-ready VM templates optimized for the Eryph virtualization platform — published to the Eryph genepool as base catlets that users inherit from.
This repository produces base VM templates in two complementary flows:
- Packer for OS installers that need an answer-file install (Windows, Oracle Linux). Boots an ISO, drives unattended setup, runs Chef/provisioning, then
catletlify.ps1post-processes the VM for Eryph. - cloud-image-customize for distros that publish ready-to-go cloud images (Ubuntu, AlmaLinux). Downloads the upstream cloud image, applies offline customizations via
virt-customize, and emits both a Hyper-V variant (sda.vhdx) and a KVM/qcow2 variant (sda.qcow2) from one run.
All Windows images use eryph-guest-services (EGS) instead of cloudbase-init; Linux images use cloud-init plus EGS.
- Cloud-ready: EGS + cloud-init pre-configured so Eryph's fodder system works on first boot.
- Optimized for Eryph: Linux-style device naming (sda/eth0), processor migration compatibility, metadata for
eryph-packer. - Two output formats: every Linux cloud-image build produces both Hyper-V (vhdx) and KVM (qcow2) artifacts.
- Rebuild paths:
repack.ps1(Packer flow) andbuild-cloud.ps1 -SourceImage(cloud-image flow) both let you re-process an existing image without going through a full installer. - Wide OS support: Ubuntu LTS, AlmaLinux 8/9/10, Oracle Linux 8/9/10, Windows Server 2016–2025, Windows 10/11.
- Windows with Hyper-V enabled (for any Packer build, and for running the Linux cloud-image flow remotely against a build catlet).
- PowerShell 7.4+.
- Sufficient disk space (~50 GB per template).
- Internet access for ISO and cloud-image downloads.
- Cloud-image flow only: either a Linux host with
libguestfs-tools+qemu-utils, or an Eryph build catlet (see Build catlet for cloud-image flow).
.\list.ps1 # all templates
.\list.ps1 -Filter ubuntu* # filter# Build a specific template (flow is auto-selected from build.json)
.\build.ps1 -Filter "ubuntu-22.04"
# Build all templates of one method
.\build.ps1 -Method packer
.\build.ps1 -Method libvirt
# Build everything
.\build.ps1build.ps1 reads build.json, which is grouped by build method then OS type, and dispatches each template to the right flow (packer → templates/<osType>/build.ps1 + catletlify.ps1; libvirt → templates/linux/build-cloud.ps1).
Built VMs land in builds/<template>-stage1/. For Packer the layout matches what catletlify.ps1 produces (Hyper-V VM + .vhdx); for the cloud-image flow:
builds/<template>-stage1/
├── metadata.json
├── catlet.yaml
├── kvm/amd64/sda.qcow2 # KVM variant (zstd-compressed)
└── hyperv/amd64/sda.vhdx # Hyper-V variant (Ubuntu: linux-azure + walinuxagent)
Both are ready for eryph-packer to pack and publish.
| OS family | Versions | Build method |
|---|---|---|
| Ubuntu | 22.04, 24.04, 25.04, 26.04 | cloud-image-customize |
| AlmaLinux | 8, 9, 10 | cloud-image-customize |
| Oracle Linux | 8, 9, 10 | Packer (installer) |
| Windows Server | 2016, 2019, 2022, 2025 (Std / StdCore / Datacenter) | Packer |
| Windows Desktop | 10 (2004, 20H2), 11 (21H1, 22H2, 24H2, 25H2, 26H2) Enterprise | Packer |
graph TD
A[build.json] --> B[build.ps1]
B -->|packer| C[templates/<osType>/build.ps1]
C --> D[Packer ISO install + Chef]
D --> E[catletlify.ps1]
E --> Z[builds/<template>-stage1/]
B -->|libvirt| F[templates/linux/build-cloud.ps1]
F --> G[build.sh: virt-customize]
G --> Z
- Stage 0: Packer drives an unattended ISO install, applies Chef recipes (Windows) or kickstart provisioning (Oracle), installs EGS, runs sysprep / cloud-init reset, exports the VM.
- Stage 1:
tools/catletlify.ps1renames drives (sda/sdb), renames network adapters (eth0/eth1), enables processor migration compatibility, and emits the metadata JSON used byeryph-packer.
For the KVM variant of Packer-built Linux templates, qemu-img convert produces sda.qcow2 alongside sda.vhdx — the in-disk kernel (linux-azure / RHEL default) works on both Hyper-V and KVM.
A single build.sh does the whole thing offline using libguestfs:
- Fetch upstream cloud image with SHA256 verification (cached by hash).
- Fetch EGS from
releases.dbosoft.eu. - Common pass: family-specific resize/package ops → upload EGS + cloud-init drop-ins → cleanup (machine-id, ssh host keys, cloud-init clean) → package-cache cleanup.
- Sparsify and emit
kvm/amd64/sda.qcow2. - Optional Hyper-V pass on a clone (Ubuntu: install
linux-azure+ walinuxagent, switch to Hyper-V cloud-init datasource), sparsify, emithyperv/amd64/sda.vhdx. - Emit
metadata.json+catlet.yaml.
On a Windows host (no libguestfs), build-cloud.ps1 drives a Linux build catlet over EGS + SSH:
- Starts the build catlet (
hyperv-boxes-buildin projectdefaultby default — defined bytemplates/build-host/catlet.yaml). - Uploads
templates/linux/and any source image to a per-run workdir on the catlet. - Runs
build.shover SSH, streaming output back. - Downloads
builds/<template>-stage1/and the build log.
One-time setup:
New-Catlet -Name hyperv-boxes-build -ProjectName default `
-Config (Get-Content -Raw .\templates\build-host\catlet.yaml)templates/
├── build-host/ # Build catlet definition (cloud-image flow)
├── linux/ # cloud-image-customize flow
│ ├── build-cloud.ps1 # PowerShell driver (Linux native or via build catlet)
│ ├── build.sh # bash orchestrator (libguestfs)
│ ├── lib/ # common.sh + per-family hooks (ubuntu.sh, rhel.sh)
│ └── files/ # cloud-init drop-ins, EGS systemd unit, catlet.yaml
├── rhel-compatible/ # Packer (Oracle Linux)
└── windows/ # Packer (Windows)
├── windows.pkr.hcl
├── win*.pkrvars.hcl # Per-version variables
└── cookbooks/packer/ # Chef recipes (EGS install, sysprep, etc.)
Fork this repo to publish your own base catlets:
- Edit
build.jsonto pick which templates you build. - For Packer templates, adjust
.pkrvars.hclfiles and the Chef recipes undercookbooks/packer/. - For cloud-image templates, edit
templates/linux/lib/<family>.sh(image URL, family-specific virt-customize args) ortemplates/linux/files/(cloud-init drop-ins). - Run
.\build.ps1 -Filter <your-template>to test.
These templates are published to the Eryph genepool under dbosoft:
dbosoft/ubuntu-22.04/latest
dbosoft/almalinux-9/latest
dbosoft/winsrv2022-standard/latest
Inherited via:
parent: dbosoft/ubuntu-22.04/latestEryph requires Linux-style naming for cross-platform consistency. Both flows enforce it:
- Drives:
sda,sdb(notC:/D:) - Network:
eth0,eth1(notEthernet)
hyperv-boxes/
├── build.json # Templates grouped by method
├── build.ps1 # Dispatcher
├── list.ps1 # List templates
├── repack.ps1 # Repack an exported Hyper-V VM (Packer flow)
├── tools/
│ ├── packer.exe # Packer binary
│ ├── catletlify.ps1 # Eryph post-processor (Packer flow)
│ ├── oscdimg.exe # ISO creator for Windows secondary ISOs
│ └── prepare-export-for-repack.ps1
├── templates/ # See "Template Structure" above
├── packer_cache/ # ISO + cloud-image cache (by hash)
└── builds/ # Output: <template>-stage1/
For testing an unreleased EGS build against a Windows catlet image, drop egs-local.zip (top-level bin/egs-service.exe + deps, same layout as the released zip) at:
templates/windows/cookbooks/packer/files/default/egs-local.zip
The packer::eryph Chef recipe prefers this file over the released build at releases.dbosoft.eu. The file is gitignored.
repack.ps1 converts a Hyper-V VM export into an Eryph-ready template — useful for re-packaging customized catlets, manually-configured VMs, or migrating existing infrastructure.
# Basic usage
.\repack.ps1 -ExportPath "C:\VMExports\MyVM" -OSType ubuntu
# Windows with custom credentials
.\repack.ps1 -ExportPath "C:\Exports\WinServer" -OSType windows `
-Username "Administrator" -Password "MyPassword123!"
# Skip non-essential cleanup
.\repack.ps1 -ExportPath "C:\Exports\MyVM" -OSType linux -MinimalCleanup
# Upload result directly to Azure (instead of staying local for eryph)
.\repack.ps1 -ExportPath "C:\Exports\WinServer" -OSType windows `
-UploadToAzure -AzureStorageAccount mystorage -AzureContainerName images| Parameter | Description | Default |
|---|---|---|
-ExportPath |
Path to Hyper-V VM export directory (required) | — |
-OSType |
windows, ubuntu, or linux (required) |
— |
-OutputName |
Custom output name | {OSType}-repack-{timestamp} |
-Username / -Password |
VM admin credentials for cleanup | Administrator / packer |
-SwitchName |
Hyper-V switch | auto-detected external switch |
-MinimalCleanup |
Skip defrag and non-essential cleanup | off |
-VMOverridesPath |
vm-overrides.json for memory/CPU/TPM |
— |
-SkipDiskMerge |
Skip merging differencing VHDX chains | off |
-UploadToAzure + -AzureStorageAccount + -AzureContainerName |
Push the result to Azure Blob Storage | — |
The repack process auto-detects and merges VHDX differencing disk chains. You can also run the merge tool standalone:
.\tools\merge-vhdx-chain.ps1 -ExportPath "C:\VMExports\MyVM" -WhatIf
.\tools\merge-vhdx-chain.ps1 -ExportPath "C:\VMExports\MyVM"build-cloud.ps1 -SourceImage re-runs the customize + cleanup pass against an existing qcow2 or vhdx instead of fetching a fresh upstream image. Use it to:
- Refresh a deployed catlet's disk with the current EGS + cloud-init drop-ins without a full rebuild.
- Turn an externally-built disk into an Eryph base catlet.
# Linux host (libguestfs available)
.\templates\linux\build-cloud.ps1 -Template_name ubuntu-22.04 `
-SourceImage C:\images\my-customized.qcow2
# Windows host — driven via build catlet, uploads the file automatically
.\templates\linux\build-cloud.ps1 -Template_name ubuntu-22.04 `
-SourceImage C:\images\my-customized.vhdx -ConvertVhdxRebuild mode skips upstream fetch, family-specific resize, and the one-shot kernel/GRUB setup; it refreshes EGS + cloud-init drops and re-runs the cleanup pass. metadata.json records build_type: "rebuild" so downstream tooling can tell the artifacts apart.
Built VMs can be tested using the eryph-genes repository:
# In eryph-genes repo
.\test_packed.ps1 -Gene "ubuntu-22.04"- Fork the repository.
- Create a feature branch.
- Test your changes locally (
.\build.ps1 -Filter <template>). - Submit a pull request.
- Eryph — the virtualization platform
- eryph-genes — build/test/publish pipeline
- eryph-packer — gene packaging tool
- eryph-guest-services — in-guest agent (EGS)
MIT — see LICENSE.
- Documentation: Eryph Docs
- Issues: GitHub Issues
- Community: Eryph Discussions
- HashiCorp Packer — installer-based VM automation
- libguestfs (
virt-customize,virt-sparsify) and QEMU — offline image customization - Chef — Windows provisioning recipes
- cloud-init — first-boot configuration