# バッチ設計書 32-make-distribution.sh

## 概要

本ドキュメントは、Sparkのバイナリディストリビューションを作成するスクリプト `dev/make-distribution.sh` のバッチ設計書である。本スクリプトはSparkプロジェクトのソースコードからビルドを実行し、デプロイ可能なバイナリパッケージ（fat JAR含む）をdist/ディレクトリに生成する。オプションでtar.gzアーカイブ、pip用Pythonパッケージ、R用パッケージ、Spark Connect対応パッケージの生成にも対応する。

### 本バッチの処理概要

本スクリプトは、Sparkの開発ビルドからリリース用のバイナリディストリビューションを作成する包括的なビルド・パッケージングツールである。

**業務上の目的・背景**：Apache Sparkのリリースプロセスにおいて、ソースコードからデプロイ可能なバイナリ配布物を生成する必要がある。本スクリプトはMaven/SBTによるビルド実行から、JAR/設定ファイル/サンプルコードの配置、tar.gzアーカイブ作成、pipパッケージ生成、Rパッケージ生成、Spark Connect対応配布物の作成まで、ディストリビューション作成の全工程を自動化する。Scalaライブラリを含むfat JARを生成するため、生成された配布物は自己完結型（self-contained）であり、別途Scalaのインストールを必要としない。

**バッチの実行タイミング**：リリースビルド時、テスト配布物作成時、開発者がローカルで配布パッケージを作成する際に手動実行される。CI/CDパイプラインからの自動実行も想定される。

**主要な処理内容**：
1. コマンドライン引数の解析（--tgz, --pip, --r, --connect, --mvn, --sbt-enabled, --sbt, --name）
2. Java/Maven/SBTの環境検証
3. Sparkプロジェクトのバージョン情報・Scalaバージョン・Hadoopバージョンの取得
4. Maven（またはSBT）を使用したプロジェクトのクリーンビルド（テストスキップ）
5. dist/ディレクトリへのJAR、設定テンプレート、bin/sbin/python/data等の配置
6. YARN用シャッフルJAR、Kubernetes用Dockerfiles・テストファイルのコピー
7. examplesのJARとソースコードのコピー（重複JARの除去含む）
8. ライセンス・NOTICE・RELEASEファイルのコピー
9. オプション：tar.gzアーカイブの作成（macOS対応のtar引数含む）
10. オプション：pip用Pythonパッケージの作成（classic/connect/client）
11. オプション：R用パッケージのビルド・検証
12. オプション：Spark Connect対応ディストリビューションの作成（環境変数注入）

**前後の処理との関連**：ビルド前にソースコードがコンパイル可能な状態である必要がある。生成されたディストリビューションは、docker-image-tool.shによるDockerイメージビルドやリリース配布の入力となる。

**影響範囲**：dist/ディレクトリの内容を完全に再作成する（既存のdist/は削除される）。ビルドプロセスではMavenローカルリポジトリへの書き込みが発生する。--tgzオプション使用時はSPARK_HOME直下にtar.gzファイルが生成される。

## バッチ種別

ビルド・リリース（バイナリディストリビューション作成）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（リリースビルド時、手動実行） |
| 実行時刻 | N/A |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動実行 / CI/CDパイプライン |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| JAVA_HOME | Javaの実行環境が必要。JAVA_HOME環境変数が設定されているか、java コマンドがPATH上に存在すること |
| Maven | `build/mvn`経由でMavenが利用可能であること（SBTモードの場合はSBT） |
| ソースコード | Sparkプロジェクトのソースコードがビルド可能な状態であること |
| Python3（--pip時） | pip用パッケージ生成時はpython3が必要 |
| R（--r時） | Rパッケージ生成時はRが必要 |

### 実行可否判定

JAVA_HOME未設定かつjavaコマンドが見つからない場合はエラー終了する。Maven（またはSBT）コマンドが見つからない場合もエラー終了する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --tgz | フラグ | No | false | tar.gzアーカイブを作成する |
| --pip | フラグ | No | false | pip用Pythonパッケージを作成する |
| --r | フラグ | No | false | R用パッケージを作成する |
| --connect | フラグ | No | false | Spark Connect対応ディストリビューションを作成する（--tgzと併用） |
| --mvn | string | No | $SPARK_HOME/build/mvn | Mavenコマンドのパス |
| --sbt-enabled | フラグ | No | false | SBTでビルドする |
| --sbt | string | No | $SPARK_HOME/build/sbt | SBTコマンドのパス |
| --name | string | No | Hadoopバージョン | ディストリビューション名 |
| Maven/SBTオプション | string | No | なし | 追加のMaven/SBTビルドオプション（-Pプロファイル等） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Sparkソースコード全体 | Java/Scala/Python/R | ビルド対象のソースコード |
| pom.xml | XML | Mavenプロジェクト定義（バージョン情報等の取得元） |
| conf/*.template | テンプレート | 設定ファイルテンプレート |
| LICENSE-binary / NOTICE-binary | テキスト | ライセンスファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| $SPARK_HOME/dist/ | ディレクトリ | バイナリディストリビューション本体 |
| $SPARK_HOME/dist/jars/ | JAR | Sparkおよび依存ライブラリのJAR |
| $SPARK_HOME/dist/examples/ | JAR/ソース | サンプルアプリケーション |
| $SPARK_HOME/dist/conf/ | テンプレート | 設定ファイルテンプレート |
| $SPARK_HOME/dist/bin/ | スクリプト | CLIスクリプト群 |
| $SPARK_HOME/dist/sbin/ | スクリプト | デーモン管理スクリプト群 |
| $SPARK_HOME/dist/python/ | Python | PySpark |
| spark-$VERSION-bin-$NAME.tgz | tar.gz | アーカイブ（--tgzオプション時） |
| spark-$VERSION-bin-$NAME-connect.tgz | tar.gz | Spark Connectアーカイブ（--connect + --tgzオプション時） |
| python/dist/*.tar.gz | tar.gz | pip用パッケージ（--pipオプション時） |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | spark-$VERSION-bin-$NAME.tgz（--tgz時） |
| 出力先 | $SPARK_HOME直下 |
| RELEASEファイル | バージョン・Hadoopバージョン・ビルドフラグ・gitリビジョンを記録 |

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数解析
   └─ --tgz, --pip, --r, --connect, --mvn, --sbt-enabled, --sbt, --name の解析
2. Java環境検証
   └─ JAVA_HOME → rpm → which java の順に検出、見つからなければエラー終了
3. Gitリビジョン取得
   └─ git rev-parse --short HEAD でリビジョン文字列を取得（任意）
4. ビルドツール検証
   └─ Maven/SBTコマンドの存在確認
5. バージョン情報取得
   └─ project.version, scala.binary.version, hadoop.version をMaven/SBTから取得
6. プロジェクトビルド
   └─ Maven: clean package -DskipTests（テスト・javadoc・scaladocスキップ）
   └─ SBT: clean package
7. dist/ディレクトリ作成・配置
   └─ 旧dist/を削除し新規作成
   └─ assembly JARのコピー
   └─ YARN shuffle JAR（存在時）のコピー
   └─ Kubernetes dockerfiles/tests（存在時）のコピー
   └─ examples JAR・ソースのコピー（重複JAR除去）
   └─ ライセンス・NOTICE・CHANGESファイルのコピー
   └─ data/conf/bin/sbin/python/Rのコピー
8. [オプション] pipパッケージ作成
   └─ classic/connect/clientの3つのsetup.py sdistを実行
9. [オプション] Rパッケージ作成
   └─ check-cran.sh実行、バージョン調整、install-source-package.sh実行
10. [オプション] tar.gzアーカイブ作成
    └─ macOS対応のtar引数でアーカイブ生成
11. [オプション] Spark Connectディストリビューション作成
    └─ 環境変数(SPARK_CONNECT_MODE等)をbin/スクリプトに注入してアーカイブ生成
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[引数解析]
    B --> C{Java環境OK?}
    C -->|いいえ| D[エラー終了]
    C -->|はい| E{ビルドツールOK?}
    E -->|いいえ| D
    E -->|はい| F[バージョン情報取得]
    F --> G[プロジェクトビルド<br/>Maven/SBT]
    G --> H[dist/ディレクトリ作成・配置]
    H --> I{--pip?}
    I -->|はい| J[pipパッケージ作成]
    I -->|いいえ| K{--r?}
    J --> K
    K -->|はい| L[Rパッケージ作成]
    K -->|いいえ| M{--tgz?}
    L --> M
    M -->|はい| N[tar.gzアーカイブ作成]
    M -->|いいえ| O[バッチ終了]
    N --> P{--connect?}
    P -->|はい| Q[Spark Connect配布物作成]
    P -->|いいえ| O
    Q --> O
```

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

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

データベース操作なし。本スクリプトはファイルシステム操作とビルドツール呼び出しのみを行う。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| -1 | JAVA_HOME未設定 | JAVA_HOME未設定かつjavaコマンドがPATH上にない | JAVA_HOMEを設定するかJDKをインストール |
| -1 | ビルドツール不在 | Maven/SBTコマンドが見つからない | --mvnまたは--sbtフラグで正しいパスを指定 |
| 1 | ビルドエラー | Maven/SBTのビルドが失敗 | ビルドエラーログを確認し、依存関係やコンパイルエラーを解消 |
| 1 | 不明な引数 | サポートされていないコマンドライン引数が指定された | --helpでサポートされる引数を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

- ビルド失敗時：Maven/SBTの出力ログを確認し、コンパイルエラーや依存関係の問題を解消する
- dist/ディレクトリは失敗時に中途半端な状態で残る可能性があるため、手動で`rm -rf dist/`を実行してから再実行する
- `set -e`と`set -o pipefail`が有効なため、パイプライン中の任意のコマンド失敗で即座にスクリプトが終了する

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイルシステム操作のみ） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A（失敗時はdist/を手動削除） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回（1ディストリビューション生成） |
| 目標処理時間 | ビルド環境に依存（通常数十分〜1時間程度） |
| メモリ使用量上限 | MAVEN_OPTS: -Xss128m -Xmx4g -XX:ReservedCodeCacheSize=128m（Mavenビルド時） |

## 排他制御

同一SPARK_HOME上での同時実行は非対応。dist/ディレクトリの削除・再作成が行われるため、並行実行すると競合が発生する。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | Sparkバージョン、ディストリビューション名 |
| 進捗ログ | ビルド中 | `set -x`による全コマンドのトレース出力 |
| ビルドコマンドログ | ビルド実行時 | 実行されるMaven/SBTコマンドの全文 |
| バージョン情報ログ | バージョン取得後 | Sparkバージョン、Scalaバージョン、Hadoopバージョン |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ビルド処理時間 | 環境依存 | CI/CDシステム |
| ビルド終了コード | 0以外 | CI/CDシステム |

## 備考

- `set -x`により全コマンドがトレース出力されるため、デバッグが容易である
- `set -o pipefail`によりパイプライン中の失敗も検出される
- SparkR関連の機能はApache Spark 4.0.0以降で非推奨（deprecated）とされている
- Spark Connectディストリビューション（--connect）では、beeline/pyspark/spark-shell/spark-submitの各スクリプトにSPARK_CONNECT_MODEまたはSPARK_CONNECT_BEELINE環境変数がデフォルト有効で注入される
- MAVEN_OPTSのデフォルト値は`-Xss128m -Xmx4g -XX:ReservedCodeCacheSize=128m`
- macOSでのtar実行時には`--no-mac-metadata --no-xattrs --no-fflags`フラグが付与される
