# 機能設計書 45-システム設定

## 概要

本ドキュメントは、JenkinsのシステムレベルのGlobal Configuration（グローバル設定）機能の設計を記載する。

### 本機能の処理概要

システム設定は、Jenkins全体に適用される設定を管理するための機能を提供する。GlobalConfiguration拡張ポイントにより、コアおよびプラグインが提供する設定項目を統一された画面で管理できる。

**業務上の目的・背景**：Jenkinsを運用するにあたり、システム全体の動作を制御する設定が必要である。Jenkins URL、ビルド実行エンジンの設定、セキュリティ設定、外部ツール連携設定などを一元的に管理することで、運用効率と保守性を向上させる。

**機能の利用シーン**：
- Jenkins初期セットアップ時のシステム設定
- セキュリティポリシー変更時の設定更新
- 外部ツール（Maven, JDK等）のパス設定
- クラウド/エージェント接続設定の変更
- プラグインが提供するグローバル設定の管理

**主要な処理内容**：
1. グローバル設定の表示（config.jelly/config.groovy）
2. 設定のロード（コンストラクタでload()呼び出し）
3. 設定の保存（setterでsave()呼び出し）
4. 設定のバインド（StaplerRequest.bindJSON）

**関連システム・外部連携**：全てのGlobalConfiguration拡張を統合して表示。プラグインによる拡張が可能。

**権限による制御**：設定の変更にはJenkins.ADMINISTERまたはJenkins.MANAGE権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | Jenkinsの設定 | 主画面 | グローバル設定の表示・編集・保存 |

## 機能種別

設定管理 / 構成管理

## 入力仕様

### 入力パラメータ

GlobalConfigurationは拡張ポイントとして設計されており、各実装クラスで固有のパラメータを定義する。共通的なフレームワークとしての入力仕様は以下の通り。

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| 設定項目（各実装で定義） | 各種 | 実装依存 | config.jelly/config.groovyで定義されたフォーム項目 | 各実装のdoCheck系メソッドで検証 |

### 入力データソース

- Web UIからのフォーム送信（StaplerRequest）
- XMLファイルからのロード（$JENKINS_HOME/{classname}.xml）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 設定値（各実装で定義） | 各種 | 各GlobalConfiguration実装で保持する設定値 |

### 出力先

- XMLファイル（$JENKINS_HOME/{classname}.xml）
- メモリ上の設定オブジェクト

## 処理フロー

### 処理シーケンス

#### 設定のロード

```
1. Jenkinsインスタンス初期化
2. GlobalConfiguration実装の発見
   └─ ExtensionList<GlobalConfiguration>の収集
3. 各実装のコンストラクタ実行
   └─ load()呼び出しでXMLから設定読み込み
4. 設定画面表示時
   └─ getConfigPage()でconfig.jellyのパスを返却
   └─ Staplerでconfig.jellyをレンダリング
```

#### 設定の保存

```
1. フォーム送信（/configure/submit）
2. StaplerRequest.bindJSON()
   └─ JSONObjectをGlobalConfigurationインスタンスにバインド
3. 各setterメソッドでsave()呼び出し
   └─ XMLファイルに永続化
4. SaveableListenerに通知
```

### フローチャート

```mermaid
flowchart TD
    A[Jenkinsの設定画面アクセス] --> B[権限チェック]
    B -->|権限あり| C[GlobalConfiguration.all()取得]
    B -->|権限なし| D[エラー: 権限不足]
    C --> E[各config.jellyをレンダリング]
    E --> F[フォーム表示]
    F --> G[ユーザー編集]
    G --> H[フォーム送信]
    H --> I[StaplerRequest.bindJSON()]
    I --> J[各setterでsave()]
    J --> K[XMLファイル保存]
    K --> L[SaveableListener通知]
    L --> M[リダイレクト]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-45-01 | 自動ロード | コンストラクタでload()を呼び出し、起動時に設定を自動読み込み | 全GlobalConfiguration |
| BR-45-02 | 自動保存 | setterでsave()を呼び出し、設定変更時に自動保存 | 全GlobalConfiguration |
| BR-45-03 | カテゴリ分類 | GlobalConfigurationCategoryでカテゴリ別に分類可能 | 設定画面表示 |
| BR-45-04 | BulkChange対応 | BulkChangeコンテキスト内ではsave()を遅延 | 複数設定の一括変更時 |

### 計算ロジック

該当なし

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

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

Jenkinsはファイルベースで設定を管理。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ロード | $JENKINS_HOME/{classname}.xml | READ | 起動時に設定読み込み |
| 保存 | $JENKINS_HOME/{classname}.xml | WRITE | 設定変更時に保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FormException | バリデーションエラー | 設定値が不正 | エラーメッセージに従って修正 |
| IOException | ファイル保存エラー | ディスク容量不足等 | ディスク状態を確認 |
| AccessDeniedException | 権限不足 | 必要な権限がない | 管理者に権限付与を依頼 |

### リトライ仕様

ファイル保存エラー時はリトライなし。ユーザーが再度保存操作を行う。

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

XMLファイルへの保存は原子的ではないが、XmlFileクラスが一時ファイルを経由したアトミック書き込みを実装。

## パフォーマンス要件

- 設定画面表示: 2秒以内（プラグイン数に依存）
- 設定保存: 1秒以内

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

- 設定変更にはJenkins.ADMINISTERまたはJenkins.MANAGE権限が必要
- パスワード等の機密情報はSecret型で暗号化保存
- CSRF保護トークンが必須

## 備考

- プラグインはGlobalConfigurationを継承して独自のグローバル設定を追加可能
- @Extensionアノテーションで自動登録
- config.groovyまたはconfig.jellyでフォームを定義

---

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

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

### 推奨読解順序

#### Step 1: GlobalConfiguration基盤を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GlobalConfiguration.java | `core/src/main/java/jenkins/model/GlobalConfiguration.java` | グローバル設定の基底クラス |
| 1-2 | Descriptor.java | `core/src/main/java/hudson/model/Descriptor.java` | 設定フレームワークの基盤 |

**主要処理フロー（GlobalConfiguration）**:
- **47-50行目**: Descriptor継承、ExtensionPoint実装
- **48-50行目**: コンストラクタでself()呼び出し（自己型参照）
- **53-55行目**: getDescriptor()で自身を返却
- **58-60行目**: getGlobalConfigPage()でconfig画面パス返却
- **68-73行目**: configure()でStaplerRequest.bindJSON()呼び出し
- **93-96行目**: all()で全GlobalConfigurationを取得

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

```
Jenkins 設定画面 (/configure)
    │
    ├─ GlobalConfiguration.all()
    │      └─ ExtensionList<GlobalConfiguration>
    │             ├─ JenkinsLocationConfiguration
    │             ├─ GlobalSecurityConfiguration
    │             ├─ GlobalToolConfiguration
    │             └─ ... (プラグイン提供設定)
    │
    ├─ 各config.jelly/config.groovyのレンダリング
    │
    └─ フォーム送信
           ├─ Descriptor.configure()
           │      └─ StaplerRequest.bindJSON()
           │
           ├─ setter呼び出し
           │      └─ save()
           │             └─ XmlFile.write()
           │
           └─ SaveableListener.fireOnChange()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GlobalConfiguration.java | `core/src/main/java/jenkins/model/GlobalConfiguration.java` | ソース | グローバル設定基底クラス |
| Descriptor.java | `core/src/main/java/hudson/model/Descriptor.java` | ソース | 設定フレームワーク基盤 |
| JenkinsLocationConfiguration.java | `core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java` | ソース | Jenkins URLとメール設定 |
| GlobalSecurityConfiguration.java | `core/src/main/java/hudson/security/GlobalSecurityConfiguration.java` | ソース | セキュリティ設定 |
| GlobalToolConfiguration.java | `core/src/main/java/jenkins/tools/GlobalToolConfiguration.java` | ソース | ツール設定 |
| XmlFile.java | `core/src/main/java/hudson/XmlFile.java` | ソース | XML永続化 |
