# 画面設計書 25-kubectl cp

## 概要

本ドキュメントは、Kubernetes CLIツール kubectl の `cp` コマンドに関する画面設計書である。kubectl cp はコンテナとローカルファイルシステム間でファイルをコピーする機能を提供する。

### 本画面の処理概要

kubectl cp コマンドは、ローカルマシンとKubernetesクラスター上のコンテナ間でファイルやディレクトリのコピーを行う。内部的には tar コマンドを使って exec 経由でのファイル転送を実現している。

**業務上の目的・背景**：コンテナからのログファイル収集、設定ファイルの投入、デバッグ用ツールの配置、データのエクスポート/インポートなど、コンテナとローカル間のファイル交換が必要な場面で使用される。

**画面へのアクセス方法**：ターミナルから `kubectl cp <src> <dest>` を実行する。送信元/先にコンテナを指定する場合は `<namespace>/<pod>:<path>` 形式を使用する。

**主要な操作・処理内容**：
1. 送信元/先の解析（ローカルかリモートかの判定）
2. コンテナ内での tar コマンド実行（exec 経由）
3. tar ストリームの転送
4. ローカルでの tar 展開またはアーカイブ

**画面遷移**：単独で使用される。

**権限による表示制御**：対象Podの `pods/exec` サブリソースに対する権限が必要（内部的に exec を使用するため）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 91 | ファイルコピー（cp） | 主機能 | コンテナとローカル間のファイルコピー |
| 88 | コンテナ実行（exec） | 内部利用 | tar コマンド実行のために exec を使用 |

## 画面種別

CLIバッチコマンド（非対話型）

## URL/ルーティング

```
kubectl cp <file-spec-src> <file-spec-dest> [options]
```

内部的には exec サブリソースを使用：
```
POST /api/v1/namespaces/{namespace}/pods/{name}/exec (tar コマンド)
```

## 入出力項目

| 項目名 | 種別 | 必須 | 型 | 説明 |
|--------|------|------|-----|------|
| file-spec-src | 引数 | Yes | string | コピー元（`[namespace/]pod:path` またはローカルパス） |
| file-spec-dest | 引数 | Yes | string | コピー先（`[namespace/]pod:path` またはローカルパス） |
| --container, -c | フラグ | No | string | 対象コンテナ名 |
| --no-preserve | フラグ | No | bool | コピーファイルの所有権/パーミッションを保持しない（デフォルト: false） |
| --retries | フラグ | No | int | リトライ回数（デフォルト: 0）。既知の問題（tar の早期終了）に対する回避策 |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| 進捗表示 | なし（標準出力への直接出力なし） |
| エラーメッセージ | ファイル転送エラー時のメッセージ |
| 警告メッセージ | tarバイナリ不在等の警告 |

## イベント仕様

### 1-ローカルからコンテナへのコピー

1. ローカルファイルを tar アーカイブに変換
2. コンテナ内で `tar -xmf -` を exec 実行
3. stdin 経由で tar ストリームを転送
4. `--no-preserve=true` の場合は `--no-same-permissions --no-same-owner` を追加

### 2-コンテナからローカルへのコピー

1. コンテナ内で `tar cf - <path>` を exec 実行
2. stdout 経由で tar ストリームを受信
3. ローカルで tar を展開（untarAll 関数）
4. シンボリックリンクの安全性チェック（パストラバーサル防止）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| cp実行 | - | SELECT | Pod情報の取得のみ（kubectl側はリソース変更なし） |

kubectl cp 自体はKubernetesリソースの状態を変更しない。コンテナ内のファイルシステムは変更される。

### テーブル別更新項目詳細

該当なし

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|----------|
| M-01 | エラー | "one of src or dest must be a remote file specification" | 両方ローカルまたは両方リモート |
| M-02 | エラー | "source or destination cannot be empty" | 送信元/先が空 |
| M-03 | 警告 | "tar: removing leading '/' from member names" | tar からのstderr出力 |
| M-04 | エラー | "the server could not find the requested resource" | Podが見つからない |

## 例外処理

| 例外 | 状態 | 対処 |
|------|------|------|
| 両方ローカル指定 | エラー終了 | リモート指定が必須のエラーを表示 |
| 両方リモート指定 | エラー終了 | 同上 |
| コンテナに tar がない | エラー終了 | tar バイナリ不在のエラーを表示 |
| パストラバーサル検出 | エラー終了 | 安全でないシンボリックリンクのエラーを表示 |
| tar 早期終了 | リトライ | --retries で指定された回数リトライ |

## 備考

- 内部的に `exec` を使用するため、コンテナに `tar` バイナリが必要。
- コンテナからローカルへのコピー時、シンボリックリンクの安全性チェック（`linkCleanPath` 関数）が行われ、パストラバーサル攻撃を防止する（cp.go 行258-280）。
- `--retries` フラグは tar バイナリの既知の問題（SIGPIPE）に対する回避策（cp.go 行67-70）。
- ワイルドカードは使用不可。リモート展開が必要な場合は exec を直接使用する。
- `--no-preserve` は tar 展開時の `--no-same-permissions --no-same-owner` オプションに対応（cp.go 行209）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | CopyOptions（行80-97）: Container, Namespace, NoPreserve, MaxTries, ClientConfig 等 |
| 1-2 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | fileSpec 構造体（行100-105）: PodNamespace, PodName, File の解析結果 |

**読解のコツ**: CopyOptions は exec.StreamOptions を使わず独自のフィールドを持つ。fileSpec が送信元/先の解析結果を保持する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | NewCmdCp（行108-143）: コマンド定義、フラグ登録 |

#### Step 3: Complete/Validate/Run を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | Complete（行145-164）: ClientConfig取得、namespace解決 |
| 3-2 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | Validate（行166-175）: 引数数チェック（正確に2つ） |
| 3-3 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | Run（行177-216）: extractFileSpec で src/dst 解析、方向判定、copyToPod/copyFromPod |

#### Step 4: ファイルコピー実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | copyToPod（行218-240）: tar作成 -> exec tar -xmf - |
| 4-2 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | copyFromPod（行242-256）: exec tar cf - -> untarAll |
| 4-3 | cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | untarAll（行282-350）: tar展開とパストラバーサルチェック |

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

```
NewCmdCp (行108)
    |
    +-- Complete (行145)
    |       +-- f.ToRESTConfig()
    |       +-- f.ToRawKubeConfigLoader().Namespace()
    |
    +-- Validate (行166)
    |
    +-- Run (行177)
            |
            +-- extractFileSpec (行362)
            |       +-- 送信元/先の解析 (namespace/pod:path 形式)
            |
            +-- [ローカル -> コンテナ]
            |       +-- copyToPod (行218)
            |               +-- makeTar (ローカルファイルのtar化)
            |               +-- exec "tar -xmf -" (コンテナ内展開)
            |
            +-- [コンテナ -> ローカル]
                    +-- copyFromPod (行242)
                            +-- exec "tar cf -" (コンテナ内tar作成)
                            +-- untarAll (行282)
                                    +-- linkCleanPath (シンボリックリンク安全チェック)
                                    +-- ローカルファイル書き出し
```

### データフロー図

```
[ローカル -> コンテナ]

ローカルファイル --> makeTar --> stdin --> exec "tar -xmf -" --> コンテナFS

[コンテナ -> ローカル]

コンテナFS --> exec "tar cf -" --> stdout --> untarAll --> ローカルファイル
                                                 |
                                        linkCleanPath (安全チェック)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cp.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp.go` | ソース | cp コマンドの主実装 |
| exec.go | `staging/src/k8s.io/kubectl/pkg/cmd/exec/exec.go` | ソース | exec 機能（内部利用） |
| cp_test.go | `staging/src/k8s.io/kubectl/pkg/cmd/cp/cp_test.go` | テスト | cp コマンドのユニットテスト |
