# 機能設計書 115-ランナー管理

## 概要

本ドキュメントは、GitLab管理画面におけるランナー管理機能の設計仕様を記述する。システム管理者がCI/CDジョブを実行する全Runnerの一覧表示、詳細閲覧、編集、登録を行うための機能である。

### 本機能の処理概要

**業務上の目的・背景**：GitLab CI/CDでは、パイプラインのジョブを実行するためにRunnerが必要である。システム管理者はインスタンス全体のRunner（インスタンスRunner、グループRunner、プロジェクトRunner）を監視・管理し、適切なリソース配分とセキュリティを維持する必要がある。本機能は管理者がRunnerの状態確認、設定変更、新規登録を行うための機能である。

**機能の利用シーン**：
- インスタンス全体のRunner状況の把握
- Runnerの設定変更（タグ、実行条件、タイムアウト等）
- 新規Runnerの登録
- 問題のあるRunnerの特定と対処
- Runnerへのプロジェクト割り当て管理

**主要な処理内容**：
1. Runner一覧の表示
2. Runner詳細情報の表示
3. Runner設定の編集
4. 新規Runner作成ウィザードの表示
5. Runner登録画面の表示
6. Runner設定の更新
7. タグ一覧の取得（オートコンプリート用）
8. Runnerセットアップスクリプトの提供

**関連システム・外部連携**：
- GitLab Runnerアプリケーション（ジョブ実行エージェント）
- CI/CDパイプラインシステム

**権限による制御**：
- 本機能は管理者（Admin）権限を持つユーザーのみがアクセス可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 258 | Runner一覧 | 主画面 | システムRunner一覧表示 |
| 259 | Runner詳細 | 主画面 | システムRunner詳細表示 |
| 260 | Runner新規登録 | 主画面 | システムRunner登録 |
| 261 | Runner編集 | 主画面 | システムRunner編集 |

## 機能種別

CRUD操作（Read/Update） / 登録管理

## 入力仕様

### 入力パラメータ

#### Runner編集時

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| description | String | No | Runner説明 | テキスト |
| tag_list | Array[String] | No | タグ一覧 | 最大50個 |
| active | Boolean | No | アクティブ状態 | true/false |
| run_untagged | Boolean | No | タグなしジョブ実行 | true/false |
| locked | Boolean | No | ロック状態 | true/false |
| access_level | Integer | No | アクセスレベル | not_protected(0)/ref_protected(1) |
| maximum_timeout_human_readable | String | No | 最大タイムアウト | 人間可読形式（例: "1h 30m"） |
| public_projects_minutes_cost_factor | Float | No | 公開プロジェクトコストファクター | 数値（Gitlab.com専用） |
| private_projects_minutes_cost_factor | Float | No | 非公開プロジェクトコストファクター | 数値（Gitlab.com専用） |

#### タグ検索時

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| search | String | No | タグ検索キーワード | 文字列 |

### 入力データソース

- 画面入力（Runner編集フォーム）
- URLパラメータ（Runner ID、検索パラメータ）
- セッション情報（現在の管理者ユーザー）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| runners | Array[Ci::Runner] | Runner一覧データ |
| runner | Ci::Runner | 個別Runner詳細データ |
| projects | Array[Project] | Runner割り当て可能なプロジェクト一覧 |
| tags | Array[Ci::Tag] | タグ一覧（オートコンプリート用） |
| setup_scripts | Hash | セットアップスクリプト情報 |

### 出力先

- 画面表示（HTML/JSON）
- リダイレクト（更新完了後）

## 処理フロー

### 処理シーケンス

```
1. Runner一覧表示（index）
   └─ render（Vue.jsコンポーネントで描画）
2. Runner詳細表示（show）
   └─ Ci::Runner.find → render
3. Runner編集画面表示（edit）
   └─ runner → assign_projects → render
4. 新規Runner作成画面表示（new）
   └─ render（作成ウィザード）
5. Runner登録画面表示（register）
   └─ registration_available? → render or 404
6. Runner更新（update）
   └─ Ci::Runners::UpdateRunnerService#execute → redirect or render
7. タグ一覧取得（tag_list）
   └─ Ci::TagsFinder#execute → JSON render
8. セットアップスクリプト取得（runner_setup_scripts）
   └─ private_runner_setup_scripts → JSON render
```

### フローチャート

```mermaid
flowchart TD
    A[管理者がRunner管理画面にアクセス] --> B{操作種別}
    B -->|一覧表示| C[index画面表示]

    B -->|詳細表示| D[Ci::Runner.find]
    D --> E[詳細画面表示]

    B -->|編集| F[edit画面表示]
    F --> G[assign_projects]
    G --> H[プロジェクト一覧取得]
    H --> I[編集フォーム表示]
    I --> J[フォーム入力]
    J --> K[UpdateRunnerService.execute]
    K --> L{成功?}
    L -->|Yes| M[編集画面へリダイレクト]
    L -->|No| N[詳細画面表示（エラー）]

    B -->|新規作成| O[new画面表示]

    B -->|登録| P{registration_available?}
    P -->|Yes| Q[register画面表示]
    P -->|No| R[404エラー]

    B -->|タグ取得| S[Ci::TagsFinder.execute]
    S --> T[JSON応答]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-115-01 | タグ数上限 | タグは最大50個まで設定可能 | Runner編集時 |
| BR-115-02 | タグ検索上限 | タグオートコンプリートは最大20件まで返却 | タグ一覧取得時 |
| BR-115-03 | 登録可否チェック | registration_available?がtrueの場合のみ登録画面を表示 | 登録画面表示時 |
| BR-115-04 | コストファクター | Gitlab.comの場合のみコストファクター設定が編集可能 | Runner編集時 |
| BR-115-05 | プロジェクト除外 | 編集画面のプロジェクト一覧から、既にRunnerに割り当て済みのプロジェクトを除外 | 編集画面表示時 |

### 計算ロジック

- タイムアウトは人間可読形式（ChronicDuration）で入力・表示

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧表示 | ci_runners | SELECT | Runner一覧取得 |
| 詳細表示 | ci_runners, runner_projects | SELECT | Runner関連情報取得 |
| 編集画面表示 | ci_runners, projects | SELECT | Runner情報とプロジェクト一覧取得 |
| 更新 | ci_runners, taggings, ci_runner_projects | UPDATE/INSERT/DELETE | Runner情報、タグ、プロジェクト関連更新 |
| タグ取得 | tags | SELECT | タグ検索 |

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

#### ci_runnersテーブル

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, description, active, run_untagged, locked等 | ID指定 | |
| UPDATE | description, active, run_untagged, locked, access_level, maximum_timeout等 | フォーム入力値 | UpdateRunnerService経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | 存在しないリソース | 指定されたRunnerが見つからない、または登録不可 | 404エラーページ表示 |
| 422 | バリデーションエラー | 入力値が不正 | エラーメッセージを表示して詳細画面を再表示 |

### リトライ仕様

特になし

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

- Runner更新はUpdateRunnerService内で単一トランザクションとして処理

## パフォーマンス要件

- プロジェクト検索：`search`パラメータがある場合のみ検索を実行
- プロジェクト一覧：ページネーション対応（30件/ページ、カウントなし）

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

- 管理者権限（Admin）が必須
- Runner登録トークンは一定時間（REGISTRATION_AVAILABILITY_TIME = 1時間）のみ有効

## 備考

- 本機能はEnterprise Edition（EE）で拡張される可能性があり、`prepend_mod`によりモジュールが追加される
- Runner一覧はVue.jsコンポーネントで描画される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | runner.rb | `app/models/ci/runner.rb` | Ci::Runnerモデルの属性、状態、タイプ（instance/group/project）を理解 |

**読解のコツ**: Runnerには3種類のタイプ（instance_type, group_type, project_type）があり、それぞれスコープが異なる。`FORM_EDITABLE`定数で編集可能な属性が定義されている。

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

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

**主要処理フロー**:
1. **6行目**: TAGS_LIMIT = 20 - タグオートコンプリートの上限
2. **16行目**: `index`アクション - 一覧表示
3. **18行目**: `show`アクション - 詳細表示
4. **20-22行目**: `edit`アクション - 編集画面、プロジェクト割り当て
5. **26-28行目**: `register`アクション - 登録可否チェック
6. **30-39行目**: `update`アクション - UpdateRunnerService経由の更新
7. **41-45行目**: `tag_list`アクション - タグ検索

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | update_runner_service.rb | `app/services/ci/runners/update_runner_service.rb` | Runner更新ロジック |

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

```
Admin::RunnersController
    │
    ├─ index
    │      └─ (Vue.jsコンポーネントで描画)
    │
    ├─ show
    │      └─ Ci::Runner.find
    │
    ├─ edit
    │      ├─ runner
    │      └─ assign_projects
    │             ├─ Project.search (if params[:search])
    │             └─ @projects.id_not_in(runner_projects_ids)
    │
    ├─ new
    │      └─ (作成ウィザード表示)
    │
    ├─ register
    │      └─ runner.registration_available?
    │
    ├─ update
    │      └─ Ci::Runners::UpdateRunnerService#execute
    │
    ├─ tag_list
    │      └─ Ci::TagsFinder#execute
    │
    └─ runner_setup_scripts
           └─ private_runner_setup_scripts (RunnerSetupScripts module)
```

### データフロー図

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

管理者操作 ───────▶ Admin::RunnersController ───────▶ HTMLレスポンス
  │                      │                              │
  │                      ▼                              │
  │       Ci::Runners::UpdateRunnerService              │
  │                      │                              │
  │                      ▼                              │
  │              Ci::Runner Model                       │
  │                      │                              │
  └──────────────▶ ci_runners テーブル ────────────────▶ Runner設定反映
                         │
                         ▼
                  関連テーブル
           (taggings, ci_runner_projects)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| runners_controller.rb | `app/controllers/admin/runners_controller.rb` | コントローラー | Runner管理のエントリーポイント |
| runner.rb | `app/models/ci/runner.rb` | モデル | Runnerデータモデル |
| update_runner_service.rb | `app/services/ci/runners/update_runner_service.rb` | サービス | Runner更新ロジック |
| tags_finder.rb | `app/finders/ci/tags_finder.rb` | ファインダー | タグ検索ロジック |
| tag_serializer.rb | `app/serializers/ci/tag_serializer.rb` | シリアライザー | タグのJSON変換 |
| runner_setup_scripts.rb | `app/controllers/concerns/runner_setup_scripts.rb` | コンサーン | セットアップスクリプト生成 |
