# 通知設計書 24-OS終末期警告

## 概要

本ドキュメントは、Jenkinsが稼働しているオペレーティングシステムがサポート終了（End of Life）に近い場合に管理者へ警告を表示する通知機能（OperatingSystemEndOfLifeAdminMonitor）の設計仕様を定義する。

### 本通知の処理概要

本通知は、Jenkinsコントローラーが動作しているOSのサポート終了日が近づいている場合、または既にサポート終了を迎えている場合に、管理者に対して警告を表示し、OSのアップグレードを促す機能を提供する。

**業務上の目的・背景**：サポートが終了したOSはセキュリティパッチが提供されなくなり、深刻な脆弱性にさらされるリスクがある。特にCI/CDサーバーは重要なインフラストラクチャであるため、事前に管理者に通知し、計画的なOSアップグレードを促す必要がある。

**通知の送信タイミング**：サポート終了日の6ヶ月前（デフォルト）から警告が表示され始める。管理画面へのアクセス時に表示される。サポート終了日を過ぎている場合は、より強い警告として表示される。

**通知の受信者**：Jenkins.SYSTEM_READ権限を持つユーザーが管理画面を閲覧した際に表示される。

**通知内容の概要**：現在使用中のOS名、サポート終了日、推奨されるアクション（OSのアップグレード）が表示される。

**期待されるアクション**：管理者はJenkinsのドキュメントを参照し、サポートされているOSバージョンへのマイグレーションを計画・実施する。

## 通知種別

アプリ内通知（Jenkins管理画面への警告バナー表示）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（画面アクセス時にチェック） |
| 優先度 | 高（サポート終了後はさらに高） |
| リトライ | 無し |

### 送信先決定ロジック

AdministrativeMonitorとして実装されているため、`/manage`画面にアクセスしたユーザーに対して表示される。表示条件は以下の通り：
- モニターが有効であること
- 警告開始日（サポート終了日の6ヶ月前）を過ぎていること
- /etc/os-releaseからOSが識別可能であること

## 通知テンプレート

### 画面通知の場合

| 項目 | 内容 |
|-----|------|
| 表示名 | Operating system end of life monitor |
| 表示位置 | 管理画面のAdministrativeMonitorセクション |
| 形式 | 警告バナー |

### 本文テンプレート

```
You are running Jenkins on {operatingSystemName} which will reach end of life on {endOfLifeDate}.
Please consider upgrading to a supported operating system version.
```

（サポート終了後）
```
You are running Jenkins on {operatingSystemName} which has already reached end of life on {endOfLifeDate}.
Please upgrade to a supported operating system version as soon as possible.
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| operatingSystemName | OS名 | /etc/os-releaseのPRETTY_NAME | Yes |
| endOfLifeDate | サポート終了日 | end-of-life-data.json | Yes |
| afterEndOfLifeDate | 終了日を過ぎているか | LocalDate.now()との比較 | Yes |
| documentationUrl | ドキュメントURL | 動的に生成 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | 管理画面アクセス | 警告開始日を過ぎている | サポート終了6ヶ月前から |
| 画面操作 | 管理画面アクセス | 終了日を過ぎている | より強い警告として表示 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| モニターが無効化されている | isEnabled()がfalse |
| ignoreEndOfLifeフラグがtrue | テスト用フラグ |
| 警告開始日より前 | まだ警告期間に入っていない |
| OSが識別できない | /etc/os-releaseが存在しない等 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[管理画面アクセス] --> B{モニター有効?}
    B -->|No| I[表示なし]
    B -->|Yes| C[OSデータ読み込み]
    C --> D[/etc/os-release解析]
    D --> E{OS識別可能?}
    E -->|No| I
    E -->|Yes| F{警告開始日を過ぎている?}
    F -->|No| I
    F -->|Yes| G{終了日を過ぎている?}
    G -->|Yes| H[強い警告表示]
    G -->|No| J[通常警告表示]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（ファイルシステムとJSONデータを使用）

### 参照データ

| データ | 内容 |
|--------|------|
| /etc/os-release | OSのPRETTY_NAME取得 |
| end-of-life-data.json | OS別のサポート終了日定義 |

### 更新対象

| 対象 | 操作 | 概要 |
|------|------|------|
| モニター設定 | UPDATE | disable(true)で無効化 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ファイル読み込みエラー | /etc/os-releaseが存在しない | OSを識別不能として処理 |
| JSON解析エラー | end-of-life-data.jsonが不正 | IOExceptionをスロー |
| 設定保存失敗 | ファイルシステムエラー | IOException発生、ログ出力 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（管理画面アクセス時に表示）

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

- 表示にはJenkins.SYSTEM_READ権限が必要
- 無効化操作にはJenkins.ADMINISTER権限が必要
- /etc/os-releaseの読み取りにはファイルシステムアクセス権限が必要
- 外部リンク（jenkins.io）へのリダイレクトを含む

## 備考

- 主にLinuxベースのOSを対象としている
- デフォルトの警告開始は終了日の6ヶ月前だが、JSON設定で個別に指定可能
- ドキュメントURLはOS名から動的に生成される
- @Symbolアノテーションで"operatingSystemEndOfLife"として参照可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OperatingSystemEndOfLifeAdminMonitor.java | `core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java` | フィールド定義（73-82行目） |

**読解のコツ**: warningsStartDate、afterEndOfLifeDate、operatingSystemName、endOfLifeDate、documentationUrlの5つのフィールドがモニターの状態を保持する。

#### Step 2: 初期化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OperatingSystemEndOfLifeAdminMonitor.java | `core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java` | fillOperatingSystemList()メソッド（93-103行目） |
| 2-2 | OperatingSystemEndOfLifeAdminMonitor.java | `core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java` | readOperatingSystemList()メソッド（106-166行目） |

**主要処理フロー**:
1. **93-103行目**: クラスパスからend-of-life-data.jsonを読み込み
2. **106-166行目**: JSONを解析し、各OSのパターンとマッチング
3. **128-161行目**: マッチした場合、サポート終了日と警告開始日を設定

#### Step 3: OS識別処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OperatingSystemEndOfLifeAdminMonitor.java | `core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java` | readOperatingSystemName()メソッド（183-205行目） |

**主要処理フロー**:
- **187行目**: PRETTY_NAMEパターンでOS名を抽出
- **190-195行目**: /etc/os-releaseの各行をパターンマッチ

#### Step 4: アクション処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | OperatingSystemEndOfLifeAdminMonitor.java | `core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java` | doAct()メソッド（255-267行目） |

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

```
Jenkins管理画面 (/manage)
    │
    └─ OperatingSystemEndOfLifeAdminMonitor
           │
           ├─ コンストラクタ
           │      └─ fillOperatingSystemList()
           │             └─ readOperatingSystemList()
           │                    ├─ getDataFile()
           │                    └─ readOperatingSystemName()
           │
           ├─ isActivated()
           │      └─ LocalDate.now().isBefore(warningsStartDate)
           │
           ├─ getOperatingSystemName()
           ├─ getEndOfLifeDate()
           ├─ getAfterEndOfLifeDate()
           ├─ getDocumentationUrl()
           │
           └─ doAct() (POSTリクエスト)
                  ├─ disable(true)
                  └─ HttpRedirect(documentationUrl)
```

### データフロー図

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

end-of-life-data.json ───▶ readOperatingSystemList() ──┐
                                    │                   │
/etc/os-release ─────────▶ readOperatingSystemName() ──┼─▶ 警告表示
                                    │                   │
                              パターンマッチング         │
                                    │                   │
LocalDate.now() ─────────────────────────────────────────┘
                                    │
                              isActivated()
                                    │
                                    ▼
                          ┌─────────────────────────────┐
                          │ warningsStartDate以降: 表示  │
                          │ 終了日以降: 強い警告         │
                          └─────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OperatingSystemEndOfLifeAdminMonitor.java | `core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java` | ソース | メインモニター実装 |
| end-of-life-data.json | `core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/end-of-life-data.json` | 設定 | OSサポート終了日定義 |
| OperatingSystemEndOfLifeAdminMonitorTest.java | `core/src/test/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitorTest.java` | テスト | 単体テスト |
