# 機能設計書 29-StorageVersionMigratorコントローラー

## 概要

本ドキュメントは、KubernetesのStorageVersionMigratorコントローラーの機能設計を記述する。StorageVersionMigrationリソースに基づきストレージのバージョンマイグレーションを実行する。

### 本機能の処理概要

**業務上の目的・背景**：KubernetesのAPIリソースの保存形式（StorageVersion）が変更された場合、既存のetcd内オブジェクトを新しい形式に移行する必要がある。StorageVersionMigratorコントローラーは、StorageVersionMigrationリソースに基づいて全対象オブジェクトにServer-Side Apply（SSA）パッチを適用し、保存形式を最新に更新する。

**機能の利用シーン**：APIバージョンの変更後にStorageVersionMigrationリソースを作成することで、既存オブジェクトの保存形式を自動的に移行する。クラスターアップグレード時のデータマイグレーション。

**主要な処理内容**：
1. StorageVersionMigrationリソースの変更を監視する
2. 対象リソースのREST Mapperとディスカバリ情報を確認する
3. GCのGraphBuilderモニターから全対象オブジェクトの一覧を取得する
4. 各オブジェクトにSSAパッチ（UID + ResourceVersion precondition付き）を適用する
5. マイグレーション完了/失敗をStorageVersionMigrationのConditionsに記録する

**関連システム・外部連携**：API Server（SSAパッチ適用、StorageVersionMigration更新）、Garbage Collector（GraphBuilderのモニターストアを共有利用）

**権限による制御**：全リソースに対するget/list/watch/patch権限を持つサービスアカウントで動作する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本コントローラーに直接関連する画面はない |

## 機能種別

データ移行 / バッチ処理（バックグラウンド自動処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| workers | int | - | 固定5ワーカー | 定数 |

### 入力データソース

- StorageVersionMigration Informer: SVMリソースのadd/update/deleteイベント
- GC GraphBuilder: 対象リソースの全オブジェクト一覧（モニターストア経由）
- REST Mapper: リソースのGVR解決

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SSAパッチ | PATCH API | TypeMeta + UID + ResourceVersion precondition付きSSAパッチ |
| SVM.Status.Conditions | []Condition | MigrationRunning/MigrationSucceeded/MigrationFailed |
| SVM.Status.ResourceVersion | string | マイグレーション開始時のResourceVersion |

### 出力先

- API Server: 対象リソースへのSSAパッチ適用、StorageVersionMigrationステータス更新

## 処理フロー

### 処理シーケンス

```
1. Run()で5ワーカーを起動する
   └─ キャッシュ同期待機後、5個のワーカーを起動
2. sync()でStorageVersionMigrationを処理する
   └─ MigrationSucceeded/Failedなら完了済みとしてスキップ
3. REST Mapperでリソースを検証する
   └─ 1分間のグレース期間で新しいCRDの登録を待機
4. GCのGraphBuilderモニターから対象リソースのストアを取得する
   └─ 10秒タイムアウトでモニター起動を待機
5. 現在のStorageVersionのResourceVersionを記録する
   └─ マイグレーション開始時点のRVを保存
6. runMigration()で全オブジェクトにSSAパッチを適用する
   └─ typeMetaUIDRV構造体でUID+RV precondition付きパッチ
7. 完了/失敗をConditionsに記録する
```

### フローチャート

```mermaid
flowchart TD
    A[SVM変更検知] --> B{Succeeded/Failed?}
    B -->|Yes| C[スキップ]
    B -->|No| D[REST Mapperでリソース確認]
    D --> E{リソース有効?}
    E -->|No 1分以内| F[リトライ]
    E -->|No 超過| G[MigrationFailed]
    E -->|Yes| H[GC Monitorからストア取得]
    H --> I{10秒以内に取得?}
    I -->|No| F
    I -->|Yes| J{RV比較: SV一致?}
    J -->|No| K[MigrationSucceeded 移行不要]
    J -->|Yes| L[MigrationRunning設定]
    L --> M[runMigration: 全オブジェクトにSSAパッチ]
    M --> N{全件成功?}
    N -->|Yes| O[MigrationSucceeded]
    N -->|リトライ可能エラー| F
    N -->|その他エラー| G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-01 | 完了チェック | MigrationSucceeded/MigrationFailedのConditionがTrueなら処理スキップ | sync開始時 |
| BR-29-02 | CRDグレース期間 | REST Mapper未登録リソースは1分間待機（新規CRD登録を期待） | リソース検証時 |
| BR-29-03 | モニター取得タイムアウト | GC Monitorのストア取得は10秒タイムアウト | ストア取得時 |
| BR-29-04 | RV比較 | 対象リソースのStorageVersionのRVがSVMのRVと一致する場合のみ移行実行 | sync内 |
| BR-29-05 | SSA Precondition | UID + ResourceVersionをpreconditionとしてSSAパッチ（Conflict時はスキップ） | runMigration内 |
| BR-29-06 | リトライ可能エラー | connection reset、HTTP/2 loss、timeout、throttling、503、500はリトライ可能 | isRetriableError |

### 計算ロジック

- **SSAパッチ本体**: typeMetaUIDRV構造体でTypeMeta(APIVersion/Kind)のみ含むペイロード。UID/RVはprecondition
- **完了判定**: 全オブジェクトへのパッチ成功またはConflict（既に移行済み/削除済み）で成功

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| SVM取得 | SVM（etcd） | SELECT | StorageVersionMigrationの取得 |
| SVMステータス更新 | SVM（etcd） | UPDATE | Conditions/ResourceVersionの更新 |
| 対象リソースパッチ | 対象リソース（etcd） | UPDATE（SSA Patch） | StorageVersion移行のためのSSAパッチ |
| StorageVersion取得 | SV（etcd） | SELECT | 現在のResourceVersion確認 |

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

#### 対象リソース（etcd経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SSA PATCH | - | TypeMetaのみ（実質no-opだが保存形式は更新される） | UID+RV precondition付き、fieldManager=storage-version-migrator |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Conflict | API応答 | UID/RV不一致（既に変更/削除済み） | 正常としてスキップ（移行済みまたは削除済み） |
| connection reset | ネットワーク | 接続リセット | リトライ（isRetriableError） |
| Throttling (429) | API応答 | レート制限 | SuggestsClientDelayに従い遅延リトライ |
| ServiceUnavailable (503) | API応答 | API Server一時停止 | リトライ（isRetriableError） |
| InternalError (500) | API応答 | API Server内部エラー | リトライ（isRetriableError） |
| その他エラー | 各種 | 回復不可能なエラー | MigrationFailed Conditionを設定 |

### リトライ仕様

- SuggestsClientDelay: API Server応答のRetry-Afterに従い遅延リトライ
- isRetriableError: 接続リセット/HTTP2 loss/timeout/throttling/503/500でリトライ
- 非リトライ可能エラー: failMigration()でMigrationFailed Conditionを設定

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

各SSAパッチはUID + ResourceVersion preconditionを使用し、オブジェクトが変更されていないことを確認する。Conflict時はオブジェクトが既に移行済みまたは削除済みとみなしスキップする。全オブジェクトの処理はアトミックではなく、途中失敗時はリトライで再開される。

## パフォーマンス要件

- workers=5で並行処理
- GCのGraphBuilderモニターストアを共有利用することで、独自のInformer起動を回避
- SSAパッチはTypeMeta のみの軽量ペイロード
- SuggestsClientDelayに従いAPI Serverの負荷制御に協力

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

- 全リソースに対するpatch権限を持つため、サービスアカウントの管理が重要
- SSAパッチは実質的にno-op（データ内容は変更しない）だが、保存形式を更新する
- fieldManager "storage-version-migrator" で管理フィールドを追跡

## 備考

- GCのGraphBuilderのモニターを共有利用するため、GCコントローラーが起動していることが前提
- マイグレーション対象は、GCモニターのストアに存在する全オブジェクト
- CRDグレース期間（1分）はCRD作成とStorageVersionMigration作成のタイミングのずれを吸収するための仕組み

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | SVMController構造体（60-70行目）。kubeClient、svmClient、svmLister、restMapper、graphBuilder（GCのGraphBuilderインターフェース）を保持 |
| 1-2 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | 定数: workers=5（50行目）、各種Condition Reason（51-54行目） |
| 1-3 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | typeMetaUIDRV構造体（394-402行目）。SSAパッチのペイロード |

**読解のコツ**: graphBuilderインターフェース（56-58行目）はGetMonitor(resource)メソッドを持つ。GCのGraphBuilderを型アサーションで使用する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | NewSVMController（72-109行目）。SVM InformerのAdd/Update/Deleteハンドラ登録 |
| 2-2 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | Run（138-161行目）。キャッシュ同期後5ワーカー起動 |

#### Step 3: 同期処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | sync（191-297行目）。完了チェック、リソース検証（REST Mapper + 1分グレース）、GCモニター取得（10秒タイムアウト）、RV比較、runMigration呼び出し |
| 3-2 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | runMigration（299-368行目）。全オブジェクトへのSSAパッチ。Conflict→スキップ、リトライ可能→リキュー、その他→failMigration |

#### Step 4: エラーハンドリングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | isRetriableError（370-379行目）。接続リセット、HTTP2 loss、timeout、throttling、503、500 |
| 4-2 | storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | processNext（168-189行目）。SuggestsClientDelay対応 |

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

```
SVMController.Run()
    │
    └─ processNext()
           └─ sync()
                  ├─ 完了チェック (Conditions)
                  ├─ REST Mapper検証 (1分グレース)
                  ├─ GraphBuilder.GetMonitor() (10秒タイムアウト)
                  ├─ StorageVersion RV比較
                  ├─ MigrationRunning Condition設定
                  └─ runMigration()
                         ├─ monitor.GetStore().List() ── 全オブジェクト取得
                         ├─ SSA Patch (UID+RV precondition)
                         │      ├─ Conflict → スキップ
                         │      ├─ Retriable → リキュー
                         │      └─ Other → failMigration()
                         └─ MigrationSucceeded Condition設定
```

### データフロー図

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

SVMイベント ──────────▶ sync()
(Informer)                 │
                          ├─ REST Mapper検証
                          ├─ GC Monitor取得 ──▶ 全オブジェクト一覧
                          │
                          └─ runMigration()
                                │
                                ├─▶ API Server SSA Patch ──▶ 各オブジェクト
                                │   (TypeMeta, UID+RV precondition)    保存形式更新
                                │
                                └─▶ API Server UpdateStatus ──▶ SVM Conditions
                                    (Succeeded/Failed)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| storageversionmigrator.go | `pkg/controller/storageversionmigrator/storageversionmigrator.go` | ソース | SVMコントローラーの全ロジック |
