# 機能設計書 10-エージェントノード

## 概要

本ドキュメントは、Jenkinsのワーカーノードであるエージェントノード（hudson.model.Slave, hudson.model.Node）の機能設計を記述する。ビルドを実行するワーカーノードの管理を担う。

### 本機能の処理概要

Slaveクラス（およびその基底クラスNode）は、Jenkinsのエージェントノード（旧称スレーブ）を表現する。エージェントはコントローラーから指示を受けてビルドを実行する分散実行の要である。

**業務上の目的・背景**：大規模なCI/CD環境では、複数のエージェントにビルドを分散することで、並列実行性能の向上、特定環境（OS、ツールバージョン）でのビルド実行、コントローラーの負荷軽減を実現する。

**機能の利用シーン**：ビルドの分散実行、特定環境（Windows/Linux/Mac）でのビルド、Docker/Kubernetes環境でのビルド、クラウド上のオンデマンドエージェント利用。

**主要な処理内容**：
1. エージェントの登録・設定管理
2. エージェントへの接続（ComputerLauncher）
3. エグゼキュータの提供とビルド実行
4. ラベルによるジョブのルーティング
5. エージェント状態の監視（オンライン/オフライン）
6. リテンション戦略による可用性制御

**関連システム・外部連携**：SSH接続、JNLP接続、Docker、Kubernetes、クラウドプロバイダー（AWS、Azure、GCP等）。

**権限による制御**：Computer.CREATE（作成）、Computer.CONFIGURE（設定）、Computer.DELETE（削除）、Computer.DISCONNECT（切断）等。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | ノード一覧 | 参照画面 | エージェントノード情報の表示 |
| 22 | ノード詳細 | 参照画面 | ノードラベルの表示 |
| 23 | ノード設定 | 主画面 | ノード設定の編集 |
| 25 | ノードオフライン設定 | 主画面 | エージェント状態の管理 |

## 機能種別

ノード管理 / 分散実行 / リソース管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | ノード名 | 空でない文字列 |
| remoteFS | String | Yes | リモートファイルシステムのルート | 有効なパス |
| numExecutors | int | No | エグゼキュータ数 | 1以上 |
| mode | Mode | No | ジョブ割り当てモード | NORMAL/EXCLUSIVE |
| label | String | No | ノードラベル | 空白区切り文字列 |
| launcher | ComputerLauncher | Yes | 起動方法 | 非null |
| retentionStrategy | RetentionStrategy | No | 保持戦略 | 非null推奨 |

### 入力データソース

- nodes/{name}/config.xml: ノード設定ファイル
- Web画面: ノード管理画面からの設定
- CLI: create-node コマンド

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| name | String | ノード名 |
| description | String | ノードの説明 |
| remoteFS | String | リモートFS |
| numExecutors | int | エグゼキュータ数 |
| mode | Mode | 割り当てモード |
| launcher | ComputerLauncher | 起動方法 |
| retentionStrategy | RetentionStrategy | 保持戦略 |
| labelString | String | ラベル文字列 |

### 出力先

- nodes/{name}/config.xml: ノード設定
- Webインターフェース: ノード管理画面
- REST API: /computer/{name}/api/json

## 処理フロー

### 処理シーケンス

```
1. エージェント作成
   ├─ Slave インスタンス生成
   ├─ Jenkins.addNode() で登録
   └─ config.xml 保存
2. エージェント接続
   ├─ ComputerLauncher.launch() 実行
   ├─ Remoting チャネル確立
   └─ エグゼキュータ開始
3. ビルド実行
   ├─ Queue からジョブ割り当て
   ├─ FilePath でリモート操作
   └─ ビルドステップ実行
4. 切断/再接続
   ├─ オフライン設定
   ├─ RetentionStrategy による制御
   └─ 再接続試行
```

### フローチャート

```mermaid
flowchart TD
    A[エージェント作成] --> B[Slaveインスタンス生成]
    B --> C[Jenkins.addNode]
    C --> D[config.xml保存]
    D --> E[Computer生成]

    E --> F{接続開始}
    F --> G[ComputerLauncher.launch]
    G --> H{接続成功?}
    H -->|Yes| I[チャネル確立]
    H -->|No| J[リトライ/オフライン]
    I --> K[エグゼキュータ開始]
    K --> L[オンライン状態]

    L --> M{ビルド要求?}
    M -->|Yes| N[ジョブ実行]
    M -->|No| O[アイドル状態]
    N --> L
    O --> L

    P[切断要求] --> Q[オフライン設定]
    Q --> R[チャネルクローズ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 名前必須 | ノード名は空にできない | 作成時 |
| BR-002 | 名前一意 | ノード名はJenkins内で一意 | 作成時 |
| BR-003 | エグゼキュータ数 | 1以上の値が必要 | 作成時 |
| BR-004 | ラベルマッチング | EXCLUSIVEモードではラベル必須 | ジョブ割り当て時 |
| BR-005 | 一時オフライン | オフライン原因を記録して一時停止可能 | 運用時 |

### 計算ロジック

- ラベル解析: Label.parse()で空白区切りのラベル文字列を解析

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

ファイルベースの永続化を使用。

### ファイル操作一覧

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定保存 | nodes/{name}/config.xml | 書き込み | ノード設定 |
| 設定読込 | nodes/{name}/config.xml | 読み取り | 起動時復元 |
| 削除 | nodes/{name}/ | ディレクトリ削除 | ノード削除時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | FormException | 無効なノード名 | 有効な名前を指定 |
| - | IOException | 接続失敗 | ネットワーク・設定確認 |
| - | ChannelClosedException | チャネル切断 | 再接続試行 |

### リトライ仕様

接続失敗時はRetentionStrategyに従ってリトライ。

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

ノード設定変更はconfig.xmlへのアトミック書き込み。

## パフォーマンス要件

- 接続確立: 数秒〜数十秒（ネットワーク依存）
- リモート操作: Remotingのレイテンシに依存
- エグゼキュータ開始: 即時

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

- 接続認証: エージェントの認証が必要
- 通信暗号化: SSH/TLS推奨
- 権限分離: エージェントでの実行は制限されたユーザーで

## 備考

- 2016年に"slave"から"agent"への名称変更
- DumbSlaveが最も基本的なエージェント実装
- CloudでEphemeralNodeの動的プロビジョニング可能

---

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

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

### 推奨読解順序

#### Step 1: クラス階層を理解する

NodeとSlaveの関係を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Node.java | `core/src/main/java/hudson/model/Node.java` | 抽象クラスNode（107行目）の基本構造 |
| 1-2 | Slave.java | `core/src/main/java/hudson/model/Slave.java` | SlaveクラスがNode継承（107行目） |

**読解のコツ**: NodeはJenkinsも継承しているため、共通インターフェースを理解することが重要。Slaveは具体的なエージェントの実装。

#### Step 2: 主要フィールドを理解する

Slaveクラスのフィールドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Slave.java | `core/src/main/java/hudson/model/Slave.java` | name（114行目）、remoteFS（129行目）、numExecutors（134行目）を確認 |
| 2-2 | Slave.java | `core/src/main/java/hudson/model/Slave.java` | launcher（149行目）、retentionStrategy（144行目）を確認 |

**主要処理フロー**:
1. **114行目**: name（エージェント名）
2. **119行目**: description（説明）
3. **129行目**: remoteFS（リモートファイルシステムルート）
4. **134行目**: numExecutors（デフォルト1）
5. **139行目**: mode（NORMAL/EXCLUSIVE）
6. **144行目**: retentionStrategy
7. **149行目**: launcher

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

ComputerLauncherによる接続方法を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Slave.java | `core/src/main/java/hudson/model/Slave.java` | getLauncher()（242-253行目）でJNLPLauncherのフォールバック |

#### Step 4: ノードプロパティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Slave.java | `core/src/main/java/hudson/model/Slave.java` | nodeProperties（156-157行目）のDescribableList |

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

```
Slave extends Node
    │
    ├─ name (エージェント名)
    │
    ├─ remoteFS (リモートファイルシステムルート)
    │
    ├─ numExecutors (エグゼキュータ数、デフォルト1)
    │
    ├─ mode (NORMAL/EXCLUSIVE)
    │
    ├─ launcher: ComputerLauncher
    │      ├─ JNLPLauncher (JNLP接続)
    │      ├─ SSHLauncher (SSH接続、プラグイン)
    │      └─ CommandLauncher (コマンド実行)
    │
    ├─ retentionStrategy: RetentionStrategy
    │      ├─ Always (常時オンライン)
    │      ├─ Demand (オンデマンド)
    │      └─ Schedule (スケジュール)
    │
    └─ nodeProperties: DescribableList
           └─ 環境変数、ツール設定等
```

### データフロー図

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

ノード設定 ─────────────▶ Slave生成 ────────────────▶ nodes/{name}/config.xml
                                │
                                ▼
ComputerLauncher ───────▶ 接続確立 ────────────────▶ Remotingチャネル
                                │
                                ▼
ビルド要求 ─────────────▶ FilePath経由実行 ─────────▶ リモートビルド結果
                                │
                                ▼
完了/切断 ─────────────▶ クリーンアップ ────────────▶ オフライン状態
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Node.java | `core/src/main/java/hudson/model/Node.java` | ソース | ノード抽象クラス |
| Slave.java | `core/src/main/java/hudson/model/Slave.java` | ソース | エージェント実装 |
| DumbSlave.java | `core/src/main/java/hudson/slaves/DumbSlave.java` | ソース | 基本エージェント |
| ComputerLauncher.java | `core/src/main/java/hudson/slaves/ComputerLauncher.java` | ソース | 起動方法基底クラス |
| JNLPLauncher.java | `core/src/main/java/hudson/slaves/JNLPLauncher.java` | ソース | JNLP起動 |
| RetentionStrategy.java | `core/src/main/java/hudson/slaves/RetentionStrategy.java` | ソース | 保持戦略 |
| SlaveComputer.java | `core/src/main/java/hudson/slaves/SlaveComputer.java` | ソース | エージェントコンピューター |
| configure.jelly | `core/src/main/resources/hudson/model/Slave/configure.jelly` | テンプレート | 設定画面 |
