xolite-ce
XO Lite rebuilt for XCP-hl - selectable XOA deploy images, plus the RPM build pipeline.
Repository: Vagrantin/xolite-ce · Language: TypeScript / Vue 3 (patch) · RPM spec · License: AGPL-3.0
What is XO Lite?
XO Lite is the lightweight single-page management application that ships bundled with every XCP-ng host. It runs entirely in the browser, served directly from the host, and is implemented as a Vue 3 / TypeScript / Vite SPA.
On a standard XCP-ng host, XO Lite’s “Deploy XOA” screen downloads and imports one
hardcoded Xen Orchestra image. XCP-hl replaces that screen with an “XOA Image URL”
selector offering four sources: XOA-hl (default), the official Vates image, Ronivay’s
image, or a custom XVA URL, plus a “Verify if ssl certificate is valid” toggle so
xoa-proxy can accept self-signed certificates upstream.
The patch
Patching uses the Rust xoa-deploy-patcher tool, which applies pattern-based
edits to xoa-deploy.vue at build time. It also applies patches/en-hl.json
(HL locale strings) and patches/xolite-loader.html (replacement loader that
drops the lite.xen-orchestra.com remote-loading fallback).
The modified “Deploy XOA” screen gains an “XOA Image URL” selector with four sources:
- XOA-hl (default): Xen Orchestra built from source for XCP-hl
- Vates image: the official appliance
- Ronivay’s image: a community XO built from source
- Custom URL: any XVA, plain or gzipped, over HTTP or HTTPS
A “Verify if ssl certificate is valid” toggle lets xoa-proxy accept
self-signed certificates on the upstream image server.
Build pipeline
Overview
1. Read XO_VERSION from the RPM in the upstream XCP-ng ISO
2. Clone vatesfr/xen-orchestra at the matching release tag
3. Apply patches/community-xoa-deploy.patch
4. Install dependencies with Yarn (Corepack)
5. Build XO Lite: yarn build:xo-lite
6. Assemble RPM source tarball
7. rpmbuild -ba SPECS/xo-lite-community.spec
8. rpmsign with the RPM signing subkey (GPG_PRIVATE_KEY + GPG_PASSPHRASE)
9. Publish RPM + xcp-ng-ce-public.asc as GitHub Release assetsVersion detection
The target XO Lite version is read from the RPM already on the upstream XCP-ng ISO, not hardcoded:
XO_VERSION=$(rpm -qp --qf '%{VERSION}' xo-lite-*.rpm)This ensures the community RPM always matches the upstream version, making it a drop-in replacement.
Tarball structure
The source tarball passed to rpmbuild has this layout:
xo-lite-{VERSION}/
├── dist/ ← compiled Vite output
├── CHANGELOG.md
├── LICENSE
└── xolite.html ← renamed from scripts/xolite-loader.htmlThe xolite.html filename is required, this is the entry point served by
the XCP-ng host to load XO Lite in the browser.
RPM spec
SPECS/xo-lite-community.spec defines:
Name: xo-lite-communityVersion: %{XO_VERSION}(injected at build time)Provides: xo-lite(so it satisfies any dependency on the upstream package)Conflicts: xo-lite(prevents co-installation with the upstream RPM)- File list:
dist/contents +xolite.html
Local development
Prerequisites
- Node.js 20+ and Yarn (enabled via
corepack enable) rpmbuild(rpm-buildpackage on RHEL/CentOS/Fedora)rpmsign(rpm-signpackage)- The community GPG public key imported in your keyring
Workflow
# 1. Clone the repo
git clone https://github.com/Vagrantin/xolite-ce.git
cd xolite-ce
# 2. Clone upstream xen-orchestra at the target tag
XO_VERSION=<version>
git clone --depth 1 --branch v${XO_VERSION} \
https://github.com/vatesfr/xen-orchestra.git upstream
# 3. Apply the community patch
cd upstream
git am ../patches/community-xoa-deploy.patch
cd ..
# 4. Install dependencies
cd upstream
corepack enable
yarn install
cd ..
# 5. Build XO Lite
cd upstream
yarn build:xo-lite
cd ..
# 6. Test the UI
scp -r lite/dist/ xcp-ng-host:/opt/xensource/www/Updating the patch for a new upstream version
# In a fresh upstream clone, make the changes manually
# then generate a new patch:
git diff HEAD > ../patches/community-xoa-deploy.patch
# or using format-patch for a clean commit:
git format-patch HEAD~1 -o ../patches/GPG signing
The xo-lite-community RPM is signed with the RPM signing subkey of the
XCP-hl keypair. The same subkey is also used to sign the xoa-proxy RPM:
there is one shared subkey for all community RPMs.
The project publishes its shared public key
at the production site root. Verify the master fingerprint before importing it.
The commands below require an RPM implementation that supports signing subkeys.
XCP-ng 8.3 Dom0 uses older RPM 4.11; installed hosts instead validate signed
repository metadata with repo_gpgcheck=1. Keep the repository settings in
Updates unchanged.
To verify the RPM locally:
curl -fLO https://vagrantin.github.io/xcp-hl/xcp-ng-ce-public.asc
gpg --show-keys --with-fingerprint xcp-ng-ce-public.asc
# 2F59 1DB9 D2C1 28C4 C3D9 63F4 6DA0 0DCA 5BBA 215A
rpm --import xcp-ng-ce-public.asc
rpm --checksig xo-lite-ce-*.rpmCI workflow (GitHub Actions)
The workflow triggers on push to main.
Key steps:
- name: Detect XO version
run: echo "XO_VERSION=$(rpm -qp --qf '%{VERSION}' ...)" >> $GITHUB_ENV
- name: Clone upstream at tag
run: git clone --depth 1 --branch v${{ env.XO_VERSION }} ...
- name: Apply patch
run: git am patches/community-xoa-deploy.patch
- name: Build XO Lite
run: |
corepack enable
yarn install
yarn build:xo-lite
- name: Build RPM
run: rpmbuild -ba SPECS/xo-lite-community.spec
- name: Sign RPM
run: |
echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --import
echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --passphrase-fd 0 --batch \
--pinentry-mode loopback --yes --armor
rpm --addsign RPMS/x86_64/xo-lite-community-*.rpm
- name: Publish release
uses: softprops/action-gh-release@v1
with:
files: |
RPMS/x86_64/xo-lite-community-*.rpm
xcp-ng-ce-public.ascContributing
To report a problem or suggest a change, open an issue on Vagrantin/xcp-hl.