# 画面設計書 33-kubectl wait

## 概要

本ドキュメントは、Kubernetes CLIツール `kubectl` の `wait` コマンドに関する画面設計書である。`kubectl wait` は、指定したKubernetesリソースが特定の条件を満たすまでブロッキングで待機するコマンドであり、CI/CDパイプラインやシェルスクリプトでのオーケストレーションに活用される。

### 本画面の処理概要

**業務上の目的・背景**：Kubernetesリソースの状態変化を待機する必要がある運用シーンは多い。例えば、Podが Ready状態になるまで待機してからテストを実行する、リソースが削除されるまで待ってから次の操作を行うなど。`kubectl wait` はこれらの待機操作をスクリプト化可能にし、ポーリングロジックの自前実装を不要にする。

**画面へのアクセス方法**：ターミナルから `kubectl wait` コマンドを実行する。`--for` フラグで待機条件を指定し、対象リソースはTYPE/NAME形式、ラベルセレクタ、またはファイル指定で特定する。

**主要な操作・処理内容**：
1. 条件の指定（condition / jsonpath / delete / create）
2. 対象リソースの特定（名前指定、ラベルセレクタ、ファイル指定）
3. Watch APIを使用したリソース状態の監視
4. タイムアウト制御（デフォルト30秒）
5. 条件達成時の成功出力
6. JSONPath式による柔軟な条件指定

**画面遷移**：kubectl waitは単独で完結するコマンドである。デプロイフローにおいて `kubectl apply` の後に `kubectl wait --for=condition=Ready` を実行するパターンが典型的。

**権限による表示制御**：対象リソースへの `get` および `watch` 権限が必要。

## 関連機能

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

## 画面種別

CLI コマンド（リソース監視・待機操作）

## URL/ルーティング

```
kubectl wait ([-f FILENAME] | resource.group/resource.name | resource.group [(-l label | --all)]) [--for=create|--for=delete|--for condition=available|--for=jsonpath='{}'[=value]]
```

コマンドエントリーポイント: `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` の `NewCmdWait` 関数（行122）

## 入出力項目

### 入力パラメータ（フラグ）

| パラメータ名 | 短縮形 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|--------|-----|------|-------------|------|
| --for | - | string | Yes | "" | 待機条件（create / delete / condition=名前[=値] / jsonpath=式[=値]） |
| --timeout | - | duration | No | 30s | 待機タイムアウト（0で即時チェック、負値で1週間） |
| -f / --filename | -f | []string | *1 | - | リソースを特定するファイル |
| -l / --selector | -l | string | No | "" | ラベルセレクタ |
| --field-selector | - | string | No | "" | フィールドセレクタ |
| --all | - | bool | No | false | 全リソースを対象 |
| -A / --all-namespaces | -A | bool | No | false | 全Namespace対象 |
| -o / --output | -o | string | No | "" | 出力形式 |

*1: TYPE/NAME形式で指定しない場合に必要

### --for フラグの条件形式

| 形式 | 説明 | 例 |
|------|------|-----|
| `delete` | リソースが削除されるまで待機 | `--for=delete` |
| `create` | リソースが作成されるまで待機 | `--for=create` |
| `condition=NAME` | status.conditionsのNAMEがTrueになるまで待機 | `--for=condition=Ready` |
| `condition=NAME=VALUE` | status.conditionsのNAMEがVALUEになるまで待機 | `--for=condition=Ready=false` |
| `jsonpath=EXPR` | JSONPathの結果が非空になるまで待機 | `--for=jsonpath='{.status.loadBalancer.ingress}'` |
| `jsonpath=EXPR=VALUE` | JSONPathの結果がVALUEになるまで待機 | `--for=jsonpath='{.status.phase}'=Running` |

## 表示項目

### 成功時の出力

| 項目 | 形式 | 説明 |
|------|------|------|
| リソース種別/名前 | テキスト | 条件達成のメッセージ（例: `pod/busybox1 condition met`） |

## イベント仕様

### 1-条件待機実行（condition / jsonpath）

1. `WaitFlags.ToOptions` でフラグからランタイムオプション変換（行155-191）
2. `conditionFuncFor` で条件文字列から適切な `ConditionFunc` を選択（行193-235）
3. `RunWait` でリソースに対するVisitor実行（行321-383）
4. Watch APIを使用してリソース変更を監視
5. 条件達成時にPrinter.PrintObjで結果出力（行361）

### 2-削除待機（--for=delete）

1. `IsDeleted` 関数が ConditionFunc として設定
2. リソースが NotFound になるまで監視
3. NotFoundエラーを無視するためVisitorに `IgnoreErrors` 設定（行372）

### 3-作成待機（--for=create）

1. `wait.PollUntilContextTimeout` で500ms間隔のポーリング実行（行331）
2. ResourceFinder.Do().Visit() でリソースの存在確認（行333）
3. NotFoundの場合はfalseを返してポーリング継続（行337-338）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 条件待機 | - | SELECT (Watch) | リソースの状態変化を監視するのみ（読み取り専用） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| MSG-W01 | 成功 | `{type}/{name} condition met` | 待機条件が達成された場合 |
| MSG-W02 | エラー | `no matching resources found` | 対象リソースが見つからない |
| MSG-W03 | エラー | `timed out waiting for the condition` | タイムアウト |
| MSG-W04 | エラー | `unrecognized condition: "{condition}"` | 不正な--for条件 |
| MSG-W05 | エラー | `jsonpath expression cannot be empty` | JSONPath式が空 |
| MSG-W06 | エラー | `jsonpath wait format must be --for=jsonpath='{...}'=value or --for=jsonpath='{...}'` | JSONPath書式エラー |
| MSG-W07 | エラー | `jsonpath wait has to have a value after equal sign` | JSONPath値が空文字列 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|----------|----------|
| タイムアウト | 指定時間内に条件を満たさない | "timed out waiting for the condition" エラー |
| リソース未発見 | 対象リソースが存在しない（delete以外） | "no matching resources found" エラー |
| JSONPathパースエラー | 不正なJSONPath式 | パースエラーメッセージを表示 |
| API Server接続エラー | Watch接続が切断 | 接続エラーを表示 |

## 備考

- タイムアウト値が負の場合、内部的に168時間（1週間）に変換される（行175-177）。
- タイムアウト値が0の場合、即時チェックのみ行い待機しない。
- 条件値の比較はUnicode Simple Case Foldingで行われ、大文字小文字を区別しない（行64-65）。
- `--for=create` の場合、500ms間隔でポーリングする実装となっている（行331）。Watch APIではなくポーリングである点に注意。
- `--for=delete` の場合、既にリソースが存在しない場合は即座に成功する。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | WaitFlags構造体（行91-100）とWaitOptions構造体（行303-315）の関係 |
| 1-2 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | ConditionFunc型定義（行318）- 条件判定の共通インターフェース |
| 1-3 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | ResourceLocation構造体（行292-296）- リソース位置のキー |

**読解のコツ**: `ConditionFunc` はクロージャパターンで実装されており、条件の種類に応じて異なる関数が生成される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | NewCmdWait関数（行122-143）のコマンド定義 |
| 2-2 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | ToOptions関数（行155-191）のフラグからオプションへの変換 |

**主要処理フロー**:
1. **行122**: `NewCmdWait` - cobraコマンド生成
2. **行133-136**: Run関数 - ToOptions -> RunWait
3. **行150-152**: AddFlags - --timeoutと--forフラグ登録

#### Step 3: 条件関数の選択ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | conditionFuncFor関数（行193-235）- 条件文字列のパースと関数割り当て |
| 3-2 | condition.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/condition.go` | ConditionalWait構造体 - status.conditions待機の実装 |
| 3-3 | json.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/json.go` | JSONPathWait構造体 - JSONPath待機の実装 |
| 3-4 | delete.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/delete.go` | IsDeleted関数 - 削除待機の実装 |
| 3-5 | create.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/create.go` | IsCreated関数 - 作成待機の実装 |

#### Step 4: RunWait - メイン待機ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | RunWait関数（行321-383）- create待機のポーリングと通常待機のVisitorパターン |

**主要処理フロー**:
- **行322-323**: コンテキストとタイムアウト設定
- **行325-350**: create条件の特殊処理（ポーリング）
- **行353-382**: 通常条件の処理（ConditionFn呼び出し）
- **行370-373**: delete条件のNotFoundエラー無視設定

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

```
NewCmdWait (行122)
    │
    ├─ WaitFlags.ToOptions (行155)
    │      ├─ PrintFlags.ToPrinter
    │      ├─ ResourceBuilderFlags.ToBuilder
    │      ├─ dynamic.NewForConfig
    │      └─ conditionFuncFor (行193)
    │             ├─ "delete" → IsDeleted
    │             ├─ "create" → IsCreated
    │             ├─ "condition=" → ConditionalWait.IsConditionMet
    │             └─ "jsonpath=" → JSONPathWait.IsJSONPathConditionMet
    │
    └─ RunWait (行321)
           ├─ [create] PollUntilContextTimeout (行331)
           │      └─ ResourceFinder.Do().Visit (行333)
           │
           └─ [other] ResourceFinder.Do().Visit (行369-375)
                  └─ ConditionFn (行359)
                         └─ Watch API経由で条件監視
```

### データフロー図

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

--for=条件               ┌──────────────────┐
  ─────────────────────▶│ conditionFuncFor  │
                        │ (条件関数選択)     │
                        └────────┬─────────┘
                                 │
リソース指定              ┌───────▼──────────┐
(TYPE/NAME / -l) ───────▶│ ResourceFinder   │
                        └────────┬─────────┘
                                 │
                        ┌────────▼─────────┐
                        │ Watch API /       │
                        │ Polling           │
                        │ (状態監視)         │
                        └────────┬─────────┘
                                 │
                        ┌────────▼─────────┐
                        │ ConditionFunc     │
                        │ (条件判定)         │
                        └────────┬─────────┘
                                 │
                     ┌───────────┴───────────┐
                     │ 条件達成              │ タイムアウト
                     ▼                       ▼
              PrintObj → stdout        エラー → stderr
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| wait.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/wait.go` | ソース | waitコマンドのメイン実装（384行） |
| condition.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/condition.go` | ソース | status.conditions待機の実装 |
| json.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/json.go` | ソース | JSONPath待機の実装 |
| delete.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/delete.go` | ソース | 削除待機の実装 |
| create.go | `staging/src/k8s.io/kubectl/pkg/cmd/wait/create.go` | ソース | 作成待機の実装 |
| jsonpath.go | `staging/src/k8s.io/client-go/util/jsonpath/jsonpath.go` | ソース | JSONPathパーサー |
| watch.go | `staging/src/k8s.io/client-go/tools/watch/` | ソース | Watch APIユーティリティ |
