エージェント間で写真を受け渡す

JenkinsBeginner
オンラインで実践に進む

はじめに

Fieldlight Studio は今度は、3 枚の小さな写真、コンタクトシート、キャプション、ダウンロード後も使えるギャラリーを含む、完全な写真パックを必要としています。一方の Jenkins エージェントは写真を処理でき、もう一方には用意されたパッケージ作成ツールがあります。両方のエージェントを正しく選んでも、ワークスペースのファイルが共有されるわけではありません。

この実習では、そのファイル不足の問題を観察し、1 回の Pipeline 実行内に実際の一時的な受け渡しを追加して、完成した ZIP を独立して使えるように保存します。この実習には専用の原本、接続済みエージェント、未ビルドのジョブが用意されています。前の実習のファイルやビルドは使いません。

前提知識は、写真処理用のエージェントを選ぶで学んだエージェントのラベル、ステージへの割り当て、幅のオプション、Jenkins 標準のアーティファクト、フィンガープリントの設定、ワークスペースのクリーンアップと、Jenkins の基本的な画面操作です。Java のプログラミングやエージェントのインストールは必要ありません。両エージェントは同じ練習用 VM 上の別々のコンテナーで、独立したファイルシステムを持ち、カーネルを共有しています。Fieldlight と、AI で生成した学習用写真は、実在の顧客やイベントを表すものではありません。所要時間は著者による見積もりで、初心者による実測値ではありません。

別々のワークスペースを観察する

このステップでは、画像処理用エージェントからパッケージ作成用エージェントへの作業の流れを追い、準備が成功しても利用できる納品物にはならない理由を観察します。Photo Desk から始めてください。

Garden Stories の原本 3 枚、ラベンダー、庭の小道、じょうろを確認します。各画像を開き、ブラウザーの Back 操作で戻ります。デスクには No completed collection yet と表示されています。これらの原本は変更してはいけません。求められる納品物は、縦横比を維持した、正確に 320 pixels wide(幅 320 ピクセル)のプレビューです。

Jenkins に切り替え、build-photo-pack を開きます。Configure → Pipeline を選び、準備された Script を読みます。最上位の agent none により、各ステージが必要な機能を持つエージェントを割り当てられます。Prepare photos は photo-imaging を要求し、/opt/fieldlight/prepare-photos --width 320 を実行します。Pack collection は photo-packing を要求し、/opt/fieldlight/pack-photos を実行します。

各ステージは deleteDir() で始まり、それぞれに post { always { deleteDir() } } のクリーンアップがあります。ワークスペースは、ジョブに割り当てられたエージェント上のディレクトリです。両ステージが同じジョブ名を使っていても、ディレクトリは別々のコンテナーファイルシステム上にあります。共有ディレクトリを別の名前で呼んでいるわけではありません。読み取り専用の原本は、ジョブのワークスペースの外側、画像処理用エージェントの /opt/fieldlight/originals にあります。

画像プログラムは、現在のワークスペースを基準に次の 6 ファイルを書き出します。

prepared/
  images/
    garden-01.png
    garden-02.png
    garden-03.png
  contact-sheet.png
  captions.csv
  preparation.json

3 枚のプレビューは 320 × 213 ピクセルです。コンタクトシートはそれらをまとめて表示し、CSV は各ファイル名とキャプション、寸法を関連付け、JSON はコレクション、要求された幅、元画像のハッシュを示します。用意されたパッケージ作成ツールは、自身のワークスペースにあるこれらの実際のファイルを使います。不足したファイルを、別のエージェントや Photo Desk から取得することはありません。

スクリプトを編集せずにジョブページに戻り、Build Now を 1 回選びます。Build History で新しい番号付きビルドを開き、Console Output を開きます。想定された FAILURE を待ってください。最初に image-studio が 3 previews at 320 pixels wide と報告します。そのクリーンアップの後、pack-studio がパッケージ作成コマンドを実行し、Missing prepared/preparation.json in this agent's workspace と報告します。最後のクリーンアップも実行されます。

これはファイルの配置場所による失敗であり、原本の破損やプログラム不足ではありません。準備ステージは完了しましたが、受け渡しがありませんでした。手動でのファイルコピー、マウントの共有、クリーンアップの削除、両ステージの画像処理用エージェントへの配置では、意図した 2 エージェントのワークフローを実現せずに、学ぶべき点を回避してしまいます。両ステージの割り当てと、両方のクリーンアップセクションをそのまま残してください。

ビルドがまだ実行中または待ち行列にある場合は、最終状態になるまで待ってからチェックします。誤った編集で別のエラーになった場合は、以下の設定から元のスクリプトを復元して保存し、1 回実行して、この想定されたファイル不足の失敗を観察してください。

pipeline {
    agent none
    stages {
        stage('Prepare photos') {
            agent { label 'photo-imaging' }
            steps {
                deleteDir()
                sh '/opt/fieldlight/prepare-photos --width 320'
            }
            post {
                always { deleteDir() }
            }
        }
        stage('Pack collection') {
            agent { label 'photo-packing' }
            steps {
                deleteDir()
                sh '/opt/fieldlight/pack-photos'
                archiveArtifacts artifacts: 'photo-pack.zip', fingerprint: true
            }
            post {
                always { deleteDir() }
            }
        }
    }
}

失敗した実行とそのコンソールを残してください。Photo Desk に切り替えて再読み込みします。まだ完了したコレクションがないと表示される必要があります。3 枚すべての原本全体は、引き続き利用できます。次のステップでは、小さな処理済み出力だけを転送し、保存用アーカイブを作成します。

写真を受け渡し、パックを保存する

このステップでは、同じ Pipeline 実行内で 6 つの処理済みファイルを転送し、完成した ZIP をアーカイブして、独立して確認します。Jenkins から始め、build-photo-pack に戻り、Configure → Pipeline を選びます。

stash は、後で同じ Pipeline 実行内で使うために、選択した小さなファイル一式を保存します。名前と includes パターンを指定してください。ここでの prepared/** は、処理済みフォルダーのファイルと、入れ子になった images/ のファイルを含みます。相対パスは維持されるため、stash を復元すると受信側のワークスペースに prepared/ が作成されます。stash に入れるのは、これらの小さな派生ファイルだけです。原本、Java ランタイム、ツールのディレクトリは含めません。

unstash は、その名前付きファイル一式を、現在のエージェントのワークスペースに復元します。名前は先ほどの stash と一致する必要があります。受信側ステージの最初の deleteDir() の後で、パッケージ作成コマンドの前に置いてください。stash は、処理の後で、画像ステージのクリーンアップの前に置きます。そうしないと、ファイルがまだ存在しない、すでに削除されている、復元直後に削除される、のいずれかになります。

stash は一時的な転送であり、ダウンロード用アーカイブではありません。通常 Jenkins は、この実行が終わると破棄します。一方、archiveArtifacts は、最終 ZIP をそのビルドとともに保存します。両方の操作を残すことで、受け渡しは一時的に、納品物は後でも使える形にできます。

Script の内側をクリックし、Windows/Linux では Ctrl+A、macOS では Command+A ですべて選択して、この完全な版に置き換えます。

pipeline {
    agent none
    stages {
        stage('Prepare photos') {
            agent { label 'photo-imaging' }
            steps {
                deleteDir()
                sh '/opt/fieldlight/prepare-photos --width 320'
                stash name: 'prepared-photos', includes: 'prepared/**'
            }
            post {
                always { deleteDir() }
            }
        }
        stage('Pack collection') {
            agent { label 'photo-packing' }
            steps {
                deleteDir()
                unstash 'prepared-photos'
                sh '/opt/fieldlight/pack-photos'
                archiveArtifacts artifacts: 'photo-pack.zip', fingerprint: true
            }
            post {
                always { deleteDir() }
            }
        }
    }
}

新しい 2 行は、名前付きの stash と、それに対応する unstash です。用意された画像処理とパッケージ作成のコマンド、正しいエージェント、元ファイルの保護範囲、クリーンアップは維持されています。archiveArtifacts の設定は photo-pack.zip を保存し、Jenkins 標準のファイルフィンガープリントを記録します。フィンガープリントが追跡するのはファイルの識別情報であり、顧客の承認やデジタル署名ではありません。

Save、Build Now の順に選びます。新しい実行が SUCCESS で完了するまで待ちます。Console Output を開いて順序を読み取ってください。image-studio が 320 ピクセルの写真を準備し、Jenkins が Stashed 6 file(s) と報告して、画像処理のワークスペースが消去されます。その後 pack-studio が stash を復元し、パッケージ作成ツールが Packed 9 collection files into photo-pack.zip と報告します。Jenkins は ZIP をアーカイブしてフィンガープリントを記録してから、パッケージ作成のワークスペースを消去します。

コンソールに No such saved stash と表示された場合は、2 つの stash 名とその順序を比較し、完全なスクリプトを復元して保存し、再実行します。まだ処理済みファイルが見つからないと報告される場合は、includes パターンが prepared/** で、unstash が受信側のクリーンアップの後にあることを確認します。新しいビルドごとに、新しい転送が始まります。以前のビルドの stash は代用できません。Groovy の構文エラーの場合は、スクリプト全体を復元し、波括弧、引用符、コンマを維持してください。失敗と成功のすべての実行を残します。通常のミスで VM をリセットする必要はありません。

成功したビルドのページで、photo-pack.zip アーティファクトを選んで保存します。自分のコンピューターの新しいフォルダーに ZIP 全体を展開してください。アーカイブビューアー内の HTML ファイルだけを開いてはいけません。同じ場所に置くほかのファイルも展開する必要があります。フォルダーには次の内容があるはずです。

index.html
styles.css
delivery.txt
captions.csv
preparation.json
contact-sheet.png
images/
  garden-01.png
  garden-02.png
  garden-03.png

展開した index.html をブラウザーで開きます。Fieldlight Studio のギャラリーには、正しい庭の写真 3 枚とそのキャプションがすべて表示されるはずです。各写真を開き、ブラウザーの Back で戻ります。Open contact sheet を選んで実際の 3 枚の一覧画像を見てから、ブラウザーの Back でギャラリーに戻ります。展開したフォルダーから、captions.csv、preparation.json、delivery.txt をテキストエディターで開いてください。ギャラリーのリンクは、これらと同じファイルを指しています。CSV のファイル名は実際の images/ ファイルを指し、すべてのプレビューは 320 × 213 ピクセルで、JSON は garden と幅 320 を示す必要があります。納品の案内には、この実際の Jenkins ジョブ、ビルド、パッケージ作成エージェントが示されているはずです。

完成した Fieldlight Studio の写真ギャラリー

完全なギャラリーには、庭の写真 3 枚、コンタクトシートのリンク、実際のキャプション・画像詳細・納品ファイルへのリンクが含まれます。展開したコピーを開くときは、周囲のファイルを一緒に保ってください。

展開した完全なフォルダーのファイルを一緒に保ってください。Photo Desk を使わず、新しいプライベートブラウザーウィンドウで開きます。すべての画像、スタイル、ファイルのリンクが、ローカルファイルから引き続き機能するはずです。ギャラリーは、リモートフォントやオンライン画像による代替表示を使いません。ローカルの画像が表示されない場合は、実際の納品ファイルが不足しているか、配置場所が違います。ソースの Web サイトから不足分をコピーするのではなく、元の ZIP 全体を新しいフォルダーに展開してください。

Photo Desk に切り替えて再読み込みし、Open prepared collection を選びます。この表示は、実際に Jenkins に保存したアーカイブからファイルを読み取ります。写真と添付ファイルを確認し、ブラウザーの Back 操作で戻って、Download complete ZIP を選びます。そのバイト内容は、ダウンロードした Jenkins アーティファクトと一致するはずです。デスクに戻り、3 枚すべての原本全体が変わっていないことを確認してください。

最後に Jenkins に切り替えます。成功したビルドを開き直し、クリーンアップ後もアーティファクトをダウンロードできることを確認します。最初のファイル不足の実行、すべての履歴、原本、ツール、ノードの接続、機能ラベルを維持してください。さらにスクリプトを編集した場合は、チェックの前に保存し、新しいビルドを正常に完了させます。実際の 2 エージェント間の受け渡しと、完全な保存済み納品物ができました。

まとめ

独立した Jenkins のワークスペースを観察し、1 回の実行内で名前付きの stash と対応する unstash を使い、必要な写真の出力だけを転送しました。パッケージ作成用エージェントは完全なローカルギャラリーを作成し、Jenkins 標準のアーティファクト保存により、両ステージのワークスペースが消去された後も使える状態に保ちました。独立したチャレンジでは、同じ学習済みの仕組みを使い、コレクションと幅を変更します。