PonyMailでMLアーカイブ検索サイトを立てる

# はじめに

十年以上前から動いていたMHonARC + Namazuによるメーリングリスト(以下ML)アーカイブ検索システムがすっ飛ぶトラブルが発生したらしく、ヘルプ要請がきた。そのまま復旧させてもいいのだが、せっかくなのでイマドキの検索システム的なものが楽に構築できないか探したところ、PonyMailというフリーウェアに行き着いた。そこそこ良さげなのに日本語情報をあまり見かけないので、紹介したい。
（なお、元のトラブルは無事復旧できたようで、結局こちらの出番はなかった）

# PonyMailについて

まずは公式サイトを見てもらうとよいと思う。
https://ponymail.incubator.apache.org/
https://github.com/apache/incubator-ponymail

<img src="https://github.com/apache/incubator-ponymail/raw/master/site/images/demo.png" width=60%>


動作サイトの例
https://lists.apache.org/


## Pros
★をつけた項目は手元で動かして判断した項目。他はカタログスペックから分かるもの。

* 見た目がMHonARCよりカッコイイ(個人の感想です)
* 検索システムを内包(ElasticSearchがバックエンド。Namazuを別に立てなくて良い)
* mbox形式などからのimportができる。★このときList-Idヘッダ等からML名を拾い自動分類する。これらがないメールはインポート時に捨てられる。
  * （個人宛メールなども含まれるような）個人のメールボックスを、とりあえずまるごと突っ込んでしまえばMLのデータだけを拾ってくれるということ。
  * ★なおMaildir形式にも対応しているらしいが手元では動かなかった。未調査。
* .forward的な仕組みで1通づつ投入することができ、到着から検索可能になるまでのタイムラグが少ない。
  * アタリマエに思えるかも知れないが、かつてfessベースで同等の仕組みを作ろうとした際にコレがネックでポシャった経緯あり。
* 添付ファイルの情報も失わない。★ただし検索時に添付ファイル内までの検索をしてくれるわけではない。
* ★日本語の取扱いがマトモ。この手の検索システムでは、日本語を相手にすると（エンコーディングのせいで）残念な状況に陥ることが多々ある（偏見）。PonyMailは少なくとも破綻しない（手元で試した限りではiso-2022-jp文字列もutf-8文字列も分け隔て無く検索できている）。
  * 添付ファイルの日本語名はデコードしてくれない。ここだけ少し残念。
  * なお大量インポートした際に稀に文字化けのままとなるメールが発生したが、条件までは追い切れていない。
* ML流量統計とか見れて楽しい。
* なお、閉鎖環境で利用すること前提なので認証機能は評価していない。OAuthが使えるらしい。

## Cons
★をつけた項目は手元で動かして判断した項目。他はカタログスペックから分かるもの。

* ElasticSearch 2.xベース。古い。★なんらかの制約に引っかかるせいで6.xや7.xでは導入に失敗することを確認済み(setup.py時に失敗する)。
  * ★なお、2.xや5.xには導入できることを確認済み。
* luaが動作するhttpd(=Apache2)の動作環境が必要。
  * ★ソースコードを読むとNginx(ngx_lua)のことも考慮しているように読めるが、残念ながら一部機能（生メールを表示する機能等）が動作しない。
    * おそらくngx_luaがpath_infoを拾えていないように思う
    * ポート番号を変えて起動したApache2でponymailを使い、Nginxでリバプロするとかで回避は可能。この場合はSELinuxとの干渉も注意(本記事の範囲外)。

# インストール
基本的に公式サイトの情報どおりなのだが、微妙にバージョン情報が古いなどの問題あり。このため要点だけを記す。

## Ubuntu
https://github.com/apache/incubator-ponymail/blob/master/docs/INSTALL.ubuntu.md

OSに縛り/こだわりがないなら一番導入が楽。情報は14.04LTS/16.04LTS用だが、同じ手順にて20.04LTSでもインストール可能。18.04LTSは試してない。
途中で足すapt-lineのおかげでelasticsearchは2.xになる。

### elasticsearch 2.x
elasticsearch起動時に、JVMのバージョン不整合に起因するGCエラーで起動できない場合には/usr/share/elasticsearch/bin/elasticsearch.in.sh を以下のような感じに編集する。

```bash:/usr/share/elasticsearch/bin/elasticsearch.in.sh
if [ "x$ES_GC_OPTS" = "x" ]; then
  # 以下2行は古い記述なので消す
  #ES_GC_OPTS="$ES_GC_OPTS -XX:+UseParNewGC"
  #ES_GC_OPTS="$ES_GC_OPTS -XX:+UseConcMarkSweepGC"
  # 以下1行を代わりに記述する
  ES_GC_OPTS="$ES_GC_OPTS -XX:+UseG1GC"
  # 以下2行はもとからあるまま
  ES_GC_OPTS="$ES_GC_OPTS -XX:CMSInitiatingOccupancyFraction=75"
  ES_GC_OPTS="$ES_GC_OPTS -XX:+UseCMSInitiatingOccupancyOnly"
fi
```

## CentOS
https://github.com/apache/incubator-ponymail/blob/master/docs/INSTALL.centos.md

### luarocks
https://luarocks.github.io/luarocks/releases/
luarocksはメジャーバージョンが変わっているので注意(本記事時点での最新は3.3.1)。
予想通り3.x系では不具合を起こすことを確認済み。
2.x系の最新版である2.4.4を使用することで問題なく先に進める。

なお、luasocketがlua-socketと記述されている ~~初見殺し~~ ミスがある。正しくは以下となる。

```bash
sudo luarocks install luasocket
sudo luarocks install luasec OPENSSL_LIBDIR=/usr/lib64/
sudo luarocks install lua-cjson
```

### Python 3.x
素で入れると環境汚し過ぎちゃうので、pyenv等で環境分離してから新しめのをテキトウに入れるのが個人的にオススメです。
私はsystem-wide anyenvからpyenv入れて処理してしまいました。
(pyenvを使う場合、あとで新規メールの取り込み設定の際にPATHが通ってないとか発生する可能性ありなので、一長一短...)

pipで入れるelastichsearchは、後で入れるelasticsearchとメジャーバージョンを揃えたいので、5.x系最新である5.5.3をバージョン指定で。

```bash
sudo pip install elasticsearch==5.5.3
```

### openjdk
システムで用意されてるヤツで行けた(GC周りはUbuntuと同様にいじったかも？)ので軽くスルーしてしまいました。

### elasticsearch 5.x
2.xの配布物がみつからない→7.xで試してみるが、セットアップでコケる→6.xで試してみるが同じくコケる→5.xでようやく動く。
~~ココの調査で苦しんだのがこの記事を書くモチベーションになりました~~

```:/etc/yum.repos.d/elasticsearch.repo
[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
```
これ書いてyum check-updateしてyum install elasticsearchで。elasticsearch-5.6.16-1.noarch が入った。


# 初期設定
ここまで来たらあとは楽なはず。httpdとかの設定はドキュメント通り。

setup.py叩いてelasticsearchの情報やら送信用smtpサーバやら取り込むMLの条件を設定して終わり。1～4選ぶヤツはテキトウに4にした。
この時点ではhttpdのトップはponymailのロゴだけで、MLはカラッポのはず。

setup.pyがエラーを吐いた場合の確認項目

* elasticsearchの起動状況(ps -ef|grep elasticsearch)
* elasticsearchのポート待ち受け状況(lsof -i -P | grep 9200)
* elasticsearchのバージョン情報(rpm -q elasticsearch、yum info elasticsearch等)
  * そんなインデックス作れねーよ系のエラーの場合、2.x/5.xでなく6.xや7.xが入ってしまっている可能性あり。

# インポート
mbox形式のファイルの拡張子を「.mbox」にしておき、特定のフォルダにまとめてから以下のように実行する。
実行後しばらくしたらhttpdのトップページ右側に取り込んだML名が出てくるハズ。

```
python import-mbox.py --source /path/to/mboxdir/
```

# 新規メールの取り込み設定

https://github.com/apache/incubator-ponymail/blob/master/docs/ARCHIVING.md

/etc/mail/aliases や .forward 的なヤツでarchiver.pyに渡すとデータを一通づつ取り込んでくれる。らしい。
らしいというのは、まだちゃんと手元で試していないから。というか休みだからMLにメールが来ないので実験できない。
必要に応じて後から編集するかも。