11 KiB
Ubuntu 24.04 の作業専用 VM
この手順は Arch 開発ホスト上の既存 KVM/QEMU を使い、Ubuntu のカーネル・AppArmor・ユーザー空間で DocView をビルドして試験するためのもの。コンテナーの Ubuntu ユーザー空間だけの試験とは区別する。ホストへパッケージをインストールせず、ホストの既存文書・ホーム・Docker socket を guest に共有しない。
作業先の既定値は build-ubuntu-vm。変更する場合は全コマンドで DOCVIEW_VM_WORK を同じ絶対パスに設定する。private/ の SSH 鍵・seed・known_hosts・serial console は報告物へ含めない。作業先は .gitignore の /build*/ により追跡対象外。4 vCPU、8 GiB RAM、24 GiB の差分ディスクを使い、SSH は 127.0.0.1:22224 のみ。QMP socket も作業先だけに置く。
固定入力
- Ubuntu cloud image:
https://cloud-images.ubuntu.com/noble/20260911/noble-server-cloudimg-amd64.img、625,256,960 bytes、SHA-256612b2c0cc1bc413a6cb8c38fd611794caf0f2b436c50013d8b3794db12ad7354。同じ公式ディレクトリーのSHA256SUMS.gpgを、Canonical 公開 fingerprintD2EB44626FDDC30B513D5BB71A5D6C4C7DB87C81に照合する。 - ホスト補助の qemu-img 11.1.1-2: Arch の公開 package を workspace へだけ展開。固定 SHA-256 とホストに既存の読み取り専用パッケージ鍵リングによる署名検証を行う。既存 QEMU 11.1.1、OVMF
/usr/share/edk2-ovmf/x64/、GnuPG、bsdtar を前提とする。 - ISO 作成の pycdlib 1.14.0: PyPI wheel 213,201 bytes を取得し、公開 SHA-256 を照合して workspace にだけ展開。
- Qt 6.11.2: 公式 basic SDK metadata と 公式 WebEngine extension metadata。basic、WebChannel、Positioning、WebEngine の実 archive 合計 325,996,106 bytes。Qt 公開 SHA-1 sidecar と照合し、各ファイルの SHA-256 も記録する。Qt Creator と debug symbols は取得しない。これらは公式ファイル名で RHEL 9.6 build とされており、Arch パッケージと同一バイナリーではない。
- qpdf 12.4.1: 公式 release source 19,713,921 bytes、release API の SHA-256 と照合。
- libzip 1.11.4: 公式 source、793,340 bytes。固定 SHA-256 は KDE Ark の 公開ビルド定義 とも対応する。上流が detached signature を公開しているとは主張しない。
- PDFium 155.0.8057.0: 既存
.deps/pdfiumを source snapshot に含め、リポジトリーの lock と supplemental notice 検証を通常 CMake で維持する。
作成と起動
リポジトリー root から実行する。取得・VM 起動は通常の OS 権限が必要。
python3 tests/ubuntu_vm/prepare_downloads.py
python3 tests/ubuntu_vm/verify_inputs.py
python3 tests/ubuntu_vm/create_guest.py
python3 tests/ubuntu_vm/run_guest.py
最後のコマンドは VM の前景プロセスを維持する。別ターミナルから python3 tests/ubuntu_vm/probe_guest.py で起動・SSH・OS・Landlock・AppArmor を記録する。初回の cloud-init が完了するまで待つ。seed はパスワード認証と root SSH を無効にし、作業専用 docview user と新規公開鍵を設定する。guest の root 作業には、この guest user の sudo だけを使う。
qmp.py query-status、qmp.py stop、qmp.py cont で状態確認・一時停止・再開、qmp.py system_powerdown で正常終了できる。性能測定の並行実行を避ける場合は guest を停止する。正常終了して QEMU が終了してからだけディスクをコピー・削除する。
依存環境と本体
- guest 内で APT update、必要 package の
--assume-nosimulation、--no-install-recommendsinstall を行う。固定 package 一覧は apt-packages.json、初回の実行記録は作業先metadata/apt-packages.json、候補・取得量・実配置ログはlogs/apt-*.txt。Ubuntu 自身の署名付きリポジトリーを使う。ホスト APT/Pacman は変更しない。 python3 tests/ubuntu_vm/fetch_sdk.pyで固定 SDK/source を取得する。sdk-downloads/とmetadata/sdk-downloads.json、install_guest_sdk.pyを専用 SSH で guest の~/incoming/へコピーする。python3 incoming/install_guest_sdk.pyを guest 内で実行する。- Qt は
/opt/docview-qt/6.11.2/gcc_64、qpdf/libzip は/opt/docview-depsへ配置される。QtWebEngineProcess のこの固定パスだけを対象に、Ubuntu 標準と同じflags=(unconfined) { userns, }形式の AppArmor profile を追加する。これは Chromium 内部の sandbox を無効にする設定ではない。kernel.apparmor_restrict_unprivileged_userns=1を維持し、--no-sandbox等は使わない。 - 本体ソースが安定した時点で
python3 tests/ubuntu_vm/snapshot.py --name source-snapshotを実行する。既存出力があれば別名にする。snapshot archive と manifest を guest の~/incoming/source-snapshot.tar.gz、source-snapshot.jsonへ転送し、build_guest.pyを同ディレクトリーへコピーして実行する。全ファイルの SHA-256 を再照合してから~/docview-source、~/docview-buildでビルドする。
guest での通常 build/test 環境は次のとおり。
export PATH=/opt/docview-deps/bin:/opt/docview-qt/6.11.2/gcc_64/bin:$PATH
export PKG_CONFIG_PATH=/opt/docview-deps/lib/pkgconfig
export LD_LIBRARY_PATH=/opt/docview-deps/lib:/opt/docview-qt/6.11.2/gcc_64/lib
export QT_QPA_PLATFORM=xcb
export QT_QUICK_BACKEND=software
mkdir -p ~/validation/ctest
dbus-run-session -- xvfb-run -a -s '-screen 0 1920x1080x24' \
ctest --test-dir ~/docview-build --output-on-failure \
--output-junit ~/validation/ctest/tests.xml
guest 内の実版・kernel・LSM、入出力の hash、CTest ログは個別に保存する。後続ソース変更を同期する際は前の manifest/結果を保持し、src/qml 差分を明示する。この VM の Xvfb/Sway headless の結果は、物理 GPU・実ディスプレイ・人の IME 操作・配布ライセンス確認まで合格した証拠にはしない。Arch 用 tar/告知 manifest の一致を、異なる Ubuntu/公式 Qt SDK の配布証拠へ流用しない。
差分と追加検証
sync_patch.py --name <新しい名前> <repository相対file...> は指定したsourceだけを転送し、guestの変更前本文と前後SHA-256を ~/validation/source-deltas/ へ保存する。既存名は再使用しない。秘密鍵・設定・ユーザー文書はsource集合へ含めない。
追加Wayland試験にはguestの sway packageを使う。runnerは独立D-Busと一時XDG保存先、1920×1080のheadless/pixman compositorを作る。実際のサイズ変更がQt側とcompositor側で確定してから次の操作へ進む。小さい出力では縦960pxの試験前提を満たせない。
python3 ~/docview-source/tests/run_wayland_validation.py --build-dir ~/docview-build --output ~/validation/wayland/gui --mode gui
python3 ~/docview-source/tests/run_wayland_validation.py --build-dir ~/docview-build --output ~/validation/wayland/smoke --mode smoke
cmake --install ~/docview-build --prefix ~/docview-install
UbuntuのPython 3.12では、Arch package cacheのzstd専用fixture 5件を明示skipする。Python 3.14で実行したArchの35件を、Ubuntuの35件成功として扱わない。Ubuntuでは残り30件と、別のinstalled runtime inventoryを検査する。
配置先の検査
guest内で、install済みの本体に対して以下を実行できる。出力先は新しいdirectoryを選ぶ。
python3 ~/docview-source/tools/collect_ubuntu_validation_runtime.py \
--prefix ~/docview-install \
--qtpaths /opt/docview-qt/6.11.2/gcc_64/bin/qtpaths \
--dependency-prefix /opt/docview-deps \
--input-manifest ~/incoming/sdk-downloads.json \
--source-root ~/dependency-sources/qpdf-12.4.1 \
--source-root ~/dependency-sources/libzip-1.11.4 \
--output ~/validation/new-installed-runtime
collectorは選択した信頼済みbuild/SDKにだけlddを実行し、ファイル・symbolic link・実体hash・依存解決・dpkg所有packageを確認する。任意の未信頼実行ファイルを調べるためには使わない。runtimeをコピーした配布物は作らず、告知の欠落と完全なChromium告知未確認も記録する。SDKのSBOMには10MBを越えるものがあるため、metadataは1件16MiB・合計64MiB、告知本文は1件8MiB・合計32MiBの別上限を使う。
本体起動時は上記のLD_LIBRARY_PATHを維持し、tests/smoke.py --binary ~/docview-install/bin/docview --output ~/validation/new-installed-smokeを専用Xvfb内で実行する。これは別prefixへのbuild/install検査であり、自己完結packageの配布確認ではない。
保存済みの実行結果には失敗と修正後の成功、配置後の6条件起動、依存台帳を区別して残した。試験の途中でフォントRPCの待機を修正したため、現行のrecord_guest_validation.pyはこの検証で使った~/validation/ctest-font-final/を照合対象にする。
追加の限定試験では--ctest-name canvas-ctest --output-name canvas-build-record.json --expected-groups 2 --scope-note 'Canvas focused tests'のように記録先と範囲を指定する。既存の全体試験の台帳を上書きせず、変更後のsource・実行ファイル・JUnit・ログのhashを別に保存する。WaylandのCanvas単独実行はrun_wayland_validation.py --mode gui --suite pdf_canvasで選択できる。
Ubuntu用deb
パッケージ生成手順と実行結果を追加した。package_smoke.py --output <新規先>は専用VMでインストール済みの/usr/bin/docviewを使い、元SDK・依存・build/installを私有mount namespaceで隠して通常ユーザーでX11/Wayland各6条件を検査する。package_lifecycle.py --smoke <成功したsmoke先> --output <新規先>は、そのバイナリー一致を確認してDocViewだけをremove/purgeし、新しく作ったユーザーデータprobeの保持を検査する。後者の検証後、VM内のDocViewパッケージは未インストールになる。開発環境のSDKとソースは保持する。
クリーンOS検証はDOCVIEW_VM_WORK=build-ubuntu-package-cleanで同じ読取専用base imageから別overlayを作り、開発VMを停止してから同じSSHポートを使う。SDKやbuildを転送せず、debと試験入力だけを転送した。clean_package.py --phase install|smoke|remove --archive <検証済みdeb> --output <新規記録先>を順に実行する。install phaseは宣言依存で全ELFが解決することを確認してからGUI試験ツールを追加する。新規OSの結果に元image・転送内容・apt変更・3 phaseを保存した。