# 機能設計書 51-Runnerレジストレーション

## 概要

本ドキュメントは、GitLabのCI/CDパイプラインを実行するためのRunner（ジョブ実行エージェント）の登録・管理機能について記述した機能設計書である。

### 本機能の処理概要

Runnerレジストレーション機能は、CI/CDジョブを実行するためのRunnerをGitLabインスタンスに登録し、プロジェクト、グループ、またはインスタンスレベルで管理するための機能である。

**業務上の目的・背景**：CI/CDパイプラインを実行するには、ジョブを実際に処理するコンピューティングリソース（Runner）が必要である。本機能により、組織はオンプレミスサーバー、クラウドインスタンス、コンテナ環境など、さまざまな実行環境をGitLabに統合し、自動化されたビルド・テスト・デプロイを実現できる。

**機能の利用シーン**：
- 新規プロジェクトでCI/CDを開始する際にRunnerを登録する場合
- 特定のプロジェクト専用の実行環境を用意する場合
- グループ全体で共有するRunnerを設定する場合
- インスタンス全体で使用可能な共有Runnerを管理する場合
- Runnerのメンテナンス時に一時停止・再開する場合

**主要な処理内容**：
1. Runnerの新規登録（プロジェクト/グループ/インスタンスレベル）
2. Runnerの設定編集（説明、タグ、実行設定など）
3. Runnerの一時停止（pause）と再開（resume）
4. Runnerの削除（unregister）
5. 共有Runnerの有効化/無効化
6. グループRunnerの有効化/無効化

**関連システム・外部連携**：
- GitLab Runner（ジョブ実行エージェント）
- Workhorse（Runner通信のプロキシ）
- Redis（Runnerキューの管理）

**権限による制御**：
- Runner閲覧: `read_runners`権限が必要
- Runner管理: `admin_runners`権限が必要
- Runner作成: `create_runners`権限が必要
- 個別Runner操作: `read_runner`, `update_runner`, `delete_runner`権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 112 | CI/CD設定 | 主画面 | Runner設定の管理 |
| 130 | Runner一覧 | 主画面 | プロジェクトRunnerの詳細表示 |
| 131 | Runner新規登録 | 主画面 | 新規Runnerの登録 |
| 132 | Runner編集 | 主画面 | Runner設定の編集 |
| 161 | Runner一覧 | 主画面 | グループRunnerの一覧表示 |
| 162 | Runner詳細 | 主画面 | グループRunnerの詳細表示 |
| 163 | Runner新規登録 | 主画面 | グループRunnerの登録 |
| 164 | Runner編集 | 主画面 | グループRunner設定の編集 |

## 機能種別

CRUD操作 / 状態管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| description | String | No | Runnerの説明 | 最大1024文字 |
| tag_list | Array<String> | No | タグリスト | 最大50タグ |
| active | Boolean | No | Runnerの有効/無効 | - |
| paused | Boolean | No | 一時停止状態 | - |
| run_untagged | Boolean | No | タグなしジョブの実行可否 | - |
| locked | Boolean | No | プロジェクトへのロック | - |
| access_level | String | No | アクセスレベル（not_protected/ref_protected） | enum値 |
| maximum_timeout | Integer | No | 最大タイムアウト時間（秒） | 600以上 |
| maintenance_note | String | No | メンテナンスノート | 最大1024文字 |

### 入力データソース

- 画面入力（Runner設定フォーム）
- API リクエスト（REST/GraphQL）
- Runner自身からの登録リクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | Runner ID |
| token | String | 認証トークン（登録時のみ表示） |
| description | String | 説明 |
| runner_type | String | タイプ（instance_type/group_type/project_type） |
| active | Boolean | 有効状態 |
| status | String | ステータス（online/offline/stale/never_contacted） |
| tag_list | Array | タグリスト |

### 出力先

- 画面表示（Runner一覧、詳細画面）
- API レスポンス（JSON）
- リダイレクト（設定画面への遷移）

## 処理フロー

### 処理シーケンス

```
1. ユーザー認証・権限確認
   └─ before_action で権限チェック

2. Runnerの登録/編集/削除
   └─ 該当するServiceクラスを呼び出し

3. 状態更新処理
   └─ Runner状態の変更（pause/resume）

4. Runner キューの更新
   └─ tick_runner_queue でWorkhorse通知

5. レスポンス生成
   └─ リダイレクトまたはJSONレスポンス
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{権限チェック}
    B -->|権限なし| C[アクセス拒否]
    B -->|権限あり| D{操作種別}
    D -->|新規登録| E[CreateRunnerService]
    D -->|編集| F[UpdateRunnerService]
    D -->|削除| G[UnregisterRunnerService]
    D -->|一時停止/再開| H[UpdateRunnerService]
    E --> I[Runner保存]
    F --> I
    G --> J[Runner削除]
    H --> I
    I --> K{保存成功?}
    K -->|Yes| L[成功レスポンス]
    K -->|No| M[エラーレスポンス]
    J --> L
    L --> N[終了]
    M --> N
    C --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-01 | Runnerタイプ制約 | インスタンスRunnerからプロジェクト/グループRunnerへの変更は不可 | Runner作成後 |
| BR-51-02 | タグ必須条件 | run_untaggedがfalseの場合、タグの設定が必須 | Runner保存時 |
| BR-51-03 | トークン有効期限 | 認証トークンは設定に応じた有効期限を持つ | トークン生成時 |
| BR-51-04 | プロジェクトRunner制約 | プロジェクトRunnerは少なくとも1つのプロジェクトに割り当てが必要 | Runner保存時 |
| BR-51-05 | グループRunner制約 | グループRunnerは正確に1つのグループに割り当てが必要 | Runner保存時 |

### 計算ロジック

- Runnerステータス判定：
  - `online`: 最終接触が2時間以内
  - `offline`: 最終接触が2時間超
  - `stale`: 7日間以上未接触または作成から7日以上経過し未接触
  - `never_contacted`: 一度も接触なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Runner登録 | ci_runners | INSERT | 新規Runnerレコード作成 |
| Runner登録 | ci_runner_projects | INSERT | プロジェクト関連付け（プロジェクトRunner時） |
| Runner登録 | ci_runner_namespaces | INSERT | グループ関連付け（グループRunner時） |
| Runner編集 | ci_runners | UPDATE | Runner設定更新 |
| Runner削除 | ci_runners | DELETE | Runnerレコード削除 |
| 一時停止/再開 | ci_runners | UPDATE | active フラグ更新 |

### テーブル別操作詳細

#### ci_runners

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | token_encrypted | 暗号化された認証トークン | 自動生成 |
| INSERT | runner_type | instance_type/group_type/project_type | 登録時に決定 |
| INSERT | registration_type | authenticated_user | UIからの登録時 |
| UPDATE | active | true/false | pause/resume時 |
| UPDATE | contacted_at | 現在時刻 | Runnerハートビート時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 権限不足 | 管理者に権限付与を依頼 |
| 404 | Not Found | Runner未検出 | 正しいRunner IDを確認 |
| 422 | Validation Error | バリデーション失敗 | 入力値を修正 |

### リトライ仕様

- Runner登録失敗時は自動リトライなし
- ハートビート失敗時はRunnerが自動リトライ

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

- Runner登録時はトランザクション内でRunner本体と関連テーブル（ci_runner_projects/ci_runner_namespaces）を同時に更新
- 削除時は関連するci_runner_projectsも自動削除（dependent: :destroy）

## パフォーマンス要件

- Runner一覧取得: 1秒以内
- Runner登録/更新: 2秒以内
- Runnerキュー通知: 即時（Redis経由）

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

- 認証トークンは暗号化して保存（token_encrypted）
- トークンは登録時のみ表示（後から参照不可）
- プロジェクト/グループ単位での権限チェック
- 監査ログへの操作記録

## 備考

- Runner登録後1時間以内に初期設定を完了する必要がある（REGISTRATION_AVAILABILITY_TIME）
- shared_runners_enabledの切り替えはプロジェクト設定として処理

---

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

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

### 推奨読解順序

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

まず、Runnerモデルの構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | runner.rb | `app/models/ci/runner.rb` | Runnerの属性、関連、バリデーション、スコープを理解する |

**読解のコツ**:
- `enum :runner_type` (43-47行目) でRunnerの3種類のタイプを確認
- `ONLINE_CONTACT_TIMEOUT` (68行目) と `STALE_TIMEOUT` (79行目) でステータス判定の閾値を確認
- `has_many :runner_projects` (99行目) と `has_many :runner_namespaces` (101行目) でRunnerとプロジェクト/グループの関連を確認

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

処理の起点となるコントローラーを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | runners_controller.rb | `app/controllers/projects/runners_controller.rb` | 各アクションの処理フローを確認 |

**主要処理フロー**:
- **24-26行目**: indexアクションはCI/CD設定画面へリダイレクト
- **36-39行目**: destroyアクションでUnregisterRunnerServiceを呼び出し
- **42-47行目**: resumeアクションでRunner有効化
- **50-55行目**: pauseアクションでRunner無効化
- **60-68行目**: toggle_shared_runnersで共有Runner切り替え

#### Step 3: サービス層を理解する

Runner操作の実際のビジネスロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create_runner_service.rb | `app/services/ci/runners/create_runner_service.rb` | Runner作成のビジネスロジック |
| 3-2 | update_runner_service.rb | `app/services/ci/runners/update_runner_service.rb` | Runner更新のビジネスロジック |
| 3-3 | unregister_runner_service.rb | `app/services/ci/runners/unregister_runner_service.rb` | Runner削除のビジネスロジック |

**主要処理フロー**:
- **CreateRunnerService 21-35行目**: パラメータ検証、ストラテジーパターンによるRunner種別ごとの処理、トランザクション内での保存
- **UpdateRunnerService 15-25行目**: パラメータ変換、更新、キュー通知
- **UnregisterRunnerService 15-18行目**: シンプルなdestroyによる削除

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

```
Projects::RunnersController
    │
    ├─ #destroy
    │      └─ Ci::Runners::UnregisterRunnerService#execute
    │             └─ Ci::Runner#destroy!
    │
    ├─ #pause / #resume
    │      └─ Ci::Runners::UpdateRunnerService#execute
    │             ├─ Ci::Runner#update
    │             └─ Ci::Runner#tick_runner_queue
    │
    └─ #toggle_shared_runners
           └─ Projects::UpdateService#execute
                  └─ Project#update
```

### データフロー図

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

Runner設定
フォーム    ───▶ RunnersController ───▶ 画面リダイレクト
                      │
                      ▼
              RunnerService
                      │
                      ▼
              Ci::Runner (Model)
                      │
                      ▼
              ci_runners テーブル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| runner.rb | `app/models/ci/runner.rb` | モデル | Runnerのデータモデル定義 |
| runners_controller.rb | `app/controllers/projects/runners_controller.rb` | コントローラー | プロジェクトレベルのRunner操作 |
| create_runner_service.rb | `app/services/ci/runners/create_runner_service.rb` | サービス | Runner作成ロジック |
| update_runner_service.rb | `app/services/ci/runners/update_runner_service.rb` | サービス | Runner更新ロジック |
| unregister_runner_service.rb | `app/services/ci/runners/unregister_runner_service.rb` | サービス | Runner削除ロジック |
| runner_project.rb | `app/models/ci/runner_project.rb` | モデル | RunnerとProject の関連 |
| runner_namespace.rb | `app/models/ci/runner_namespace.rb` | モデル | RunnerとGroup の関連 |
