# 機能設計書 61-ランチャー

## 概要

本ドキュメントは、Jenkins における外部プロセス起動・制御機能（ランチャー）の設計について記述する。

### 本機能の処理概要

ランチャー機能は、Jenkins のビルド処理において外部コマンドやスクリプトを実行するための基盤機能である。ローカル環境とリモートエージェント環境の両方でシームレスにプロセス起動を行うことができる。

**業務上の目的・背景**：CI/CD パイプラインにおいて、シェルスクリプトの実行、ビルドツールの起動、テストコマンドの実行など、外部プロセスを起動する必要がある。ランチャー機能は、コントローラーノードとエージェントノードの違いを抽象化し、統一的なインターフェースで外部プロセスを起動・管理することで、ビルドステップの実装を簡素化する。

**機能の利用シーン**：
- シェルスクリプト（Shell）ビルドステップの実行時
- バッチファイル（BatchFile）ビルドステップの実行時
- Maven/Gradle 等のビルドツール起動時
- カスタムビルドステップにおける外部コマンド実行時
- エージェントノードへのリモートプロセス起動時

**主要な処理内容**：
1. ProcStarter ビルダーパターンによるプロセス設定の構築
2. コマンドライン引数、環境変数、作業ディレクトリの設定
3. 標準入出力（stdin/stdout/stderr）のリダイレクト管理
4. ローカルプロセス（LocalLauncher）またはリモートプロセス（RemoteLauncher）の起動
5. プロセスの終了コード取得と監視
6. 環境変数フィルタリングルールの適用
7. プロセスツリーを使用したプロセス終了処理（kill）

**関連システム・外部連携**：
- VirtualChannel: リモートエージェントとの通信チャネル
- FilePath: リモートファイルシステム操作
- EnvVars: 環境変数管理
- ProcessTree: プロセスツリー管理・終了処理

**権限による制御**：ランチャー機能自体には権限制御はないが、ビルドステップの実行権限はジョブの設定とユーザー権限に依存する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | コンソール出力 | 結果表示画面 | プロセスの標準出力・エラー出力の表示 |
| 12 | ジョブ設定 | 参照画面 | シェルスクリプト等のビルドステップ設定 |

## 機能種別

プロセス制御 / システム連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| commands | List<String> | Yes | 実行するコマンドと引数のリスト | 空でないこと |
| masks | boolean[] | No | コマンド引数のマスク設定（ログ出力時に隠す部分） | commands と同じサイズ |
| envs | String[] | No | 環境変数オーバーライド（"KEY=VALUE" 形式） | = を含むこと |
| pwd | FilePath | No | 作業ディレクトリ | 存在するディレクトリ |
| stdin | InputStream | No | 標準入力ストリーム | - |
| stdout | OutputStream | No | 標準出力ストリーム | - |
| stderr | OutputStream | No | 標準エラー出力ストリーム | - |
| quiet | boolean | No | コマンドライン出力の抑制フラグ | - |

### 入力データソース

- ビルドステップ設定（ジョブ設定XML）
- ビルド実行時の環境変数（EnvVars）
- プラグインからの API 呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Proc | Proc | 起動されたプロセスへの参照 |
| exitCode | int | プロセスの終了コード |
| stdout | InputStream | 標準出力ストリーム（reverseStdout 時） |
| stderr | InputStream | 標準エラー出力ストリーム（reverseStderr 時） |

### 出力先

- TaskListener: コマンドライン出力
- 指定された OutputStream: プロセスの標準出力・エラー出力

## 処理フロー

### 処理シーケンス

```
1. ProcStarter の生成
   └─ launch() メソッドで新しい ProcStarter インスタンスを作成

2. プロセス設定の構築
   └─ cmds(), envs(), pwd(), stdout(), stderr(), stdin() でパラメータ設定

3. 環境変数の継承・展開
   └─ inherit() メソッドで現在の環境変数を継承し、オーバーライドを適用

4. 環境変数フィルタリング（オプション）
   └─ EnvVarsFilterRuleWrapper によるフィルタリングルール適用

5. プロセスの起動
   └─ LocalLauncher: ProcessBuilder を使用してローカルプロセス起動
   └─ RemoteLauncher: VirtualChannel 経由でリモートプロセス起動

6. 入出力ストリームの接続
   └─ stdin/stdout/stderr のリダイレクト設定

7. プロセスの監視・終了待機
   └─ join() メソッドで終了コードを取得
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ProcStarter 生成]
    B --> C[コマンド・環境変数設定]
    C --> D{ローカル or リモート?}
    D -->|ローカル| E[LocalLauncher.launch]
    D -->|リモート| F[RemoteLauncher.launch]
    E --> G[ProcessBuilder でプロセス起動]
    F --> H[VirtualChannel 経由でリモート起動]
    G --> I[入出力ストリーム接続]
    H --> I
    I --> J[プロセス実行]
    J --> K{join() 呼び出し?}
    K -->|Yes| L[終了コード取得]
    K -->|No| M[Proc オブジェクト返却]
    L --> N[終了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-01 | 環境変数継承 | プロセスは現在の環境変数を継承し、指定された変数でオーバーライドする | 常時 |
| BR-61-02 | PATH+ 記法 | PATH+XXX 形式の環境変数は既存の PATH に追加される | 環境変数名が PATH+ で始まる場合 |
| BR-61-03 | マスク出力 | masks で true が指定された引数は "********" として出力される | ログ出力時 |
| BR-61-04 | プロセスクッキー | プロセスツリー管理用のクッキー環境変数が自動設定される | launchChannel 時 |

### 計算ロジック

該当なし

## データベース操作仕様

### 操作別データベース影響一覧

該当なし（ランチャー機能はデータベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IOException | 入出力エラー | プロセス起動失敗、ストリーム操作失敗 | ビルド失敗として処理 |
| InterruptedException | 割り込み | プロセス待機中の割り込み | ビルド中断として処理 |
| InterruptedIOException | 割り込み(IO) | リモート呼び出し中の割り込み | ビルド中断として処理 |

### リトライ仕様

リトライ処理は行わない。プロセス起動に失敗した場合はビルド失敗となる。

## トランザクション仕様

該当なし（データベーストランザクションは使用しない）

## パフォーマンス要件

- プロセス起動のオーバーヘッドは最小限に抑える
- リモートプロセス起動時は VirtualChannel の効率的な利用
- 大量の出力がある場合のストリーム処理の効率化

## セキュリティ考慮事項

- コマンド引数のマスク機能によるパスワード等の保護
- 環境変数フィルタリングによる機密情報の制御
- プロセス実行権限はビルド実行者の権限に依存

## 備考

- Launcher は抽象クラスであり、具体的な実装として LocalLauncher、RemoteLauncher、DecoratedLauncher などがある
- decorateFor() メソッドで LauncherDecorator による拡張が可能
- decorateByPrefix() メソッドでコマンドの前にプレフィックスを追加可能（Docker コンテナ内実行等）
- decorateByEnv() メソッドで追加の環境変数を自動設定可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Launcher.java | `core/src/main/java/hudson/Launcher.java` | ProcStarter 内部クラス、IOTriplet、RemoteProcess インターフェースの構造を理解 |

**読解のコツ**: Launcher は抽象クラスであり、ProcStarter がビルダーパターンを使用している点に注目。186-557行目の ProcStarter クラスを最初に理解すると良い。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Launcher.java | `core/src/main/java/hudson/Launcher.java` | launch() メソッド（564-566行目）がエントリーポイント |

**主要処理フロー**:
1. **564-566行目**: launch() メソッドで新しい ProcStarter を生成
2. **506-508行目**: ProcStarter.start() で実際のプロセス起動
3. **516-543行目**: ProcStarter.join() で終了コード取得

#### Step 3: ローカルランチャーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Launcher.java | `core/src/main/java/hudson/Launcher.java` | LocalLauncher クラス（963-1062行目）の実装 |

**主要処理フロー**:
- **973-996行目**: LocalLauncher.launch() - ローカルプロセスの起動処理
- **978行目**: inherit() で環境変数を継承
- **991-995行目**: LocalProc を生成してプロセス起動
- **1004-1012行目**: launchChannel() - チャネル経由でのプロセス起動

#### Step 4: リモートランチャーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Launcher.java | `core/src/main/java/hudson/Launcher.java` | RemoteLauncher クラス（1091-1245行目）の実装 |

**主要処理フロー**:
- **1110-1140行目**: RemoteLauncher.launch() - リモートプロセスの起動
- **1119-1136行目**: RemoteLaunchCallable を使用してリモート呼び出し
- **1352-1418行目**: RemoteLaunchCallable の call() メソッドでエージェント側の処理

### プログラム呼び出し階層図

```
Launcher.launch()
    │
    └─ ProcStarter.start()
           │
           ├─ LocalLauncher.launch(ProcStarter)
           │      ├─ inherit() [環境変数継承]
           │      ├─ envVarsFilterRuleWrapper.filter() [フィルタリング]
           │      └─ new LocalProc() [プロセス生成]
           │
           └─ RemoteLauncher.launch(ProcStarter)
                  ├─ RemoteOutputStream/RemoteInputStream [ストリーム準備]
                  └─ channel.call(RemoteLaunchCallable)
                         └─ LocalLauncher.launch() [エージェント側]
```

### データフロー図

```
[入力]                      [処理]                           [出力]

コマンドライン引数 ───▶ ProcStarter.cmds() ───▶ Launcher.launch()
環境変数              ───▶ ProcStarter.envs()      │
作業ディレクトリ     ───▶ ProcStarter.pwd()       ▼
                                              LocalLauncher/RemoteLauncher
                                                     │
                                                     ▼
                                              ProcessBuilder/Channel
                                                     │
                                                     ▼
                                              Proc オブジェクト ───▶ 終了コード
                                                     │
                                              OutputStream ───────▶ 標準出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Launcher.java | `core/src/main/java/hudson/Launcher.java` | ソース | 外部プロセス起動の主要クラス |
| Proc.java | `core/src/main/java/hudson/Proc.java` | ソース | 起動されたプロセスを表すクラス |
| LocalProc.java | `core/src/main/java/hudson/Proc.java` | ソース | ローカルプロセスの実装 |
| EnvVars.java | `core/src/main/java/hudson/EnvVars.java` | ソース | 環境変数管理 |
| FilePath.java | `core/src/main/java/hudson/FilePath.java` | ソース | リモートファイルパス操作 |
| VirtualChannel.java | `remoting/.../VirtualChannel.java` | ソース | リモート通信チャネル |
| ProcessTree.java | `core/src/main/java/hudson/util/ProcessTree.java` | ソース | プロセスツリー管理 |
| LauncherDecorator.java | `core/src/main/java/hudson/LauncherDecorator.java` | ソース | ランチャー拡張ポイント |
