build-xoa-hl
XCP-ng 上で XOA-HL の VM アプライアンスをビルドし、XO Lite CE が展開する XVA イメージを作る Packer のパイプラインです。
リポジトリ: Vagrantin/build-xoa-hl · 言語:Bash / Packer の JSON / Kickstart · ライセンス:AGPL-3.0
目次
- 目的
- リポジトリの構成
- 事前に必要なもの
- ビルドの入口(scripts/setup-xoa-builder.sh)
- Packer のテンプレート(almalinux-build.json)
- 初回起動時の自動設定
- 出力されるもの
- 自動ビルドとオーケストレーター
- 開発に参加する
目的
このリポジトリは XOA HomeLab Edition の VM アプライアンスをビルドします。 実機の XCP-ng ホスト上で Packer によりインストール・設定した AlmaLinux 9 の VM に、xoa-hl の RPM を入れたものです。 できあがるのは圧縮した XVA イメージで、これが XO Lite CE の展開ボタンが 取り込む成果物になります。
このアプライアンスはビルドの時点では汎用のままです。初回起動時に 1 回だけ 動く 2 つのサービスを持っており、XO Lite が展開するときに XenStore から 設定情報(ネットワーク、管理者の資格情報)を読み取ります。そのため、1 つの イメージをすべての利用者が使えます。
リポジトリの構成
build-xoa-hl/
├── build.config.sample ← インフラ設定のテンプレート(コピーして build.config にする)
├── scripts/
│ ├── setup-xoa-builder.sh ← ビルドの入口:Kickstart と Packer の JSON を生成し、ビルドを実行
│ ├── xoa-first-boot.sh ← VM 内フェーズ 1:XenStore → ネットワーク + 環境ファイル
│ └── xoa-credentials.sh ← VM 内フェーズ 2:xo-cli で XO の管理者の資格情報を設定
├── systemd/
│ ├── xoa-first-boot.service
│ └── xoa-credentials.service
├── bin/ ← 同梱した VMware VDDK のアーカイブ(V2V 対応)
└── artefact/ ← ビルドとデバッグの成果物:ログ、導入済み RPM の一覧、メモ
事前に必要なもの
aptと sudo が使える Linux のビルド用マシン(Linux Mint で開発して います)。セットアップ用のスクリプトが、必要なもの(HashiCorp の apt リポジトリから Packer、Packer プラグインddelnano/xenserver、wget、curl、jq、ufw)を自分で導入します。- 接続できる XCP-ng ホスト(root の資格情報、
Local storageの SR、 名前の付いた VM 用ネットワークが必要)。 - GitHub で公開済みの
xoa-hlのリリース(最新リリースの RPM は自動で解決します)。 build.config。build.config.sampleからコピーし、XCP-ng ホストの IP アドレスと資格情報、ネットワーク名、VM 名と root のパスワード、 AlmaLinux の ISO の URL、xe-guest-utilitiesの RPM の URL を記入します。
build.config には平文の資格情報(XCP-ng の root のパスワード、VM の root のパスワード)が入ります。決してコミットしないでください。git に入れて よいのは build.config.sample だけです。
ビルドの入口(scripts/setup-xoa-builder.sh)
ビルド用マシンで動き、Packer に必要なものをすべて生成します。
build.configを読み込む(存在しない場合は組み込みの既定値を使い ます)。- 必要なものを導入する。 apt のパッケージ、HashiCorp の Packer、
ddelnano/xenserverの Packer プラグインです。 - 8000〜9000/tcp のポートを開ける(ufw)。Packer は内蔵の HTTP サーバーを使い、この範囲のポートで Kickstart のファイルを VM に配信します。
- AlmaLinux の ISO のチェックサムを解決する。 ミラーの BSD 形式の
CHECKSUMファイルを解析し、なければ GNU 形式のSHA256SUMSを使い ます。有効な SHA256 が見つからない場合はビルドを失敗させます (build.configで固定している場合を除きます)。 - xoa-hl の最新の RPM の URL を解決する。
api.github.com/repos/Vagrantin/xoa-hl/releasesを調べ、.rpmの成果物 を持つ最新のリリースを探します。releases/latestを使わないのは、 #22 より前のxoa-image-*のリリース(XVA しか含まない)に当たることがあるためです。 inst.ksを生成する。 Kickstart の応答ファイルです。eth0で DHCP、EXT4 でのパーティション分割(LVM なし)、SELinux とファイア ウォールは無効、パッケージは最小構成。%postで sshd と chrony を 有効にし、epel-release、wget、nc、vimを導入して、xoユーザー(wheelグループ)を作ります。almalinux-build.jsonを生成する。 Packer のテンプレートです (後述)。- ビルドを実行する。
packer validateのあとPACKER_LOG=1 packer build almalinux-build.jsonを実行します。
Packer のテンプレート(almalinux-build.json)
xenserver-iso のビルダーを 1 つだけ使います。Packer は AlmaLinux の ISO を XCP-ng ホストへアップロードし、カーネルのコマンドラインに inst.ks=http://:/inst.ks を指定して VM (メモリー 2 GB、ディスク 10 GB)を起動し、SSH を待ってからプロビジョナーを 実行します。
dnf update -y。- xe-guest-utilities と xe-guest-utilities-xenstore を導入します (RPM の URL は
build.configから)。初回起動時に XenStore へ接続する ために必要です。 - Node.js 24 を導入します(NodeSource)。
- xoa-hl の RPM を導入します。これにより XOA-HL 一式が入ります (
xoa-hlを参照。RPM の%postがリリースのアーカイブを/opt/xoにダウンロードし、redisとxo-serverを有効にします)。 xoa-first-boot.shとxoa-credentials.shを/root/へ、2 つの systemd ユニットを/etc/systemd/system/へアップロードし、両方の ユニットを有効にします。- イメージを軽量化します。 無線 LAN のファームウェア、firewalld、 sssd、NetworkManager の追加分、rsyslog、ドキュメント・man・info の ページ、英語以外のロケールを削除し、
dnf autoremoveとclean allを 実行します。 - 固有の情報を消します。
/etc/machine-idを空にして、展開された 各 VM が自分で作り直すようにします。
ビルダーの重要な設定:format: xva_compressed(XVA を出力)、 keep_vm: never(ビルドした VM を XCP-ng ホストらか削除します。)、そして vm_name(XOA-hl)です。vm_name は Packer が XVA に VM の name-label と して埋め込む値で、アプライアンスを展開したあとに XO Lite が表示する名前に なります。出力ファイル名(<vm_name>.xva)にも使われます。
初回起動時の自動設定
1 回だけ動く 2 つのサービスがイメージに組み込まれています。XO Lite は アプライアンスを展開するときに、設定情報を XenStore (/local/domain/<domid>/vm-data/*)へ書き込みます。
フェーズ 1(xoa-first-boot.service)
ネットワークが立ち上がる前に動きます(Before=network.target、 ConditionPathExists=!/var/lib/xoa-first-boot.done が条件)。 スクリプトの処理は次のとおりです。
xenstore-readでvm-dataのキーを読みます。ip、netmask、gateway、dns、ntp-servers、system-account-xoa-password、およびadmin-accountの JSON(メールアドレスとパスワード)です。- それらを
/etc/xoa-first-boot.env(モード 600)に保存します。 - NetworkManager の設定ファイル (
/etc/NetworkManager/system-connections/xoa-provisioned.nmconnection) を書き出します。IP アドレスが指定されていれば固定 IP、なければ DHCP に します。 - 現地での調査に備えて
/var/log/xoa-first-boot.logに詳しく記録します。
フェーズ 2(xoa-credentials.service)
network-online.target と xo-server.service のあとに 1 回だけ動きます (条件は !/var/lib/xoa-credentials.done)。スクリプトの処理は次の とおりです。
- xo-server が 443 番ポートで応答するのを最大 3 分待ちます。
- システムユーザー
xoの SSH のパスワードを、渡された値に設定します。 - 初期の資格情報を使って
xo-cliをwss://127.0.0.1に登録し、user.changePasswordとuser.setを呼んで、渡された管理者の メールアドレスとパスワードを適用します。 - 終了時に自分自身を削除します(trap を使用)。完了の印を書き、2 つの ユニットとスクリプトを無効にして削除し、機密情報の入った環境ファイルを 消します。
設定情報がない場合やフェーズ 2 が失敗した場合、アプライアンスは初期値の admin@admin.net / admin のままになります。展開後に XO の Web 画面から 変更してください。
出力されるもの
- ビルド用マシンのビルドディレクトリー内の
output-xva/にできる、圧縮 された XVA イメージ。 - ビルドに使った VM 本体(
keep_vm: alwaysにより XCP-ng ホストに残り ます)。 - 自動化されたパイプラインでは、このリポジトリ (
Vagrantin/build-xoa-hl)の GitHub リリース。タグはxoa-image-<日付>-<sha7>で、XOA-hl.xvaを成果物として持ちます。 これが XO Lite の展開ボタンが解決する成果物です。
自動ビルドとオーケストレーター
毎日のパイプラインでは、setup-xoa-builder.sh の代わりに buildorchestration の xoa-vm-agent crate を使います。同じ手順をプログラムから実行し、さらに 次のことを行います。
- リポジトリの HEAD が最後にビルドした SHA と同じなら、ビルドを飛ばします。
- まず
Vagrantin/xoa-hlのbuild-xoa.ymlワークフローをworkflow_dispatchで実行し、RPM のリリースを待ちます。 - 生成した
inst.ksとalmalinux-build.jsonでpacker validateとpacker buildを実行します。 - XVA を、
Vagrantin/build-xoa-hl(このリポジトリ)のxoa-image-<日付>-<sha7>というタグの GitHub リリースとして公開します (<sha7>はイメージのビルド元となったxoa-hlのコミットです。その コミットは別のリポジトリにあるため、タグはmainに作り、元のコミットは リリースの本文に記録します)。イメージのリリースは リリース一覧表に記録します。
#22 までは、イメージは Vagrantin/xoa-hl で公開していました。すでに配布済みの ISO がそれらを解決し 続けられるよう、これらのリリースはそのままにしてあります。そのため、 xoa-hl で RPM を探すツールは、今も xoa-image-* のタグを飛ばす必要が あります。
開発に参加する
参加の方法はまだ正式には決めていません。今のところは XCP-hl リポジトリ で issue を 作ってください。