# 機能設計書 41-ジョブ管理コマンド

## 概要

本ドキュメントは、JenkinsのCLI（コマンドラインインターフェース）を通じてジョブを操作するためのジョブ管理コマンド群の機能設計を記載する。

### 本機能の処理概要

ジョブ管理コマンドは、CLIからJenkinsのジョブ（ビルドジョブ）を作成、取得、コピー、削除、一覧表示、再読み込みするための機能を提供する。

**業務上の目的・背景**：CI/CD環境の自動化において、Web UIを介さずにジョブを管理する必要がある。スクリプトやバッチ処理による一括操作、他システムとの連携、GitOpsワークフローでのジョブ定義管理などのユースケースに対応するため、CLIベースのジョブ管理機能が必要である。

**機能の利用シーン**：
- インフラストラクチャ・アズ・コードでジョブ定義をバージョン管理し、デプロイ時にCLIで適用
- 大量のジョブを一括作成・削除するスクリプトの実行
- CI/CDパイプラインから別のジョブを動的に作成・管理
- ジョブ設定のバックアップ・リストア操作

**主要な処理内容**：
1. `create-job`: 標準入力からXML設定を読み込み、新規ジョブを作成
2. `get-job`: 指定したジョブのXML設定を標準出力に出力
3. `copy-job`: 既存ジョブをコピーして新規ジョブを作成
4. `delete-job`: 指定したジョブを削除（複数指定可能）
5. `list-jobs`: ジョブ一覧を表示（ビューまたはアイテムグループでフィルタ可能）
6. `reload-job`: ディスクからジョブ設定を再読み込み

**関連システム・外部連携**：Jenkins CLI クライアント（jenkins-cli.jar）またはSSH経由でコマンドを実行。REST APIとも同等の操作が可能。

**権限による制御**：各コマンドには対応する権限が必要。create-jobはItem.CREATE、delete-jobはItem.DELETE、get-jobはItem.READ、reload-jobはItem.CONFIGUREなどの権限チェックが行われる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 59 | CLI操作 | 主画面 | CLI使用方法とコマンド一覧の表示 |

## 機能種別

CRUD操作 / コマンド実行

## 入力仕様

### 入力パラメータ

#### create-job コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | 作成するジョブ名 | 空文字不可、「/」でフォルダ階層指定可能、Jenkins.checkGoodName()によるバリデーション |
| stdin | InputStream | Yes | ジョブ設定XML | 有効なXML形式であること |

#### get-job コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| job | AbstractItem | Yes | 取得対象のジョブ名 | 存在するジョブであること |

#### copy-job コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| src | TopLevelItem | Yes | コピー元ジョブ名 | 存在するジョブであること |
| dst | String | Yes | コピー先ジョブ名 | 同名ジョブが存在しないこと |

#### delete-job コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| jobs | List<String> | Yes | 削除対象ジョブ名のリスト | 各ジョブが存在すること |

#### list-jobs コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | No | ビュー名またはアイテムグループ名 | 指定時は存在するビュー/アイテムグループであること |

#### reload-job コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| jobs | List<String> | Yes | 再読み込み対象ジョブ名のリスト | 各ジョブが存在すること |

### 入力データソース

- CLI経由でのコマンドライン引数
- 標準入力（create-jobの場合はXML設定ファイル）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| stdout | String | コマンド実行結果（get-jobの場合はXML、list-jobsの場合はジョブ名一覧） |
| stderr | String | エラーメッセージ |
| returnCode | int | 0=成功、非0=エラー |

### 出力先

- 標準出力（コマンド実行結果）
- 標準エラー出力（エラーメッセージ）
- Jenkinsファイルシステム（ジョブ設定ファイルの作成・更新・削除）

## 処理フロー

### 処理シーケンス

#### create-job

```
1. パラメータ解析
   └─ ジョブ名を取得
2. ジョブ存在チェック
   └─ 同名ジョブが存在する場合はエラー
3. フォルダ階層処理
   └─ 「/」が含まれる場合は親フォルダを特定
4. ジョブ名バリデーション
   └─ Jenkins.checkGoodName()を呼び出し
5. XMLからジョブ作成
   └─ ig.createProjectFromXML()を実行
```

#### delete-job

```
1. パラメータ解析
   └─ ジョブ名リストを取得（重複除去）
2. 各ジョブに対してループ
   └─ ジョブ存在チェック
   └─ 権限チェック（Item.DELETE）
   └─ job.delete()を実行
3. エラー集約
   └─ 複数ジョブでエラーがあれば集約してAbortException
```

### フローチャート

```mermaid
flowchart TD
    A[CLIコマンド受信] --> B{コマンド種別判定}
    B -->|create-job| C[ジョブ存在チェック]
    C -->|存在しない| D[フォルダ階層解析]
    C -->|存在する| E[エラー: ジョブ既存]
    D --> F[ジョブ名バリデーション]
    F --> G[XMLからジョブ作成]
    G --> H[成功: return 0]

    B -->|delete-job| I[ジョブリスト取得]
    I --> J[各ジョブをループ]
    J --> K{ジョブ存在?}
    K -->|Yes| L[権限チェック]
    K -->|No| M[エラー記録]
    L --> N[ジョブ削除]
    N --> O{全ジョブ処理完了?}
    M --> O
    O -->|Yes| P{エラーあり?}
    O -->|No| J
    P -->|Yes| Q[AbortException]
    P -->|No| H

    B -->|get-job| R[ジョブ取得]
    R --> S[XML出力]
    S --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | ジョブ名重複禁止 | 同一階層に同名のジョブは作成不可 | create-job, copy-job |
| BR-41-02 | フォルダ階層対応 | 「/」区切りでフォルダ階層を指定可能 | create-job, copy-job |
| BR-41-03 | 複数ジョブ一括処理 | delete-job, reload-jobは複数ジョブを一度に処理可能 | delete-job, reload-job |
| BR-41-04 | エラー継続処理 | 複数ジョブ処理時、一部でエラーが発生しても残りを継続処理 | delete-job, reload-job |

### 計算ロジック

該当なし

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

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

Jenkinsはファイルベースでジョブ設定を管理するため、データベース操作ではなくファイルシステム操作となる。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| create-job | $JENKINS_HOME/jobs/{name}/config.xml | CREATE | ジョブ設定ファイル作成 |
| delete-job | $JENKINS_HOME/jobs/{name}/ | DELETE | ジョブディレクトリ削除 |
| copy-job | $JENKINS_HOME/jobs/{dst}/config.xml | CREATE | コピー先ジョブ設定ファイル作成 |
| reload-job | $JENKINS_HOME/jobs/{name}/config.xml | READ | ディスクから設定再読み込み |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IllegalStateException | ジョブ既存 | create-job/copy-jobで同名ジョブが存在 | 別名を指定するか既存ジョブを削除 |
| IllegalArgumentException | フォルダ不存在 | 指定したフォルダパスが存在しない | 事前にフォルダを作成 |
| IllegalArgumentException | ジョブ不存在 | delete-job/reload-jobで指定ジョブが存在しない | ジョブ名を確認 |
| AccessDeniedException | 権限不足 | 必要な権限がない | 管理者に権限付与を依頼 |
| AbortException | 一括処理エラー | 複数ジョブ処理で一部エラー発生 | stderrのエラーメッセージを確認 |

### リトライ仕様

CLIコマンドはステートレスなため、エラー発生時はクライアント側でリトライを実装する。

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

Jenkinsのジョブ操作はファイルシステムベースであり、トランザクション制御は行われない。複数ジョブの一括削除時に途中でエラーが発生した場合、処理済みのジョブは削除されたままとなる。

## パフォーマンス要件

- 単一ジョブの作成/削除: 1秒以内
- 大量ジョブの一括処理: ジョブ数に比例（1ジョブあたり1秒程度）

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

- 各コマンドは対応するJenkins権限（Item.CREATE, Item.DELETE, Item.READ, Item.CONFIGURE）をチェック
- Jenkins.ADMINISTER権限を持つユーザーは全操作が可能
- CLI認証はAPIトークンまたはSSH公開鍵認証を使用
- ジョブ設定XMLに含まれる機密情報（パスワード等）は暗号化された状態で保存

## 備考

- CLIコマンドは`java -jar jenkins-cli.jar -s http://jenkins/ command`の形式で実行
- SSH経由の場合は`ssh -l user -p port jenkins command`で実行可能
- REST APIでも同等の操作が可能（/createItem, /job/{name}/config.xml等）

---

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

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

### 推奨読解順序

#### Step 1: CLIコマンド基盤を理解する

まず、CLIコマンドの基盤クラスを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CLICommand.java | `core/src/main/java/hudson/cli/CLICommand.java` | 全CLIコマンドの基底クラス。stdin/stdout/stderrの扱い、権限チェックの仕組み |

**読解のコツ**: @Extensionアノテーションによる拡張ポイントの仕組み、@Argumentによるパラメータバインディングを理解する。

#### Step 2: 各ジョブ管理コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CreateJobCommand.java | `core/src/main/java/hudson/cli/CreateJobCommand.java` | ジョブ作成の実装 |
| 2-2 | DeleteJobCommand.java | `core/src/main/java/hudson/cli/DeleteJobCommand.java` | 複数ジョブ削除の実装、エラーハンドリング |
| 2-3 | GetJobCommand.java | `core/src/main/java/hudson/cli/GetJobCommand.java` | ジョブ設定XML出力の実装 |
| 2-4 | CopyJobCommand.java | `core/src/main/java/hudson/cli/CopyJobCommand.java` | ジョブコピーの実装 |
| 2-5 | ListJobsCommand.java | `core/src/main/java/hudson/cli/ListJobsCommand.java` | ジョブ一覧表示の実装 |
| 2-6 | ReloadJobCommand.java | `core/src/main/java/hudson/cli/ReloadJobCommand.java` | ジョブ再読み込みの実装 |

**主要処理フロー（CreateJobCommand）**:
- **51-52行目**: Jenkinsインスタンス取得
- **54-56行目**: 同名ジョブ存在チェック
- **58-73行目**: フォルダ階層の解析とModifiableTopLevelItemGroupの取得
- **75-76行目**: ジョブ名バリデーションとXMLからのジョブ作成

**主要処理フロー（DeleteJobCommand）**:
- **60行目**: 重複除去のためHashSet使用
- **62-83行目**: 各ジョブに対するループ処理
- **72-73行目**: 権限チェックと削除実行
- **86-88行目**: エラー発生時のAbortException

#### Step 3: ジョブモデルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractItem.java | `core/src/main/java/hudson/model/AbstractItem.java` | ジョブの基底クラス、delete()メソッド、writeConfigDotXml()メソッド |
| 3-2 | Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | getItemByFullName()によるジョブ検索 |

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

```
CLI Client (jenkins-cli.jar)
    │
    └─ CLICommand (基底クラス)
           │
           ├─ CreateJobCommand
           │      ├─ Jenkins.get()
           │      ├─ Jenkins.getItemByFullName() - 存在チェック
           │      ├─ Jenkins.checkGoodName() - 名前バリデーション
           │      └─ ModifiableTopLevelItemGroup.createProjectFromXML()
           │
           ├─ DeleteJobCommand
           │      ├─ Jenkins.get()
           │      ├─ Jenkins.getItemByFullName() - ジョブ取得
           │      ├─ AbstractItem.checkPermission(Item.DELETE)
           │      └─ AbstractItem.delete()
           │
           ├─ GetJobCommand
           │      └─ AbstractItem.writeConfigDotXml()
           │
           ├─ CopyJobCommand
           │      ├─ Jenkins.get()
           │      ├─ Jenkins.getItemByFullName() - 存在チェック
           │      └─ ModifiableTopLevelItemGroup.copy()
           │
           ├─ ListJobsCommand
           │      ├─ Jenkins.getView() - ビュー取得
           │      ├─ View.getAllItems() - ジョブ一覧
           │      └─ Jenkins.getItems() - 全ジョブ一覧
           │
           └─ ReloadJobCommand
                  ├─ Jenkins.getItemByFullName() - ジョブ取得
                  ├─ AbstractItem.checkPermission(Item.CONFIGURE)
                  └─ AbstractItem.doReload()
```

### データフロー図

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

CLIコマンド引数 ──────▶ CLICommand.run() ──────────────────▶ return code (0/非0)
                              │
標準入力 (XML) ──────▶ CreateJobCommand ──────────────────▶ ジョブ設定ファイル
                              │                                   (config.xml)
                              ├─ GetJobCommand ──────────────────▶ 標準出力 (XML)
                              │
                              ├─ ListJobsCommand ────────────────▶ 標準出力 (ジョブ名一覧)
                              │
                              ├─ DeleteJobCommand ───────────────▶ ジョブディレクトリ削除
                              │
                              └─ ReloadJobCommand ───────────────▶ メモリ上のジョブ設定更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CLICommand.java | `core/src/main/java/hudson/cli/CLICommand.java` | ソース | CLI基底クラス |
| CreateJobCommand.java | `core/src/main/java/hudson/cli/CreateJobCommand.java` | ソース | ジョブ作成コマンド |
| DeleteJobCommand.java | `core/src/main/java/hudson/cli/DeleteJobCommand.java` | ソース | ジョブ削除コマンド |
| GetJobCommand.java | `core/src/main/java/hudson/cli/GetJobCommand.java` | ソース | ジョブ設定取得コマンド |
| CopyJobCommand.java | `core/src/main/java/hudson/cli/CopyJobCommand.java` | ソース | ジョブコピーコマンド |
| ListJobsCommand.java | `core/src/main/java/hudson/cli/ListJobsCommand.java` | ソース | ジョブ一覧コマンド |
| ReloadJobCommand.java | `core/src/main/java/hudson/cli/ReloadJobCommand.java` | ソース | ジョブ再読み込みコマンド |
| AbstractItem.java | `core/src/main/java/hudson/model/AbstractItem.java` | ソース | ジョブの基底クラス |
| Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | ソース | Jenkinsコアクラス |
| ModifiableTopLevelItemGroup.java | `core/src/main/java/jenkins/model/ModifiableTopLevelItemGroup.java` | ソース | ジョブ作成インターフェース |
