mcpField
J
jetson-promote-image

jetson-promote-image

github.com/nvidiaクラウド・DevOps3.8k1.1k 回インストール今日更新
リポジトリ

jetson-promote-image について

jetson-promote-imageは、カスタマイズとビルドの成果物を設定済みのbsp_imageへコピーし、後続のフラッシュや確認に備えるスキルです。overlayとビルドマニフェストを統合し、同一ファイルを除外します。カーネルやモジュールの変更時にはinitramfsを更新します。

主な機能

  1. 01overlayとビルドマニフェストの成果物を統合
  2. 02同一内容のファイルをコピー対象から除外
  3. 03変更されたカーネルImageをrootfsへ反映
  4. 04カーネルまたはモジュール変更後のinitramfs更新
  5. 05ビルドの鮮度とoverlayの競合を確認

活用シーン

  1. 01Jetsonのフラッシュ前にBSP成果物を配置
  2. 02フラッシュせずに確認用のbsp_imageを更新
  3. 03別のフラッシュ用ホストに渡すイメージを準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nvidia/skills --skill jetson-promote-image

インストール後、Claude Code で/jetson-promote-imageを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

BENCHMARK.md
skill-card.md
skill.oms.sig
evals/
evals.json
references/
build-source-freshness-gate.md
copy-pass-snippets.md
kernel-image-and-initramfs.md

詳細

BSP イメージのプロモート

目的

すべての Customize-* と Build の出力を bsp_image にステージングし、/jetson-flash-image ですぐに使える状態にします。これは Deploy のプロモート工程です。ファイルをコピーするだけで、フラッシュもビルドもしません。

前提条件

  • source: と bsp_image: の両方が解決済みの、アクティブなターゲットプラットフォームプロファイル(先に /jetson-init-source と /jetson-init-image を実行してください)。
  • <source.root_path>/Linux_for_Tegra/ が git リポジトリ(オーバーレイトラッカー)として初期化され、ワーキングツリーがクリーンであること。
  • <bsp_image.root_path>/Linux_for_Tegra/ が BSP tarball から展開済みで、apply_binaries.sh も実行済みであること。
  • ホストに git、yq、cmp、および(rootfs/* のコピー先用に)sudo があること。
  • /jetson-build-source による <source.root_path>/.build-manifest.yaml と .build-state.yaml(カーネル側のリポジトリに customize-* のコミットがある場合に必要)。

概要

これは Deploy のプロモート工程です。パイプラインの概要は ../../context/bsp-customization-workflow.md を参照してください。このスキルがたどる 2 つの経路は次のとおりです。

経路ソース搬送元管理者
オーバーレイトラッカー<source.root_path>/Linux_for_Tegra/(HEAD にある git リポジトリ)ビルド不要の Customize-* 出力(例:nvfancontrol.conf、nvpmodel.conf、BPMP DTB の手動編集)Customize customize-* スキルがここにコミット
ビルドマニフェスト<source.root_path>/.build-manifest.yaml再ビルドされたカーネル Image、ツリー内の .ko、OOT .ko、NVIDIA DTBBuild jetson-build-source がここに書き込み

このスキルは、コピー対象ファイルの和集合を算出し、差分を確認して同一ファイルのコピーをスキップするロジックで、それぞれを <bsp_image.root_path>/Linux_for_Tegra/ に書き込みます。コピー処理でカーネル Image または rootfs/lib/modules/ 配下のファイルに触れた場合は、NVIDIA の tools/l4t_update_initrd.sh を使って initramfs も再構築し、新たにプロモートされたカーネルとモジュールを、ブートローダーが実際に読み込む initrd に含めます。処理の完了後、bsp_image にはすべての Customize と Build の出力が揃います。このスキルはフラッシュを行わず、ワークスペースも変更しません。

実行するタイミング

  • 一般的な Deploy チェーンの最初の工程 jetson-promote-image → jetson-flash-image → jetson-validate-image。
  • ユーザーが bsp_image を更新したいものの、まだフラッシュの準備ができていない場合に単独で実行します(例:解決済みファイルの確認、bsp_image を読み込む範囲外のビルドの実行、または bsp_image を別のフラッシュ用ホストに渡す場合)。

手順

アクティブなターゲットとパスを解決する

../../context/target-platform-contract.md の契約に従って、アクティブなプロファイルを解決します。

次の場合は拒否し、適切な処理先に案内します。

条件拒否時の案内
アクティブなプロファイルがない、または active: NA/jetson-set-target または /jetson-init-target に案内します。
プロファイルに bsp_image: がない/jetson-init-image に案内します。
<bsp_image.root_path>/Linux_for_Tegra/ がない/jetson-init-image に案内します。
<source.root_path>/Linux_for_Tegra/ がない、または git リポジトリではない/jetson-init-source に案内します。

パスを解決します。

  • <workspace> = アクティブなプロファイルの target-platform/ ディレクトリの親ディレクトリ(読み込み時に検出)。
  • <bsp_image.root_path> は、bsp_image.root_path: があればその値、なければ <workspace>/Image。
  • <source.root_path> は、source.root_path: があればその値、なければ <workspace>/Source。

以降の手順で使うシェル変数を設定します。

LFT_SRC="<source.root_path>/Linux_for_Tegra"   # overlay tracker
LFT_DST="<bsp_image.root_path>/Linux_for_Tegra"
MANIFEST="<source.root_path>/.build-manifest.yaml"   # build outputs
2 つの経路を検証する

このスキルを実行するには、少なくとも 1 つの経路にデータが必要です。オーバーレイトラッカーに未コミットの変更がある場合(status --porcelain が空でない場合)、$MANIFEST が存在するものの YAML として解析できない場合、または両方の経路が空の場合は拒否します。後続の手順で使う OVERLAY_HAS_COMMITS/OVERLAY_HEAD と MANIFEST_PRESENT を記録します。

シェルスニペットと拒否時のメッセージについては、references/copy-pass-snippets.md を参照してください。

ビルドソースの鮮度を確認する

.build-state.yaml で、最後の /jetson-build-source 以降に Source/bsp_sources/ 内のカーネル側リポジトリが変更されていることが 示されている場合は、処理を拒否します。そうしないと、コピー処理で 古い成果物が気付かれないまま出荷されてしまいます。 検出ルールとシェルスニペットについては、 references/build-source-freshness-gate.mdを参照してください。 BUILD_FRESH=1 を記録します。

昇格前の衝突チェック(オーバーレイのみ)

オーバーレイがリモートを追跡している場合、上流に未取得のコミットが あれば処理を拒否します。リモートが設定されていない場合は、 適切にスキップします(jetson-init-source によるデフォルトの 空の git init トラッカー)。 マニフェストチャネルには git リモートの概念がないため、このチェックは オーバーレイのみに適用されます。Summary 用に COLLISION_CHECK を記録します。

シェルスニペットについては、 references/copy-pass-snippets.md を参照してください。

ソースの列挙(両方のチャネル)

チャネル A — オーバーレイ:$LFT_SRC に対する git ls-files を 信頼できる情報源とします(source.repos.Linux_for_Tegra が オーバーライドされている場合、シンボリックリンクマウントにも対応し、 未追跡ファイルや .gitignore 対象ファイルは除外します)。各エントリは src = $LFT_SRC/<rel> → dst = $LFT_DST/<rel> に対応します。

チャネル B — マニフェスト:$MANIFEST から artifacts[].{src,dst} を解析します。src がディスク上に存在しない場合は 処理を拒否します(ビルドが中断されたか、マニフェストが古くなっています。 /jetson-build-source を再実行してください)。 マニフェストのスキーマは jetson-build-source v0.2.0 によって書き込まれます。

両方のシェルスニペットとマニフェストの YAML スキーマについては、 references/copy-pass-snippets.md を参照してください。

差分を考慮した bsp_image へのコピー

オーバーレイファイルとマニフェストエントリの和集合を反復処理します。 各 dst について、バイト単位で同一の場合はスキップし、それ以外は cp -p でコピーします(サンプル rootfs が root として展開された rootfs/* のコピー先には sudo を使用します)。rootfs/lib/modules/* または kernel/Image への書き込みがあれば INITRD_DIRTY=1 を設定します。 「initramfs の更新」ステップはこのフラグを条件として実行されます。 件数/FIRST/LAST は Summary 用に記録されます。

フェイルファスト:cp が失敗した場合は、失敗したパスを示して停止します。 bsp_image は部分的に更新された状態になる場合がありますが、原因を 修正して再実行すれば、差分を考慮したスキップによって処理を再開できます。 チャネルの順序は、まずオーバーレイ、次にマニフェストです。dst が 衝突した場合は、マニフェストが優先されます(古いオーバーレイのコピーより、 新しくビルドされた成果物が優先されます)。

copy_one() 関数と、処理を実行する 2 つのループについては、 references/copy-pass-snippets.md を参照してください。

カーネルが変更された場合の、カーネル Image の rootfs へのミラーリング

カーネル Image は bsp_image 内の 2 つのパスに存在します。 <LFT_DST>/kernel/Image(フラッシュツールが読み取ります)と <LFT_DST>/rootfs/boot/Image(rootfs 側のコピーで、更新ツールが実行される rootfs の chroot 内からは /boot/Image として見えます)です。 ビルドマニフェストに含まれるのは kernel/Image の dst のみであるため、 このステップでは kernel/Image → rootfs/boot/Image をミラーリングします (差分を考慮し、すでに同期されている場合は何もしません)。これにより、 chroot 内で実行される更新ツールは古い rootfs のコピーではなく、新しく 昇格されたバイナリを使ってカーネルを解決します。このミラーリングでは INITRD_DIRTY=1 も設定されるため、カーネルのみの昇格 (rootfs/lib/modules/* への書き込みなし)でも更新が実行されます。

シェルスニペット、この処理で防止される障害、および INITRD_DIRTY の 特殊ケースについては、 references/kernel-image-and-initramfs.md を参照してください。

initramfs を更新する(カーネルまたはモジュールが変更された場合)

INITRD_DIRTY=1(上記の差分対応コピーまたはミラーステップによって設定された場合)は、<LFT_DST>/ から tools/l4t_update_initrd.sh を実行します。このツールは rootfs/ に chroot し、NVIDIA の nv-update-initrd を実行して、<LFT_DST>/bootloader/l4t_initrd.img(フラッシュツールで使用)と <LFT_DST>/rootfs/boot/initrd(DUT 上の /boot/initrd)の両方を書き込みます。冪等で、所要時間は約 30 秒です。INITRD_DIRTY=0 の場合(オーバーレイのみの編集)はスキップします。DUT 側での回避策(update-initramfs -u と手動の cp)は対象外です。フラッシュ時に整合性のあるイメージが使われるよう、ここで問題を解決してください。

シェルのスニペット、拒否するパス、再ビルドによって解消される「モジュールのシャドーイング」と「vermagic の不整合」の障害モード、および別のファイルである bootloader/initrd をそのままにする理由については、references/kernel-image-and-initramfs.md を参照してください。

概要

以下を報告します。

  • オーバーレイの範囲:overlay HEAD ($OVERLAY_HEAD) または「(空)」。
  • マニフェストの範囲:mode=<...>, bsp_version=<...>, rebuilt_at=<...>, N artifacts または「(なし)」。
  • 衝突チェック:$COLLISION_CHECK。
  • 件数:
    • オーバーレイ:$COPIED_OVERLAY copied, $IDENTICAL_OVERLAY identical
    • マニフェスト:$COPIED_MANIFEST copied, $IDENTICAL_MANIFEST identical
  • カーネル Image のミラー:$KIMG_MIRRORED、initramfs:$INITRD_STATUS(kernel/Image または rootfs/lib/modules/* への書き込みによって実行された場合は copied … / rebuilt、それ以外は skipped …)。
  • コピーした最初と最後のパス(COPIED の合計が両方とも 0 の場合は省略)。
  • 解決済みの <source.root_path>、<bsp_image.root_path>。
  • 次のステップ:/jetson-flash-image(ユーザーが確認または静的検証のために bsp_image の更新のみを希望した場合は /jetson-validate-image)。

制限事項

  • 2 つのチャネルで 1 つの出力先を共有します。 bsp_image/Linux_for_Tegra/ には両方のパスから書き込みます。オーバーレイは customize-* の出力 (nvfancontrol.conf のようなオーバーレイのみの編集)を引き継ぎ、 マニフェストは再ビルドされたバイナリ(カーネル/OOT/DT)を引き継ぎます。 2 つは設計上、互いに重複しません。ビルド出力は オーバーレイに入らず、ビルド対象外ファイルへの customize-* による編集は マニフェストに入りません。
  • ビルドマニフェストは、トレースと変更の対応関係を保証します。 マニフェスト内の 項目はすべて、変更のあったソースリポジトリから生成されています (jetson-build-source の「Write the build manifest」ステップのトレースポリシーに従います)。そのため、マニフェストの 昇格は安全です。各項目はカスタマイズを含む 成果物であり、ツールチェーンの差異によるノイズではありません。このスキルは トレースを再導出せず、マニフェストを信頼します。
  • マニフェストの項目は、ビルド出力がなくなった後も残ることがあります。 ユーザーが jetson-build-source と jetson-promote-image の実行の間に Source/.build/ または bsp_sources/ のビルド成果物を 削除すると、マニフェストは存在しないファイルを参照します。その場合、「Enumerate sources (both channels)」ステップは処理を拒否し、再ビルドするために /jetson-build-source を実行するようユーザーに案内します。
  • オーバーレイのみを編集した場合、マニフェストがなくても問題ありません。 オーバーレイ側のみのカスタマイズ(例:customize-fan)では ビルド出力は生成されず、マニフェストも書き込まれません。「Enumerate sources (both channels)」ステップは 何もせず、「Diff-aware copy into bsp_image」ステップはオーバーレイファイルのみを 昇格します。このスキルは概要に「manifest: (absent)」と出力して、 処理を続行します。
  • 差分を考慮し、冪等です。 前回の昇格以降にオーバーレイのコミットや マニフェストの変更がなければ、再実行しても何も行われません(すべての ファイルが同一です)。副作用なしで bsp_image が同期されていることを 確認できます。
  • シンボリックリンクマウントを透過的に扱います。 jetson-init-source で source.repos.Linux_for_Tegra が上書きされている場合、正規マウントは <source.root_path>/.repos/Linux_for_Tegra/<subdir> へのシンボリックリンクです。git -C、 cp -p、cmp -s はすべて透過的にこれをたどるため、このレイヤーで特別な 処理は不要です。マニフェストの src パスは絶対パスなので、 bsp_sources/ 配下のシンボリックリンクはマニフェストチャネルに 影響しません。
  • sudo の使用は rootfs/ 宛ての処理に限定されます。 rootfs/ 配下のファイルは jetson-init-image が sudo tar xpjf で展開したもので、root の所有権と、フラッシュ用ツールチェーンが読み取る特別な モードビットを保持しています。sudo cp -p でそれらを保持できます。それ以外(bootloader/、kernel/、 kernel/dtb/、tools/ など)はユーザー所有なので、 sudo は不要です。これは両方のチャネルに適用されます。
  • チャネル間で重複した場合の優先順位。 同じ dst が オーバーレイとマニフェストの両方にある場合、マニフェストが優先されます(「Diff-aware copy into bsp_image」ステップの ループで後に処理されるためです)。これが意図した動作です。マニフェストの項目は 新たにビルドされたもので、オーバーレイの項目は古い状態の可能性があります。バイナリファイルを オーバーレイに手作業で編集することは推奨されません(ビルドの役割は 再ビルドすることです)。この優先順位により、そのような誤りから復旧できます。
  • Deploy の外では bsp_image は読み取り専用です。 通常のフローでは、このスキルのみが 書き込みを行います(ワークフローの不変条件と一致します)。 Deploy の外で <bsp_image.root_path>/Linux_for_Tegra/ を手作業で 編集すると、同じパスがいずれかのチャネルに存在する場合、次回の昇格実行時に 予告なく上書きされます。一方、対応する項目がなければ 元に戻されません。どちらも差分の追跡を損なうため、上流を手作業で編集しないでください。
  • 対象範囲はオーバーレイの HEAD のみです(チャネル A)。 名前付きタグ/ マニフェスト/コミット範囲は後回しです(下記参照)。過去の状態を 昇格するには、まず git -C $LFT_SRC checkout <ref> を実行してから、 再実行してください。マニフェストチャネルには範囲指定がなく、 jetson-build-source の前回実行で生成された内容を反映します。
  • 部分的な失敗が起きても、自動ロールバックは行いません。 cp が途中で失敗すると、 bsp_image は中間状態のままになります。根本原因(通常は権限またはディスク容量不足)を 解消してから再実行してください。「Diff-aware copy into bsp_image」ステップは、すでに昇格したファイルをスキップして 処理を再開します。
  • カーネル Image のミラーと initramfs の更新。 コピー処理で kernel/Image または rootfs/lib/modules/* への書き込みがあった場合にのみ実行します。ミラーは更新処理の chroot に 使用されます。どちらも差分を考慮し、オーバーレイのみの編集ではスキップされます。 bsp_image に tools/l4t_update_initrd.sh が存在する必要があります (apply_binaries.sh に同梱されています)。ツールが見つからない場合は処理を拒否し、 /jetson-init-image を案内します。契約と失敗時の動作については、 references/kernel-image-and-initramfs.md を参照してください。

トラブルシューティング

エラー原因解決策
Overlay has uncommitted changes at <LFT_SRC>promote の前に Customize-* の編集がコミットされていませんgit -C $LFT_SRC commit(または stash)を実行してから、再実行してください。
origin has N unpulled commits on <upstream>リモートのオーバーレイがローカルと分岐していますgit -C $LFT_SRC pull を実行し、競合を解決してから再実行してください。
Both overlay and manifest are empty — nothing to promoteCustomize-* のコミットも Build マニフェストもありません先に customize-* スキルまたは /jetson-build-source を実行してください。
Kernel-side source(s) changed since last /jetson-build-sourcefreshness gate が Source/bsp_sources/ 配下の未処理の customize-* 編集を検出しました保留中の編集をコミットし、/jetson-build-source を実行してから promote を再実行してください。
Manifest entry references missing build output: <src>bsp_sources/ のビルド出力が削除されているか、マニフェストが古くなっています/jetson-build-source を再実行して再生成してください。
Build manifest at <MANIFEST> is not valid YAMLマニフェストが手動編集されたか、書き込みが途中で終了しています/jetson-build-source を再実行してマニフェストを書き直してください。
rootfs/ 配下で cp: permission deniedホストで sudo 権限がありませんsudo cp を実行できるアカウントで実行してください。再実行すると差分を考慮したコピーから再開します。
プロファイルに bsp_image: / source: がありませんワークスペースが初期化されていません/jetson-init-image および/または /jetson-init-source を実行してください。
tool not found at <LFT_DST>/tools/l4t_update_initrd.shtools/ が削除されたか、bsp_image が NVIDIA 以外の tarball から展開されています/jetson-init-image を再実行して補充してください。
l4t_update_initrd.sh exited non-zerosudo 権限不足、rootfs の破損(lib/modules/<ver>/modules.dep がない)、または /tmp の空き容量不足ですまず rootfs に対して depmod -a -b <LFT_DST>/rootfs <ver> を実行し、/tmp の空き容量を確認してから promote を再実行してください。
promote 後に DUT が古いカーネル/モジュールで起動する、モジュールの読み込みが disagrees about version of symbol … で失敗する、または refresh の実行後も initramfs にカスタマイズ前のモジュールが含まれるミラー/refresh gate が作動していません(スキル外で <LFT_DST> 配下を手動編集した場合など)。または rootfs/boot/Image が kernel/Image と異なり、chroot 内の refresh が古いカーネルを使ってビルドしましたsudo touch <LFT_DST>/kernel/Image を実行して gate を強制し、promote を再実行してください。または、次の 2 つの手順を手動で実行してください:sudo cp -p <LFT_DST>/kernel/Image <LFT_DST>/rootfs/boot/Image && cd <LFT_DST> && sudo ./tools/l4t_update_initrd.sh。その後、再フラッシュしてください。詳細は references/kernel-image-and-initramfs.md を参照してください。

仕様のステータス

v0.2.0 で確定:

  • 2 チャネルのスコープ — オーバーレイの HEAD とビルドマニフェストの両方を対象とします。どちらも差分を考慮し、<bsp_image.root_path>/Linux_for_Tegra/ にコピーします。
  • チャネル間で重複した場合の優先順位 — dst が競合した場合はマニフェストを優先します。
  • ソースリポジトリの競合チェック — オーバーレイのみが対象です。マニフェストにはリモートの概念がなく、bsp_sources/ 配下のソースリポジトリは取得されません(jetson-build-source がマニフェストを書き込んだ時点で、その状態が固定されているためです)。
  • アトミック性 — 最初のエラーで処理を停止し、ロールバックは行いません。差分を考慮したコピーにより、自然に再開できます。
  • 監査証跡 — 昇格時は標準出力のみを使用します。オーバーレイのトラッカーの Git ログがチャネル A の正式な記録であり、マニフェスト自体がチャネル B の正式な記録です。
  • カーネル Image のミラーリングと initramfs の更新。 ペアで行うステップとして確定しました。コピー処理で kernel/Image に触れた場合は、ミラーリングによって kernel/Image を rootfs/boot/Image にコピーします。kernel/Image またはいずれかの rootfs/lib/modules/* が昇格された場合は、更新処理で tools/l4t_update_initrd.sh を実行し、bootloader/l4t_initrd.img と rootfs/boot/initrd の両方を再ビルドします。更新処理は rootfs/ に chroot し、/boot/Image 経由でカーネルを解決するため、ミラーリングを先に実行する必要があり、両者は切り離せません。これにより、モジュールのシャドーイングと vermagic の不整合による両方の障害モードを解消します。どちらも差分を考慮し、オーバーレイのみの編集ではスキップされます。詳しい仕様については、references/kernel-image-and-initramfs.md を参照してください。

引き続き保留:

  • オーバーレイチャネルでの タグ名/コミット範囲のスコープ。「リリース X を昇格する」ユースケースが現れたら再検討します。
  • マニフェストの履歴。 現在は直近のビルドのマニフェストのみが存在します。ユーザーが bsp_image を以前のビルド状態に戻したい場合は、以前のコミットで /jetson-build-source を再実行する必要があります。ビルドモードごと、またはコミットごとにマニフェストを保存してアーカイブすれば、再ビルドせずにロールバックできるようになります。
  • bsp_image 内のサイドカーマニフェスト。 オーバーレイのトラッカーリポジトリ(またはワークスペースのマニフェストファイル)にアクセスできないホストで昇格処理を行うようになったら、再検討します。

参考資料

コメント