# 機能設計書 102-Wait

## 概要

本ドキュメントは、`kubectl wait` コマンドによるリソース条件待機機能の設計を記述する。指定したリソースが特定の条件を満たすまで待機する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Kubernetesクラスターの運用やCI/CDパイプラインにおいて、リソースのデプロイ完了やPodの起動完了を待ってから次のステップに進む必要がある。`kubectl wait` はリソースの状態変化をWatch APIで監視し、条件が満たされるまでブロッキングで待機することで、スクリプトやパイプラインでの順序制御を実現する。

**機能の利用シーン**：CI/CDパイプラインでのデプロイ後のヘルスチェック待機、Podの起動完了待ち、リソースの削除完了確認、テストスクリプト内でのリソース準備完了待機等で利用される。

**主要な処理内容**：
1. 待機条件の解析（condition / jsonpath / delete / create）
2. リソースの検索とWatch設定
3. 条件を満たすまでのポーリングまたはWatch監視
4. タイムアウト管理
5. 条件達成時の成功メッセージ出力

**関連システム・外部連携**：API ServerとのWatch API通信によるリアルタイム状態監視

**権限による制御**：対象リソースの読み取り（get/list/watch）権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | kubectl wait | 主機能 | リソースが指定条件を満たすまで待機する主処理 |
| 33 | kubectl wait | API連携 | リソースのWatch APIを使用して条件変化を監視する |

## 機能種別

監視・待機処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --for | string | Yes | 待機条件（condition=X / jsonpath=X / delete / create） | condition / jsonpath / delete / create のいずれか |
| --timeout | duration | No | タイムアウト時間 | デフォルト: 30s、0=一度だけチェック、負値=1週間 |
| -f / --filename | string[] | No | 対象リソースファイル | ファイルまたはリソース名指定 |
| -l / --selector | string | No | ラベルセレクター | 有効なラベルセレクター形式 |
| --field-selector | string | No | フィールドセレクター | 有効なフィールドセレクター形式 |
| --all | bool | No | 全リソース対象 | デフォルト: false |
| -A / --all-namespaces | bool | No | 全Namespace対象 | デフォルト: false |
| -o / --output | string | No | 出力形式 | json/yaml等 |

### 入力データソース

- コマンドライン引数（リソースタイプ/名前）
- マニフェストファイル
- API Serverからのリソース状態（Watch API）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 成功メッセージ | text | "condition met" と共にリソース情報を出力 |
| エラーメッセージ | text | タイムアウトや条件不成立時のエラー |

### 出力先

標準出力（stdout）に成功メッセージ、標準エラー（stderr）にエラーメッセージ

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数のパースとバリデーション
   └─ WaitFlags -> WaitOptions変換
2. 待機条件関数の生成（conditionFuncFor）
   ├─ "delete" -> IsDeleted
   ├─ "create" -> IsCreated
   ├─ "condition=X" -> ConditionalWait.IsConditionMet
   └─ "jsonpath=X" -> JSONPathWait.IsJSONPathConditionMet
3. タイムアウトコンテキストの設定
   └─ 0: チェック1回のみ、負値: 1週間、正値: 指定時間
4. create条件の場合: ポーリングベースの待機
   └─ 500msインターバルでリソース存在をチェック
5. その他の条件の場合: Watch APIベースの待機
   ├─ リソースのList + Watch設定
   ├─ preconditionFuncでリソース消失チェック
   └─ UntilWithSyncで条件監視
6. 条件達成時: 成功メッセージ出力
7. タイムアウト時: エラー出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数パース]
    B --> C[待機条件関数生成]
    C --> D{条件タイプ}
    D -->|create| E[ポーリング待機 500ms間隔]
    D -->|delete/condition/jsonpath| F[Watch API設定]
    F --> G[リソース取得 + Watch開始]
    G --> H{条件を満たしたか}
    H -->|Yes| I[成功メッセージ出力]
    H -->|No| J{タイムアウトか}
    J -->|Yes| K[タイムアウトエラー]
    J -->|No| H
    E --> L{リソースが存在するか}
    L -->|Yes| I
    L -->|No| M{タイムアウトか}
    M -->|Yes| K
    M -->|No| E
    I --> N[終了]
    K --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-201 | タイムアウト制御 | timeout=0は一度だけチェック、負値は168時間（1週間） | 常に適用 |
| BR-202 | condition値比較 | Unicode Simple Case Foldingによる大文字小文字非依存比較 | condition=X 指定時 |
| BR-203 | observedGeneration確認 | condition一致でもobservedGeneration < generationなら未達成 | condition待機時 |
| BR-204 | create待機 | 500ms間隔のポーリングでリソース出現を監視 | --for=create 指定時 |
| BR-205 | delete待機 | NotFoundエラーで条件達成と判定 | --for=delete 指定時 |

### 計算ロジック

条件判定ロジック: `strings.EqualFold(status, conditionStatus)` によりUnicode Simple Case Foldingで比較。デフォルトのconditionValueは "true"。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リソース監視 | etcd（API Server経由） | SELECT（GET/LIST/WATCH） | リソースの状態変化を監視 |

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

本機能は読み取り専用で動作し、リソースの変更は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | タイムアウト | 指定時間内に条件が満たされない | "timed out waiting for the condition" エラー |
| - | リソース未検出 | 対象リソースが見つからない | "no matching resources found" エラー |
| - | 条件未認識 | --for の値が不正 | "unrecognized condition" エラー |
| - | JSONPathエラー | JSONPath式が不正 | パースエラーメッセージ |

### リトライ仕様

Watch接続が切断された場合、UntilWithSync内部でList + Watch の再接続が自動的に行われる。

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

読み取り専用の監視処理であり、トランザクション管理は不要。

## パフォーマンス要件

- create条件: 500msインターバルのポーリング
- その他の条件: Watch APIによるイベント駆動（低レイテンシ）
- タイムアウトのデフォルト値は30秒

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

- 対象リソースのget/list/watch権限が必要
- JSONPath式によるフィールドアクセスは、ユーザーが閲覧権限を持つリソースに限定される

## 備考

- `--for=condition=Ready` のデフォルト条件値は "true"
- `--for=condition=Ready=false` のように等号区切りで条件値を指定可能
- JSONPath式では `==` はエスケープされ分割されない（`splitJSONPathInput` の実装）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | WaitFlags構造体（91-100行目）：CLIフラグの保持 |
| 1-2 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | WaitOptions構造体（303-315行目）：ランタイムオプション |
| 1-3 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | ConditionFunc型（318行目）：条件判定関数のインターフェース |

**読解のコツ**: WaitFlagsがCLI入力を、WaitOptionsがランタイム処理を担当する分離パターン。ConditionFuncが条件判定の抽象化を提供する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | NewCmdWait関数（122-143行目）：Cobraコマンド定義 |
| 2-2 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | conditionFuncFor関数（193-235行目）：条件文字列から判定関数への変換 |

**主要処理フロー**:
1. **132-136行目**: flags.ToOptions -> o.RunWait の実行チェーン
2. **193-235行目**: 条件文字列のパースと適切なConditionFuncの生成

#### Step 3: メイン待機処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | RunWait関数（321-383行目）：メインの待機ループ |

**主要処理フロー**:
- **322-323行目**: タイムアウトコンテキストの設定
- **325-350行目**: create条件の特別処理（ポーリングベース）
- **352-383行目**: 汎用の待機処理（Visit + ConditionFn）

#### Step 4: 条件判定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | condition.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/condition.go` | ConditionalWait構造体とIsConditionMet（41-98行目） |
| 4-2 | condition.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/condition.go` | getObjAndCheckCondition関数（105-184行目）：Watch APIによる条件監視 |

**主要処理フロー**:
- **53-82行目**: checkCondition - status.conditionsから条件をチェック
- **71-77行目**: observedGenerationとgenerationの比較ロジック
- **138-147行目**: ListWatch設定によるWatch API利用
- **167行目**: UntilWithSyncによる条件達成までの監視

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

```
NewCmdWait
    │
    ├─ WaitFlags.ToOptions()
    │      └─ conditionFuncFor()
    │             ├─ IsDeleted
    │             ├─ IsCreated
    │             ├─ ConditionalWait.IsConditionMet
    │             └─ JSONPathWait.IsJSONPathConditionMet
    │
    └─ WaitOptions.RunWait()
           ├─ [create] PollUntilContextTimeout()
           │
           └─ [others] visitor.Visit()
                  └─ ConditionFn()
                         └─ getObjAndCheckCondition()
                                ├─ DynamicClient.Get() [timeout=0]
                                └─ UntilWithSync() [timeout>0]
                                       ├─ ListWatch
                                       └─ condMet()
```

### データフロー図

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

コマンドライン引数 ──▶ conditionFuncFor() ──▶ ConditionFunc
                                                    │
API Server ◀── Watch API ◀────────── RunWait() ────┘
       │                                    │
       ▼                                    ▼
   リソース状態 ──▶ 条件判定 ──▶ {true: 成功メッセージ, false: 継続待機}
                                    │
                                    └──▶ stdout ("condition met")
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | ソース | メインロジック：コマンド定義、条件パース、待機ループ |
| condition.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/condition.go` | ソース | 条件判定：condition/jsonpath/delete/createの判定ロジック |
| create.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/create.go` | ソース | create条件の判定 |
| delete.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/delete.go` | ソース | delete条件の判定 |
| json.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/json.go` | ソース | JSONPath条件の判定 |
| wait_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait_test.go` | テスト | ユニットテスト |
