HN 日本語サマリー

← 一覧へ戻る
プログラミング

ゼロからブート可能なイメージへ:Tineビルドシステム

From Thin Air to Bootable Images: The Tine Build System (amutable.com)

40 pointsby Levitating22 コメント

要約

この記事では、著者らが開発した新しいビルドシステム「Tine」を紹介しています。TineはBuck2を基盤とし、暗号学的に検証可能な完全性を持つオペレーティングシステムの構築を目指しています。最小限のホスト要件、入力の完全な制御、再現性のあるビルド、迅速なイテレーションといった要件を満たすため、既存のツール(mkosi, OBS, BuildStream, Antlir)の評価を経て、TineはAntlirとmkosiのアイデアを組み合わせ、Buck2をエンジンとして採用しました。

全文翻訳

薄い空気からブート可能なイメージへ:Tineビルドシステム 目次 この記事は、ここ数ヶ月で行ってきたオープンソースの取り組みの一部です。本日、私たちは新しいBuck2ベースのビルドシステムであるTineを紹介し、公開します。 私たちの要件 暗号学的に検証可能な完全性を持つオペレーティングシステムを構築するには、まさにその特性を持つビルドシステムから始める必要があります。同時に、私たちはより大きなオープンソースコミュニティの一員であり、既存の作業を可能な限り貢献し、再利用したいと考えています。また、迅速な開発と短いターンアラウンドを目指しています。これは、ビルドシステムに対する以下の要件に大まかに翻訳されます。 最小限のホスト要件。自己完結型であり、外部依存関係を最小限に抑え、あらゆる環境で実行できるようにする必要があります。 入力の完全な制御。製品に含まれるすべてのソフトウェアをピン留めできるようにする必要があります。アップストリームディストリビューション(Fedora, CentOS, Arch, Debianなど)の選択をサポートし、可能な限り既存のパッケージを再利用しつつ、CVEに迅速に対応し、必要に応じてアップストリームのパッケージング決定から(一時的または永続的に)逸脱することを容易にする必要があります。 統合されたパッケージ管理機能。インポートされたパッケージのインポート、更新、マージのためのツールを提供する必要があります。 安価なワールドリビルド。例えばgccの更新後など、オンデマンドでワールド全体をリビルドできる必要があります。 Hermeticで再現性のあるビルド。すべてのコンポーネントとイメージのビルドは、hermeticな環境で実行され、ビット単位で再現可能な出力を生成する必要があります。 ネイティブイメージビルド。ブート可能なオペレーティングシステムイメージとsystemd sysextイメージをネイティブに、かつ並行してビルドできる必要があります。 Monorepoベースのイテレーション。オペレーティングシステムを単一のトップレベルのmonorepoで保守することをサポートし、高速なエンドツーエンドのイテレーションを可能にする必要があります。インポートされたrpmやGoまたはRustコンポーネントへの変更は、中間コミットやプッシュなしに、また複雑なバージョンや依存関係の宣言なしに、イメージの全セットで即座にビルドおよびテスト可能である必要があります。 ファーストクラスのカスタムコンポーネント。ピン留めされた外部リポジトリ(例:kubernetesやvarlink-http-bridge)から、GoおよびRustプロジェクトをネイティブかつ効率的にビルドできる必要があります。 スキャナー互換性。ビルドされたイメージは、syft/grypeやtrivyなどの標準的なSBOMツールやセキュリティスキャナーと連携する必要があります。 キャッシュ。ビルドは、ローカルおよび/またはグローバルキャッシュから変更されていないコンポーネントを取得できる必要があります。すべてをゼロからビルドするには数時間かかることがあり、開発者は通常、単一のコンポーネントのみを扱っています。 既存のツール 独自のビルドツールを構築する前に、いくつかのオプションを評価しました。 mkosi 私たちのチームにはmkosiの作成者兼メンテナーが含まれているため、これは自然な最初の候補でした。しかし、すぐに根本的な欠点があるという結論に至りました。個々のイメージをアップストリームパッケージに基づいて構築するには優れていますが、互いに弱く関連する複数のイメージを構築する場合や、イメージを構成するアーティファクトに対するより多くの制御が必要な場合には制限的になります。複数のイメージのビルドは、「メイン」イメージの一部として出荷されることを意図したイメージに限定されます。私たちは、さまざまな種類のアーティファクトを統一的かつ堅牢な方法でビルドする必要があり、イメージだけではありません。したがって、ビルドは汎用的で柔軟なツールによってオーケストレーションされる必要があります。メインのビルドファイルは、ライブラリ関数(「cargo crateをコンパイルする」や「UKIをビルドする」など)を呼び出す言語であるべきです。mkosiはその逆で、フレームワークです。イメージの構築方法を知っており、他の種類のビルドに対しては自由形式の不透明なフックしか提供しません。これは、イメージ以上のものをビルドしたい場合に悪い経験につながります。 Open Build Service Open Build Service(OBS)は、SUSEおよびopenSUSEプロジェクトがパッケージからISO、その他多くのイメージフォーマットまで、すべてのアーティファクトを生成するために主に利用している、強力で完全に統合されたビルドシステムです。依存関係の追跡が強力で、驚くほど多くのディストリビューションをサポートしています。しかし、それは「最小限のホスト要件」の対極でもあります。サーバーサイドが必要であり、中央集権的で、自己ホストするには単純ではありません。また、汎用的なビルドシステムではないため、新しいアーティファクトタイプはパッケージとしてモデル化するか、OBSに重いパッチを適用する必要があるでしょう。この柔軟性の欠如と全体的なアーキテクチャの組み合わせにより、OBSが私たちの要件を満たすのは難しいだろうと結論付けました。 BuildStream Apache BuildStreamは、YAMLの「要素」のグラフとしてオペレーティングシステムイメージを記述します。各要素は独自のソース、依存関係、ビルドコマンドを持ちます。BuildStreamは、各要素をbubblewrapサンドボックス内でビルドし、その結果を、入力されたすべてもののハッシュの下にキャッシュします。これはBuck2に似ています。これは成熟しており、freedesktop-sdk、GNOME OS、WebKitGTKのビルドに使用されています。BuildStreamに関する私たちの懸念は、主にブートストラップと拡張性に関するものです。BuildStreamはコンパイル済み拡張機能やその他の依存関係を持つPythonアプリケーションです。ホストからの別のヘルパープログラムセット、およびサンドボックスツールに依存しています。それらのそれぞれはピン留めできますが、異なるメカニズムを通じて行われ、それでも結果はホストのPythonに依存します。実際には、ピン留めされたコンテナイメージから実行しますが、それでも制御できないコンテナランタイム全体に依存することになります。BuildStreamのYAMLはプレーンなデータフォーマットであり、Pythonプラグインで拡張されます。YAMLには関数がないため、時間が経つにつれてプロジェクト全体でコピー&ペーストすることになります。最終的に、より良いブートストラップとピン留めのストーリー、そしてより柔軟な言語を持つツールを採用することにしました。 Antlir AntlirはMetaのOSイメージビルダーであり、Buck2ビルドシステムエンジン上に構築されています。Buck2はMetaのオープンソースビルドシステムで、正確性、柔軟性、および可能な限りのキャッシュに重点を置いています。AntlirはBuck2でイメージをビルドするためのさまざまなルールを実装しています。AntlirはMetaの内部リポジトリに焦点を当てた高レベルツールであるため、自然に非常に意見が強く、Metaの内部ユースケース向けに設計されています。例えば、btrfsを必要とし、単一のmonorepoに強く焦点を当てています。Antlir自体を使用しないことにしましたが、その基盤となるエンジンであるBuck2は適していることが判明し、独自のビルドシステムの基盤として採用することにしました。 私たちのビルドシステム:Tine 本質的に、Tineはrpm、Rust crate、Goモジュールコンポーネント、UKI、およびイメージをビルドするための、意見を持ったBuck2ルールのセットです。ハードウェアキーを介したPKCS#11またはローカルで生成されたキーでイメージに署名できます。その意図は、Antlirとmkosiの最良のアイデアを単一のツールに組み合わせることです。Tineはビルドホストに3つの要件しかありません:git、python3(自身のブートストラップ用のみで、本番ビルド用ではない)、およびユーザー名前空間です。そこから、再現性があり独立したビルド環境を取得するために、ピン留めされた宣言から必要なすべてをブートストラップします。それは、必要なだけ古くても新しくてもよいディストリビューションになります。Tineの重要な概念は「ボックス」であり、これはビルドタスクを実行するための宣言され、ピン留めされた環境です。コンテナやdistroboxと考えてくださいが、Buck2の言語でネイティブに宣言され、Buck2のキャッシュとリビルドルールを使用するため、高速かつ自然にビルドされ、再現性を保ち、実行するためにさらなる依存関係を必要としません。Tine自体は、rpmbuild、go、またはcargoを実行するためのボックス、またはイメージのビルド用のsystemd-ukifyや仮想マシンの実行用のQEMUなどを含む、より大きな汎用ボックスであるfedora.rawhide.boxを定義します。あなた自身のプロジェクトも独自のボックスを定義できます。 Tineのエンジン:Buck2 この記事と例をよりよく理解するために、MakeまたはMesonに慣れている人向けに、1分間のBuck2入門を紹介します。 ビルドファイル:BUCKファイルは、ディレクトリのMakefileに相当します。Pythonの方言であるStarlarkで記述されており、ビルドできるすべてのターゲットを宣言します。 セル:名前付きのビルドグラフのルートです。これらはgitリポジトリの境界に大まかに従います://はあなたのトップレベルプロジェクト(ビルドしたいOS)であり、tine//はTineのチェックアウトです。