Skip to content
DocumentationComponents

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

LayerTechnology
Hypervisor baseXCP-ng 8.3 (Xen 4.17, Linux 4.19 Dom0)
XO Lite UIVue 3 · TypeScript · Vite · Pinia (@xen-orchestra/lite)
XO Lite buildYarn (Corepack) · yarn build:xo-lite
RPM packagingrpmbuild, rpmsign, createrepo_c
ISO assemblycreate-install-image (XCP-ng toolchain, master branch)
ISO toolingmksquashfs, xorriso, isohybrid, implantisomd5
XOA-hl buildNode.js 24 · Yarn workspaces · AlmaLinux 9 container
XVA image buildPacker · ddelnano/xenserver plugin · Kickstart
Build environmentDocker (xcp-ng-build-env:8.3)
Proxy serverRust · hyper · tokio · tokio_util::io::ReaderStream
CI/CDGitHub Actions
SigningGPG: 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 deploys

Design 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

PropertyValue
Key UIDXCP-ng Community Edition (Master signing key) (as shown by gpg --list-keys)
Master key fingerprint2F59 1DB9 D2C1 28C4 C3D9 63F4 6DA0 0DCA 5BBA 215A
Publishedkeys.openpgp.org
Emailxcp-ng-ce.lid530@passmail.com
Public key filexcp-ng-ce-public.asc

Subkey roles

SubkeyUsed for
RPM signing subkeyxo-lite-community-*.rpm and xoa-proxy-*.rpm
ISO signing subkeyxcp-ng-8.3-ceN.iso.sha256.asc (detached signature over the ISO checksum file)

Detailed component docs

PageDescription
xoa-proxyRust HTTP/gzip proxy for XVA delivery
xolite-ceXO Lite patch, RPM spec, build pipeline
xcp-ng-ce-isoISO assembly, toolchain, CI workflow
xoa-hlpatched Xen Orchestra (XOA-hl), built and packaged as an RPM
build-xoa-hlPacker pipeline building the XOA XVA image on XCP-ng