# 機能設計書 1-Jenkins本体

## 概要

本ドキュメントは、Jenkinsのコア機能であるJenkins本体（jenkins.model.Jenkins）の機能設計を記述する。Jenkinsシステム全体を統括するルートオブジェクトとして、プラグイン管理、ジョブ管理、ノード管理、セキュリティ、設定管理などの中核機能を提供する。

### 本機能の処理概要

Jenkins本体は、オープンソースの自動化サーバーとしてCI/CDパイプラインを構築・管理するためのコアプラットフォームを提供する。

**業務上の目的・背景**：ソフトウェア開発における継続的インテグレーション（CI）と継続的デリバリー（CD）を実現するため、ビルド、テスト、デプロイの自動化プラットフォームとして機能する。開発チームの生産性向上、品質管理の効率化、リリースサイクルの短縮を目的とする。

**機能の利用シーン**：開発者がコードをコミットした際の自動ビルド・テスト実行、定期的なビルドスケジュール管理、複数のビルドエージェントへのジョブ分散実行、ビルド結果の通知・可視化など、開発ライフサイクル全般で利用される。

**主要な処理内容**：
1. Jenkinsインスタンスの初期化・起動処理（InitMilestoneに基づく段階的初期化）
2. プラグインのロードと拡張機能の管理（PluginManager経由）
3. ジョブ（Item）の作成・管理・実行スケジューリング
4. ノード（Agent）の管理とビルドの分散実行
5. セキュリティ（認証・認可）の統括管理
6. システム設定の永続化とXML形式での保存
7. RESTful APIの提供とWebインターフェースの基盤

**関連システム・外部連携**：SCM（Git、SVN等）、ビルドツール（Maven、Gradle等）、アーティファクトリポジトリ、通知システム（メール、Slack等）、LDAPなどの認証プロバイダーとの連携が可能。

**権限による制御**：管理者権限（ADMINISTER）を持つユーザーのみがシステム設定の変更、プラグイン管理、ノード管理などの操作が可能。ジョブの操作はJob単位の権限設定に依存する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | システム設定 | 主画面 | Jenkinsグローバル設定の編集 |
| 31 | システム情報 | 参照画面 | Jenkinsシステム情報の表示 |
| 33 | スレッドダンプ | 参照画面 | JVMスレッドダンプの取得と表示 |
| 34 | 再起動 | 主画面 | Jenkinsの再起動処理 |
| 35 | 安全な再起動 | 主画面 | ジョブ完了待機後の再起動処理 |
| 36 | Jenkinsについて | 参照画面 | バージョン・ライセンス情報の表示 |
| 53 | インスタンス設定 | 主画面 | JenkinsインスタンスURL等の設定 |
| 60 | スクリプトコンソール | 主画面 | Groovyスクリプトの実行 |
| 63 | ヒープダンプ | 参照画面 | JVMヒープダンプの取得 |
| 69 | 404エラー | 結果表示画面 | リソース未検出エラーの表示 |
| 70 | 500エラー（Oops） | 結果表示画面 | 内部エラーの表示 |

## 機能種別

コア機能 / システム管理 / プラットフォーム基盤

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| numExecutors | int | No | ビルトインノードのエグゼキュータ数 | 0以上の整数 |
| mode | Mode | No | ジョブ割り当て戦略（NORMAL/EXCLUSIVE） | enum値 |
| systemMessage | String | No | ダッシュボードに表示するメッセージ | なし |
| quietPeriod | Integer | No | デフォルトの待機時間（秒） | 0以上の整数 |
| scmCheckoutRetryCount | int | No | SCMチェックアウトのリトライ回数 | 0以上の整数 |
| slaveAgentPort | int | No | TCPエージェントポート | -1（無効）、0（ランダム）、または有効なポート番号 |
| label | String | No | ビルトインノードに割り当てるラベル | 空白区切りのラベル文字列 |

### 入力データソース

- config.xml: Jenkinsのルート設定ファイル（$JENKINS_HOME/config.xml）
- 環境変数: JENKINS_HOME等のシステムプロパティ
- Web画面: 管理画面からのフォーム入力
- REST API: /api/json または /api/xml 経由のリクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| version | String | Jenkinsのバージョン番号 |
| mode | Mode | 現在のジョブ割り当てモード |
| numExecutors | int | エグゼキュータ数 |
| quietPeriod | int | 待機時間設定 |
| useSecurity | boolean | セキュリティが有効かどうか |
| primaryView | String | デフォルトビュー名 |

### 出力先

- config.xml: 設定の永続化
- Webインターフェース: ダッシュボード、管理画面
- REST API: JSON/XML形式でのレスポンス
- ログファイル: jenkins.log（システムログ）

## 処理フロー

### 処理シーケンス

```
1. Jenkins起動
   └─ WebAppMain.contextInitialized()でServletContextを取得
2. Jenkinsインスタンス生成
   └─ コンストラクタでrootディレクトリ、ServletContextを受け取る
3. 初期化フェーズ実行（InitMilestone）
   ├─ STARTED: 起動開始
   ├─ PLUGINS_LISTED: プラグイン一覧取得完了
   ├─ PLUGINS_PREPARED: プラグイン準備完了
   ├─ PLUGINS_STARTED: プラグイン起動完了
   ├─ EXTENSIONS_AUGMENTED: 拡張機能拡張完了
   ├─ SYSTEM_CONFIG_LOADED: システム設定読み込み完了
   ├─ SYSTEM_CONFIG_ADAPTED: システム設定適用完了
   ├─ JOB_LOADED: ジョブ読み込み完了
   ├─ JOB_CONFIG_ADAPTED: ジョブ設定適用完了
   └─ COMPLETED: 初期化完了
4. 設定のロード
   └─ config.xmlからシステム設定を読み込み
5. ジョブのロード
   └─ jobsディレクトリ配下の各ジョブをロード
6. サービス開始
   └─ HTTPリクエストの受付開始
```

### フローチャート

```mermaid
flowchart TD
    A[Jenkins起動] --> B[WebAppMain.contextInitialized]
    B --> C[Jenkinsインスタンス生成]
    C --> D{STARTUP_MARKER_FILE存在?}
    D -->|No| E[初回起動処理]
    D -->|Yes| F[通常起動処理]
    E --> G[SetupWizard実行]
    F --> H[プラグインロード]
    G --> H
    H --> I[システム設定ロード]
    I --> J[ジョブロード]
    J --> K[ノードロード]
    K --> L[キュー初期化]
    L --> M[COMPLETED]
    M --> N[サービス開始]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | シングルトン | Jenkinsインスタンスは1つのみ存在可能 | 常時 |
| BR-002 | 初期化順序 | InitMilestoneの順序に従って初期化を実行 | 起動時 |
| BR-003 | 設定永続化 | 設定変更時はconfig.xmlに保存 | 設定変更時 |
| BR-004 | 権限チェック | 管理操作にはADMINISTER権限が必要 | 管理操作時 |
| BR-005 | 安全な再起動 | QuietDownモードでは新規ビルドをキューに入れない | 再起動準備中 |

### 計算ロジック

- エグゼキュータ負荷計算: OverallLoadStatistics.computeQueueLength()で待機中タスク数を算出
- ノードプロビジョニング判定: NodeProvisioner.update()で必要なノード数を動的に計算

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

Jenkinsはファイルベースの永続化を使用し、RDBMSは使用しない。

### ファイル操作一覧

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定保存 | config.xml | 書き込み | システム設定の永続化 |
| 設定読込 | config.xml | 読み取り | 起動時の設定復元 |
| シークレット | secret.key | 読み書き | 暗号化キーの管理 |
| キュー | queue.xml | 読み書き | ビルドキューの永続化 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IllegalStateException | 2つ目のJenkinsインスタンス生成試行 | 設計上発生しないはず、システム再起動 |
| - | IOException | config.xml読み書き失敗 | ファイルシステム権限確認 |
| - | ReactorException | 初期化中のエラー | ログ確認、プラグイン無効化 |
| - | AccessDeniedException | 権限不足 | 適切な権限を持つユーザーで操作 |

### リトライ仕様

設定保存失敗時は即時エラーとなり、自動リトライは行わない。

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

ファイルベース永続化のため、RDBMSトランザクションは存在しない。BulkChangeクラスを使用して複数の設定変更をバッチ処理し、最後にまとめて保存することで整合性を保つ。

## パフォーマンス要件

- 起動時間: ジョブ数・プラグイン数に依存するが、数十秒〜数分以内
- API応答時間: 通常100ms以内
- 同時接続数: JVMヒープサイズとスレッドプール設定に依存

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

- 認証: SecurityRealmによるユーザー認証（内蔵DB、LDAP、OAuth等）
- 認可: AuthorizationStrategyによる権限制御
- CSRF保護: CrumbIssuerによるトークン検証
- 機密情報: Secretクラスによる暗号化保存
- APIトークン: ユーザー毎のAPIアクセストークン管理

## 備考

- Jenkins.get()メソッドでシングルトンインスタンスにアクセス可能
- Groovyスクリプトコンソールから直接Jenkinsオブジェクトを操作可能
- プラグインによる拡張ポイント（ExtensionPoint）を多数提供

---

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

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

### 推奨読解順序

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

まず、Jenkinsクラスの主要なフィールドとその役割を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | Jenkinsクラスのフィールド定義（359-500行目）を確認し、queue、items、computers、cloudsなどの主要データ構造を把握する |

**読解のコツ**: Jenkinsクラスは約5000行の大規模クラスだが、まずフィールド定義（transientかどうか）を見て、永続化されるデータと実行時のみのデータを区別する。

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

Jenkinsの起動処理の流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | コンストラクタ（888-999行目）で初期化処理の全体像を理解 |

**主要処理フロー**:
1. **900-913行目**: theInstanceへの代入とシングルトン検証
2. **921-924行目**: Trigger.timerとqueueの初期化
3. **936-948行目**: secret.keyの生成または読み込み
4. **956-958行目**: PluginManagerの生成
5. **986-990行目**: executeReactorによる初期化タスク実行

#### Step 3: シングルトンアクセスパターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | get()メソッド（803-810行目）とgetInstanceOrNull()（837-841行目）の違いを理解 |

**主要処理フロー**:
- **803-810行目**: get()はnull時にIllegalStateExceptionをスロー
- **837-841行目**: getInstanceOrNull()はnullを許容

#### Step 4: 初期化マイルストーンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | InitMilestone.java | `core/src/main/java/hudson/init/InitMilestone.java` | 初期化の各段階を定義するenum |

#### Step 5: セキュリティ関連を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | authorizationStrategy、securityRealmフィールド（425-442行目）とsetSecurityRealm()メソッド |

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

```
WebAppMain.contextInitialized()
    │
    ├─ new Jenkins(root, context)
    │      ├─ PluginManager.createDefault(this)
    │      │      └─ LocalPluginManager()
    │      │             └─ プラグインのロード
    │      │
    │      ├─ executeReactor()
    │      │      ├─ pluginManager.initTasks()
    │      │      ├─ loadTasks()
    │      │      │      └─ ジョブの読み込み
    │      │      └─ InitMilestone.ordering()
    │      │
    │      └─ 各種初期化処理
    │
    └─ Jenkins.get() でアクセス可能に
```

### データフロー図

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

HTTPリクエスト ───────────▶ Stapler Webフレームワーク ───▶ HTMLレスポンス
                                    │
config.xml ────────────────▶ XStream2デシリアライズ ────▶ Jenkinsオブジェクト
                                    │
REST API ──────────────────▶ API クラス ────────────────▶ JSON/XMLレスポンス
                                    │
Groovyスクリプト ──────────▶ GroovyShell実行 ────────────▶ 実行結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | ソース | Jenkinsコアクラス（シングルトン） |
| InitMilestone.java | `core/src/main/java/hudson/init/InitMilestone.java` | ソース | 初期化段階の定義 |
| WebAppMain.java | `core/src/main/java/hudson/WebAppMain.java` | ソース | サーブレット初期化 |
| AbstractCIBase.java | `core/src/main/java/hudson/model/AbstractCIBase.java` | ソース | Jenkinsの基底クラス |
| config.xml | `$JENKINS_HOME/config.xml` | 設定 | システム設定ファイル |
| index.jelly | `core/src/main/resources/jenkins/model/Jenkins/index.jelly` | テンプレート | ダッシュボード画面 |
| configure.jelly | `core/src/main/resources/jenkins/model/Jenkins/configure.jelly` | テンプレート | システム設定画面 |
