Components
Everything you need to understand, build, and contribute to XCP-hl.
Repository overview
XCP-hl is split across several functional repositories plus this documentation repo.
Vagrantin/xcp-hl ← docs (this site)
│
├── Vagrantin/xolite-ce ← XO Lite patch + RPM build
│ │ publishes signed RPM as GitHub Release artifact
│ │
├─────────│───Vagrantin/xoa-proxy ← Rust HTTP proxy + RPM build
│ │ │ publishes signed RPM as GitHub Release artifact
│ ▼ ▼
├── Vagrantin/xcp-ng-ce-iso ← ISO assembly + ISO GitHub Releases
│ │ downloads RPM from xolite-ce and xoa-proxy, assembles ISO
│
├── Vagrantin/xoa-hl ← XOA-hl: patched Xen Orchestra (RPM + container)
│ ▼
├── Vagrantin/build-xoa-hl ← Packer pipeline → XOA XVA image on XCP-ng
│ │ publishes the XVA as a GitHub Release (xoa-image-* tags)
│Each repo has its own GitHub Actions pipeline. They are loosely coupled:
xolite-ce and xoa-proxy publish versioned RPM artifacts that xcp-ng-ce-iso
fetches by release tag. Neither repo needs to be checked out together for normal
builds. xoa-hl builds the community-patched Xen Orchestra (XOA-hl), and
build-xoa-hl packages it into an XVA image.
Tech stack
| Layer | Technology |
|---|---|
| Hypervisor base | XCP-ng 8.3 (Xen 4.17, Linux 4.19 Dom0) |
| XO Lite UI | Vue 3 · TypeScript · Vite · Pinia (@xen-orchestra/lite) |
| XO Lite build | Yarn (Corepack) · yarn build:xo-lite |
| RPM packaging | rpmbuild, rpmsign, createrepo_c |
| ISO assembly | create-install-image (XCP-ng toolchain, master branch) |
| ISO tooling | mksquashfs, xorriso, isohybrid, implantisomd5 |
| XOA-hl build | Node.js 24 · Yarn workspaces · AlmaLinux 9 container |
| XVA image build | Packer · ddelnano/xenserver plugin · Kickstart |
| Build environment | Docker (xcp-ng-build-env:8.3) |
| Proxy server | Rust · hyper · tokio · tokio_util::io::ReaderStream |
| CI/CD | GitHub Actions |
| Signing | GPG: offline master key + 2 signing subkeys (see below) |
Build pipeline, end to end
1. xolite-ce CI (GitHub Actions)
├── Clone vatesfr/xen-orchestra at the tag pinned in UPSTREAM_TAG
│ (currently xo-lite-v0.21.0, bumped deliberately, not automatically)
├── Apply patches/community-xoa-deploy.patch
├── yarn build:xo-lite
├── rpmbuild → xo-lite-community-<VERSION>.rpm
├── rpmsign with RPM signing subkey (GPG_PRIVATE_KEY + GPG_PASSPHRASE)
└── Publish signed RPM as GitHub Release asset (public key on
keys.openpgp.org; import steps in the release notes)
2. xoa-proxy CI (GitHub Actions)
├── Install musl toolchain (musl-1.2.4, static libc)
├── Install Rust stable via rustup
├── Add x86_64-unknown-linux-musl target
├── cargo build --release --target x86_64-unknown-linux-musl
├── Prepare RPM sources (binary + systemd unit + logrotate config)
├── rpmbuild → xoa-proxy-<VERSION>.rpm
├── rpmsign with RPM signing subkey (GPG_PRIVATE_KEY + GPG_PASSPHRASE)
└── Publish signed RPM as GitHub Release asset (public key on
keys.openpgp.org; import steps in the release notes)
3. xcp-ng-ce-iso CI (GitHub Actions)
├── Download signed RPM from xolite-ce release
├── Download signed RPM from xoa-proxy release
├── Import GPG_PRIVATE_KEY (ISO signing subkey) into runner keyring
├── Export public key from runner keyring → inject into installer chroot
├── Set up community-repo/x86_64/ with createrepo_c
├── Run create-installimg.sh (root): builds install.img (SquashFS)
├── Run create-iso.sh (non-root): assembles ISO
├── isohybrid --uefi (hybrid MBR/GPT stamp)
├── implantisomd5
├── sha256sum → xcp-ng-8.3-ceN.iso.sha256
├── gpg --detach-sign (ISO signing subkey via GPG_PRIVATE_KEY)
└── Publish xcp-ng-8.3-ceN.iso + .iso.sha256 + .iso.sha256.asc as a
Vagrantin/xcp-ng-ce-iso GitHub Release (public key on
keys.openpgp.org; verification steps in the release notes)
4. xoa-hl CI (GitHub Actions, on a v<VERSION>-ceN tag)
├── Shallow-fetch vatesfr/xen-orchestra at the commit pinned in UPSTREAM_XO
│ (currently 5.113.2, the last XO 5.x release, bumped deliberately)
├── Apply patches/*.patch (menu-hide-items, xcp-hl-updates, xoa-hl-update-api)
├── Write xoahl.config.toml + generate self-signed TLS certificate
├── yarn && yarn build (all workspaces), prune, strip devDependencies
├── tar → xoa-hl-<VERSION>.tar.gz (build input only, not published)
├── rpmbuild → xoa-hl-<VERSION>-N.….x86_64.rpm (the whole pre-built XO)
├── Publish the RPM as a v<VERSION>-ceN GitHub Release
└── Republish the 5 newest RPMs as a signed yum repository (appliance updates)
5. build-xoa-hl (Packer, on a real XCP-ng host)
├── Resolve AlmaLinux ISO checksum + latest xoa-hl RPM release URL
├── Generate inst.ks (Kickstart) and almalinux-build.json (Packer template)
├── packer build: install AlmaLinux 9 via Kickstart on the XCP-ng host
├── Provision: xe-guest-utilities, Node 24, xoa-hl RPM, first-boot units
├── Slim the image, blank /etc/machine-id
└── Export XVA (xva_compressed): the appliance XO Lite CE deploysDesign decisions
Three-repo split for the ISO side
This is about the ISO pipeline specifically (xolite-ce, xoa-proxy,
xcp-ng-ce-iso); see the diagram above for how XOA-hl’s own repos fit into
the component overview. Separating each RPM build from the ISO assembly
keeps concerns clean: xolite-ce (UI patch, packaging) and xoa-proxy
(Rust proxy, packaging) can each be iterated on independently without
touching the ISO toolchain, and vice versa. Each publishes a versioned,
signed RPM as a GitHub Release artifact. Those artifacts are then consumed
to build the ISO.
Patch at source level
The XO Lite patch is applied to the Vue/TypeScript source of
DeployXoaView.vue.
GPG signing
XCP-hl uses a single keypair following an offline master + subkeys model. The master key is kept offline and is never used for signing. Two signing subkeys are derived from it, one for both RPMs, one for the ISO.
Key details
| Property | Value |
|---|---|
| Key UID | XCP-ng Community Edition (Master signing key) (as shown by gpg --list-keys) |
| Master key fingerprint | 2F59 1DB9 D2C1 28C4 C3D9 63F4 6DA0 0DCA 5BBA 215A |
| Published | keys.openpgp.org |
xcp-ng-ce.lid530@passmail.com | |
| Public key file | xcp-ng-ce-public.asc |
Subkey roles
| Subkey | Used for |
|---|---|
| RPM signing subkey | xo-lite-community-*.rpm and xoa-proxy-*.rpm |
| ISO signing subkey | xcp-ng-8.3-ceN.iso.sha256.asc (detached signature over the ISO checksum file) |
Detailed component docs
| Page | Description |
|---|---|
| xoa-proxy | Rust HTTP/gzip proxy for XVA delivery |
| xolite-ce | XO Lite patch, RPM spec, build pipeline |
| xcp-ng-ce-iso | ISO assembly, toolchain, CI workflow |
| xoa-hl | patched Xen Orchestra (XOA-hl), built and packaged as an RPM |
| build-xoa-hl | Packer pipeline building the XOA XVA image on XCP-ng |