# 画面設計書 25-ノードオフライン設定

## 概要

本ドキュメントは、Jenkins CI/CDサーバーにおける「ノードオフライン設定」画面の設計仕様を定義するものである。

### 本画面の処理概要

ノードオフライン設定画面は、特定のノード（エージェント）を一時的にオフラインに設定するための画面である。ノードをオフラインにする理由（メンテナンス、障害対応等）を入力し、ノードへの新規ジョブ割り当てを停止する。オフライン設定されたノードは、現在実行中のビルドが完了するまで待機し、その後新規ビルドを受け付けなくなる。

**業務上の目的・背景**：分散ビルド環境において、計画的なメンテナンスや緊急の障害対応時に、特定のノードを一時的に利用不可にする必要がある。この画面は、ノードを安全にオフライン状態に移行させ、オフライン理由を記録することで、チームメンバーへの情報共有と作業追跡を可能にする。オフライン理由を明確にすることで、ノード管理の透明性が向上する。

**画面へのアクセス方法**：ノード詳細画面の「Mark this node temporarily offline」ボタンをクリック、または直接URL `/computer/{nodeName}/markOffline` でアクセスする。

**主要な操作・処理内容**：
1. オフライン理由の入力 - テキストエリアにオフラインにする理由を入力
2. オフライン設定の実行 - 「Mark this node temporarily offline」ボタンで設定を適用
3. オフライン設定のキャンセル - 画面を離れて設定をキャンセル

**画面遷移**：
- 遷移元：ノード詳細画面
- 遷移先：ノード詳細画面（設定後）

**権限による表示制御**：
- Computer.DISCONNECT権限：オフライン設定操作に必要
- 権限がない場合は画面にアクセスできない

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | コンピューター管理 | 主機能 | ノードオフライン状態の設定 |

## 画面種別

入力

## URL/ルーティング

- `/computer/{nodeName}/markOffline` - ノードオフライン設定画面

## 入出力項目

| 項目名 | 項目ID | 入出力 | 型 | 必須 | 説明 |
|--------|--------|--------|-----|------|------|
| オフライン理由 | offlineMessage | 入力 | String | No | オフラインにする理由のテキスト |

## 表示項目

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|-----|------|
| ページタイトル | title | String | ノード名を含むタイトル |
| 現在の理由 | temporaryOfflineCauseReason | String | 既にオフラインの場合の現在の理由 |

## イベント仕様

### 1-Mark this node temporarily offlineボタン押下

「Mark this node temporarily offline」ボタン押下（POST changeOfflineCause）により、入力されたオフライン理由でノードをオフラインに設定する。処理完了後、ノード詳細画面へリダイレクトする。

### 2-Updateボタン押下（オフライン理由更新）

既にオフラインの場合、「Update」ボタン押下（POST changeOfflineCause）により、オフライン理由を更新する。処理完了後、ノード詳細画面へリダイレクトする。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| オフライン設定 | Node設定（メモリ） | UPDATE | temporaryOfflineCauseを設定 |

### テーブル別更新項目詳細

#### Node設定（メモリ上）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | temporaryOfflineCause | OfflineCause.UserCause(currentUser, message) | オフライン状態を設定 |

## メッセージ仕様

| メッセージID | メッセージ内容 | 表示条件 | 種別 |
|-------------|---------------|----------|------|
| - | Message | 常時表示 | ラベル |
| - | Mark this node temporarily offline | ボタンラベル（新規オフライン時） | ボタン |
| - | Update | ボタンラベル（理由更新時） | ボタン |

## 例外処理

| 例外条件 | 対応処理 |
|---------|---------|
| ノードが存在しない | 404エラー |
| 権限不足（DISCONNECT） | アクセス拒否（403） |

## 備考

- オフライン理由は空でも設定可能
- 設定後、ノードは新規ビルドを受け付けなくなるが、実行中ビルドは継続
- オフライン状態はJenkins再起動後も保持される（Node設定に保存）
- ビルトインノード（コントローラー）もオフラインに設定可能

---

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

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

### 推奨読解順序

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

まず、オフライン状態に関連するデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OfflineCause.java | `core/src/main/java/hudson/slaves/OfflineCause.java` | オフライン理由の基底クラスと各サブクラス |
| 1-2 | UserCause | `core/src/main/java/hudson/slaves/OfflineCause.java` | ユーザー操作によるオフラインを表すクラス |

**読解のコツ**: OfflineCause.UserCauseはユーザーとメッセージを保持し、いつ誰がオフラインにしたかを追跡する。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | markOffline.jelly | `core/src/main/resources/hudson/model/Computer/markOffline.jelly` | 画面のビューテンプレート |

**主要処理フロー**:
1. **行26-27**: レイアウト開始、タイトル設定
2. **行31**: sidepanel.jellyのインクルード
3. **行33**: setOfflineCause.jellyのインクルード（フォーム部分）

#### Step 3: オフライン設定処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Computer.java | `core/src/main/java/hudson/model/Computer.java` | doChangeOfflineCause()メソッド（行1416-1421）で理由設定 |
| 3-2 | Computer.java | `core/src/main/java/hudson/model/Computer.java` | setTemporaryOfflineCause()メソッド（行725-731） |

**主要処理フロー**:
- **行1416-1421**: doChangeOfflineCause()がDISCONNECT権限をチェック後、setTemporaryOfflineCause()を呼び出し
- **行1419**: OfflineCause.UserCauseを生成（現在のユーザーとメッセージを設定）
- **行725-731**: setTemporaryOfflineCause()がNode.setTemporaryOfflineCause()に委譲

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

```
HTTP Request: GET /computer/{nodeName}/markOffline
    │
    ├─ Computer (Model Object)
    │      ├─ getTemporaryOfflineCauseReason() → 既存の理由
    │      └─ isTemporarilyOffline() → 現在のオフライン状態
    │
    └─ markOffline.jelly (View)
           └─ st:include setOfflineCause.jelly
                  ├─ f:form → changeOfflineCauseへPOST
                  ├─ f:textarea (offlineMessage)
                  └─ f:submit

HTTP Request: POST /computer/{nodeName}/changeOfflineCause
    │
    └─ Computer.doChangeOfflineCause()
           ├─ checkPermission(DISCONNECT)
           ├─ new OfflineCause.UserCause(User.current(), message)
           └─ setTemporaryOfflineCause(cause)
                  └─ Node.setTemporaryOfflineCause()
```

### データフロー図

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

フォーム入力値       Computer                 リダイレクト
offlineMessage ───▶ doChangeOfflineCause() ───▶ ノード詳細画面
                         │
                         ▼
                    OfflineCause.UserCause
                         │
                         ▼
                    setTemporaryOfflineCause()
                         │
                         ▼
                    Node.temporaryOfflineCause更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| markOffline.jelly | `core/src/main/resources/hudson/model/Computer/markOffline.jelly` | テンプレート | 画面表示用テンプレート |
| setOfflineCause.jelly | `core/src/main/resources/hudson/model/Computer/setOfflineCause.jelly` | テンプレート | オフライン理由入力フォーム |
| Computer.java | `core/src/main/java/hudson/model/Computer.java` | ソース | doChangeOfflineCause()による処理 |
| OfflineCause.java | `core/src/main/java/hudson/slaves/OfflineCause.java` | ソース | オフライン理由クラス |
| Node.java | `core/src/main/java/hudson/model/Node.java` | ソース | ノード設定クラス |
