# バッチ設計書 41-999.local

## 概要

本ドキュメントは、FreeBSDのperiodicフレームワークにおける月次ローカルカスタムスクリプト実行バッチ `999.local` の設計仕様を記述するものである。

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

このバッチは、システム管理者が独自に定義した月次メンテナンススクリプトを自動実行するための汎用フレームワークを提供する。`/etc/monthly.local` に配置されたスクリプト、または `monthly_local` 変数で指定された任意のスクリプトを順次実行する。

**業務上の目的・背景**：FreeBSDのperiodicフレームワークは標準的なシステム管理タスクをカバーしているが、各サイト固有の要件に対応するためのカスタマイズポイントが必要である。本バッチは、管理者が月次で実行したい独自のメンテナンス処理（データベースの月次最適化、カスタムレポート生成、アーカイブ処理など）を、periodicフレームワークの統一的な出力管理・通知機構に乗せて実行するために存在する。

**バッチの実行タイミング**：月次（毎月1回、通常は月初にcronから `periodic monthly` 経由で実行される）

**主要な処理内容**：
1. `/etc/defaults/periodic.conf` およびオーバーライド設定ファイルの読み込み
2. `monthly_local` 変数に設定されたスクリプトパスのリストを順次処理
3. 各スクリプトについて絶対パスかどうかを検証
4. スクリプトファイルの存在と実行権限を確認し、適切な方法で実行
5. 各スクリプトの終了コードを集約して最終的な終了コードを返却

**前後の処理との関連**：本バッチは `monthly` periodicスクリプト群の最後（番号999）に実行される。前段の標準月次バッチ（200.accounting、450.status-securityなど）の処理完了後に実行されるため、それらの結果を前提とした後続処理を記述できる。

**影響範囲**：管理者が定義したスクリプトの内容に完全に依存する。スクリプト自体はroot権限で実行されるため、システム全体に影響を与える可能性がある。

## バッチ種別

汎用スクリプト実行（ローカルカスタム処理）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 月次 |
| 実行時刻 | periodic monthlyの実行時刻に準ずる（通常05:30、cron設定依存） |
| 実行曜日 | 該当なし |
| 実行日 | 毎月1日（デフォルトcron設定） |
| トリガー | cron経由 `periodic monthly` |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| periodic.conf読み込み可能 | `/etc/defaults/periodic.conf` が読み取り可能であること |
| monthly_local変数 | スクリプトパスが設定されていること（デフォルト: `/etc/monthly.local`） |

### 実行可否判定

`monthly_local` 変数にスクリプトパスが設定されている限り、常に実行される。個別のスクリプトについては、ファイルの存在・実行権限・パス形式（絶対パスであること）が検証される。enable/disable設定による制御は行われない。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| monthly_local | 文字列（スペース区切り） | No | /etc/monthly.local | 実行するローカルスクリプトのパスリスト |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| /etc/defaults/periodic.conf | シェル変数定義 | デフォルト設定値 |
| /etc/periodic.conf | シェル変数定義 | ユーザオーバーライド設定 |
| monthly_localで指定されたスクリプト | シェルスクリプト | 実行対象のカスタムスクリプト |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | 各スクリプトの実行状況と出力（periodicフレームワークが集約） |

### 出力ファイル仕様

本バッチ自体はファイル出力を行わない。出力はperiodicフレームワークにより `monthly_output` の設定に従ってメール送信またはファイル出力される。

| 項目 | 内容 |
|-----|------|
| ファイル名 | 該当なし（periodicフレームワーク管理） |
| 出力先 | monthly_output設定に依存（デフォルト: root宛メール） |
| 文字コード | システムロケール依存 |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. 設定ファイル読み込み
   └─ /etc/defaults/periodic.confを読み込み、source_periodic_confsでオーバーライド設定を適用
2. 終了コード初期化
   └─ rc=0 で初期化
3. monthly_local変数のスクリプトリストをループ処理
   └─ 各スクリプトについて以下を実行：
      3a. パス形式検証
          └─ 絶対パス（/で始まる）かどうかを確認
      3b. 絶対パスの場合：ファイル存在・実行権限チェック
          ├─ 実行可能ファイル（-x）の場合：直接実行
          ├─ 通常ファイル（-f）の場合：sh経由で実行
          └─ ファイルが存在しない場合：エラーメッセージ出力、rc=2
      3c. 絶対パスでない場合：エラーメッセージ出力、rc=2
4. 集約した終了コードで終了
   └─ 0=成功、2=設定エラー、3=スクリプト実行エラー
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[periodic.conf読み込み]
    B --> C[rc=0 初期化]
    C --> D{monthly_localにスクリプトあり?}
    D -->|なし| K[終了 rc=0]
    D -->|あり| E{絶対パス?}
    E -->|No| F["エラー: Not an absolute path"]
    F --> G["rc=2（未満の場合）"]
    E -->|Yes| H{実行可能ファイル?}
    H -->|Yes| I[直接実行]
    H -->|No| H2{ファイル存在?}
    H2 -->|Yes| I2[sh経由で実行]
    H2 -->|No| F2["エラー: No such file"]
    F2 --> G
    I --> J{実行失敗?}
    I2 --> J
    J -->|Yes| J2[rc=3]
    J -->|No| D
    J2 --> D
    G --> D
    D -->|ループ完了| K[exit rc]
```

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

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

本バッチはデータベース操作を行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | - |

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 2 | 設定エラー | スクリプトパスが絶対パスでない | monthly_local変数の設定を修正し絶対パスを指定する |
| 2 | ファイル不在 | 指定されたスクリプトファイルが存在しない | スクリプトファイルを正しいパスに配置する |
| 3 | 実行エラー | スクリプトの実行が非ゼロで終了 | 対象スクリプトの内容を確認・修正する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構なし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

バッチ失敗時は、periodicフレームワークの出力（メールまたはログ）に記録されたエラーメッセージを確認する。個別のスクリプトが失敗しても他のスクリプトの実行は継続される。終了コードは最も深刻なエラーのコードが保持される。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（シェルスクリプト実行のため） |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 登録スクリプト数に依存（通常1〜数件） |
| 目標処理時間 | スクリプト内容に依存 |
| メモリ使用量上限 | スクリプト内容に依存 |

## 排他制御

本バッチ自体には排他制御機構はない。同時実行の制御が必要な場合は、個別のローカルスクリプト内でロックファイル等による排他制御を実装する必要がある。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 実行ログ | 各スクリプト実行前 | "Running {script}:" メッセージ |
| エラーログ | パスエラー時 | "{script}: Not an absolute path" |
| エラーログ | ファイル不在時 | "{script}: No such file" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | monthly_output設定先（デフォルト: root） |

## 備考

- daily/weekly版の999.localと同一の構造を持つが、`monthly_local` 変数を参照する点が異なる
- デフォルトの `monthly_local` は `/etc/monthly.local` であり、このファイルが存在しない場合は何も実行せずに終了する
- ソースコード: `usr.sbin/periodic/etc/monthly/999.local`
