# 機能設計書 43-プラグイン管理コマンド

## 概要

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

### 本機能の処理概要

プラグイン管理コマンドは、CLIからJenkinsのプラグインをインストール、有効化、無効化、一覧表示するための機能を提供する。

**業務上の目的・背景**：CI/CD環境の構築・保守において、プラグインの管理は重要な作業である。スクリプトによるプラグインの一括インストール、インフラストラクチャ・アズ・コードによるプラグイン構成管理、セキュリティパッチの自動適用などのユースケースに対応するため、CLIベースのプラグイン管理機能が必要である。

**機能の利用シーン**：
- Jenkins新規環境構築時のプラグイン一括インストール
- Dockerイメージビルド時のプラグインプリインストール
- セキュリティ脆弱性対応としての問題プラグインの一括無効化
- プラグインバージョン管理とアップデート自動化

**主要な処理内容**：
1. `install-plugin`: URL、標準入力、またはアップデートセンターからプラグインをインストール
2. `enable-plugin`: 指定したプラグインを有効化（依存プラグインも自動有効化）
3. `disable-plugin`: 指定したプラグインを無効化（依存戦略の指定可能）
4. `list-plugins`: インストール済みプラグインの一覧表示

**関連システム・外部連携**：Jenkins CLI クライアント、アップデートセンター（更新サイト）との連携。

**権限による制御**：全てのプラグイン管理コマンドにはJenkins.ADMINISTER権限が必要。

## 関連画面

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

## 機能種別

CRUD操作 / プラグイン状態制御 / コマンド実行

## 入力仕様

### 入力パラメータ

#### install-plugin コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | List<String> | Yes | プラグインソース（URL、「=」で標準入力、プラグイン短縮名[:バージョン]） | 有効なソース指定 |
| -restart | boolean | No | インストール後にJenkinsを再起動 | - |
| -deploy | boolean | No | 再起動を待たずに即座にプラグインをデプロイ | - |

#### enable-plugin コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pluginNames | List<String> | Yes | 有効化するプラグインの短縮名リスト | インストール済みプラグイン |
| -restart | boolean | No | 有効化後にJenkinsを再起動 | - |

#### disable-plugin コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pluginNames | List<String> | Yes | 無効化するプラグインの短縮名リスト | インストール済みプラグイン |
| -restart | boolean | No | 無効化後にJenkinsを再起動 | - |
| -strategy | String | No | 依存プラグイン処理戦略（none/mandatory/all） | 有効な戦略名 |
| -quiet | boolean | No | エラーメッセージのみ出力 | - |

#### list-plugins コマンド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | No | 特定プラグインの情報のみ表示 | インストール済みプラグイン |

### 入力データソース

- CLI経由でのコマンドライン引数
- 標準入力（install-pluginで「=」指定時はプラグインファイル）
- アップデートセンター（install-pluginでプラグイン名指定時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| stdout | String | コマンド実行結果（list-pluginsはプラグイン一覧） |
| stderr | String | エラーメッセージ |
| returnCode | int | 0=成功、16=依存関係エラー、17=プラグイン不存在 |

### 出力先

- 標準出力（コマンド実行結果）
- 標準エラー出力（エラーメッセージ）
- Jenkinsファイルシステム（プラグインファイル .jpi/.hpi）

## 処理フロー

### 処理シーケンス

#### install-plugin

```
1. 権限チェック
   └─ Jenkins.ADMINISTER権限を確認
2. 各ソースに対してループ
   └─ ソース種別判定（標準入力/URL/プラグイン名）
3. 標準入力の場合
   └─ 一時ファイルに保存後、プラグインディレクトリに移動
4. URLの場合
   └─ URLからダウンロード後、プラグインディレクトリに移動
5. プラグイン名の場合
   └─ アップデートセンターから検索してインストール
6. 動的ロード処理（-deploy指定時）
   └─ pm.dynamicLoad()を実行
7. 再起動処理（-restart指定時）
   └─ jenkins.safeRestart()を実行
```

#### disable-plugin

```
1. 権限チェック
   └─ Jenkins.ADMINISTER権限を確認
2. 戦略パース
   └─ none/mandatory/allをenum変換
3. プラグイン無効化実行
   └─ pluginManager.disablePlugins(strategy, pluginNames)
4. 結果出力
   └─ 各プラグインの無効化結果を表示
5. 再起動判定
   └─ 無効化されたプラグインがあれば再起動（-restart指定時）
6. リターンコード決定
   └─ エラー種別に応じたコード返却
```

### フローチャート

```mermaid
flowchart TD
    A[CLIコマンド受信] --> B{コマンド種別判定}

    B -->|install-plugin| C[権限チェック]
    C --> D[各ソースをループ]
    D --> E{ソース種別?}
    E -->|=| F[標準入力から読み込み]
    E -->|URL| G[URLからダウンロード]
    E -->|プラグイン名| H[アップデートセンター検索]
    F --> I[プラグインディレクトリに配置]
    G --> I
    H --> J{プラグイン見つかった?}
    J -->|Yes| K[アップデートセンターからインストール]
    J -->|No| L[エラー: プラグイン不明]
    I --> M{-deploy指定?}
    K --> M
    M -->|Yes| N[動的ロード実行]
    M -->|No| O{-restart指定?}
    N --> O
    O -->|Yes| P[安全な再起動]
    O -->|No| Q[成功: return 0]
    P --> Q

    B -->|disable-plugin| R[権限チェック]
    R --> S[戦略パース]
    S --> T[disablePlugins実行]
    T --> U[結果出力]
    U --> V{プラグイン無効化された?}
    V -->|Yes| W{-restart指定?}
    V -->|No| X[リターンコード決定]
    W -->|Yes| Y[安全な再起動]
    W -->|No| X
    Y --> X
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-43-01 | 複数ソースインストール | install-pluginは複数のプラグインソースを一度に処理可能 | install-plugin |
| BR-43-02 | バージョン指定 | プラグイン名:バージョン形式で最小バージョン指定可能 | install-plugin |
| BR-43-03 | 依存プラグイン自動有効化 | enable-pluginは依存プラグインを自動的に有効化 | enable-plugin |
| BR-43-04 | 依存戦略 | disable-pluginは依存プラグインの処理戦略を指定可能 | disable-plugin |
| BR-43-05 | 更新情報表示 | list-pluginsは更新可能なバージョンがあれば併記 | list-plugins |

### 計算ロジック

#### 依存戦略（disable-plugin）
- **none**: 必須依存プラグインが有効な場合は無効化不可
- **mandatory**: 必須依存プラグインも一緒に無効化
- **all**: 全ての依存プラグイン（任意含む）を無効化

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

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

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| install-plugin | $JENKINS_HOME/plugins/{name}.jpi | CREATE | プラグインファイル作成 |
| disable-plugin | $JENKINS_HOME/plugins/{name}.jpi.disabled | CREATE | 無効化マーカーファイル作成 |
| enable-plugin | $JENKINS_HOME/plugins/{name}.jpi.disabled | DELETE | 無効化マーカーファイル削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 16 | 依存関係エラー | disable-pluginで必須依存プラグインが有効 | -strategy mandatoryを使用 |
| 17 | プラグイン不存在 | 指定プラグインが存在しない | プラグイン名を確認 |
| AbortException | インストール失敗 | ダウンロードやデプロイに失敗 | ネットワーク接続確認、URL確認 |
| IllegalArgumentException | 無効な戦略 | 不正な-strategy値 | none/mandatory/allを指定 |

### リトライ仕様

ネットワークエラー時はクライアント側でリトライを実装。

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

プラグインの有効化/無効化は原子的操作ではない。複数プラグインの一括処理中にエラーが発生した場合、処理済みのプラグインは変更されたままとなる。

## パフォーマンス要件

- プラグイン一覧表示: 1秒以内
- プラグインインストール: ダウンロードサイズに依存（大規模プラグインで数十秒）

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

- 全コマンドはJenkins.ADMINISTER権限が必須
- プラグインインストール元（URL/アップデートセンター）の信頼性を確認
- プラグインの署名検証が推奨

## 備考

- `-name`オプションは非推奨（使用されない）
- プラグインのマニフェストからShort-Nameを取得してファイル名を決定
- 類似プラグイン名をEditDistanceで提案

---

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

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

### 推奨読解順序

#### Step 1: 各プラグイン管理コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | InstallPluginCommand.java | `core/src/main/java/hudson/cli/InstallPluginCommand.java` | インストールの実装、ソース種別判定 |
| 1-2 | EnablePluginCommand.java | `core/src/main/java/hudson/cli/EnablePluginCommand.java` | 有効化の実装、依存プラグイン処理 |
| 1-3 | DisablePluginCommand.java | `core/src/main/java/hudson/cli/DisablePluginCommand.java` | 無効化の実装、戦略パターン |
| 1-4 | ListPluginsCommand.java | `core/src/main/java/hudson/cli/ListPluginsCommand.java` | 一覧表示の実装 |

**主要処理フロー（InstallPluginCommand）**:
- **84-86行目**: 権限チェック（Jenkins.ADMINISTER）
- **93-103行目**: 標準入力からのインストール処理
- **106-118行目**: URLからのダウンロードとインストール
- **121-141行目**: アップデートセンターからの検索とインストール
- **175-188行目**: プラグインファイルの最終配置処理

**主要処理フロー（DisablePluginCommand）**:
- **76-78行目**: 権限チェック
- **81-94行目**: 戦略enumへの変換
- **97行目**: pluginManager.disablePlugins()呼び出し
- **204-241行目**: リターンコード決定ロジック

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

```
CLI Client (jenkins-cli.jar)
    │
    └─ CLICommand (基底クラス)
           │
           ├─ InstallPluginCommand
           │      ├─ Jenkins.checkPermission(ADMINISTER)
           │      ├─ FileUtils.copyInputStreamToFile() - 標準入力処理
           │      ├─ FileUtils.copyURLToFile() - URLダウンロード
           │      ├─ UpdateCenter.getPlugin() - プラグイン検索
           │      ├─ Plugin.deploy() - インストール実行
           │      └─ PluginManager.dynamicLoad() - 動的ロード
           │
           ├─ EnablePluginCommand
           │      ├─ Jenkins.checkPermission(ADMINISTER)
           │      ├─ PluginManager.getPlugin() - プラグイン取得
           │      ├─ enableDependencies() - 依存有効化
           │      └─ PluginWrapper.enable() - 有効化実行
           │
           ├─ DisablePluginCommand
           │      ├─ Jenkins.checkPermission(ADMINISTER)
           │      ├─ PluginDisableStrategy.valueOf() - 戦略パース
           │      └─ PluginManager.disablePlugins() - 無効化実行
           │
           └─ ListPluginsCommand
                  ├─ Jenkins.checkPermission(ADMINISTER)
                  ├─ PluginManager.getPlugins() - 一覧取得
                  └─ PluginWrapper.hasUpdate() - 更新確認
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| InstallPluginCommand.java | `core/src/main/java/hudson/cli/InstallPluginCommand.java` | ソース | インストールコマンド |
| EnablePluginCommand.java | `core/src/main/java/hudson/cli/EnablePluginCommand.java` | ソース | 有効化コマンド |
| DisablePluginCommand.java | `core/src/main/java/hudson/cli/DisablePluginCommand.java` | ソース | 無効化コマンド |
| ListPluginsCommand.java | `core/src/main/java/hudson/cli/ListPluginsCommand.java` | ソース | 一覧表示コマンド |
| PluginManager.java | `core/src/main/java/hudson/PluginManager.java` | ソース | プラグイン管理クラス |
| PluginWrapper.java | `core/src/main/java/hudson/PluginWrapper.java` | ソース | プラグインラッパー |
| UpdateCenter.java | `core/src/main/java/hudson/model/UpdateCenter.java` | ソース | アップデートセンター |
