(ヽ´ω`) < 助けてほしいマン

わからないことを助けてほしいマンが書くブログ

(ヽ'ω`) < Mailmanのconfig_listコマンドの使用方法と一括設定について

(ヽ´ω`) < config_listコマンドの役割

bin/config_listコマンドでは、コンソールからリストの各種設定を変更できる。

システム管理者がコマンドの実行を行う事を想定されているようで、パスワード等による認証は不要。

単一のリストだけの設定変更であれば、WebUIからのほうが手軽だが、運用形態の変化によるmm_cfg.pyの変更などが発生した場合、複数のリストに対して一括して処理を行うことができる。(繰り返しになるが、mm_cfg.pyを変更しても、既に作成されたリストの設定には影響がない)

(ヽ´ω`) < いくつかの注意点

面倒なことに、config_listコマンドでは、予め変更したい設定内容を記述したファイルを別個に用意してやらないといけない。

このファイルはPythonのスクリプトそのもので、config.pck内の変更したい変数への代入文を記載する。

例としてアーカイブの設定を変更するための設定ファイルは以下の通り

$ vi /tmp/archive_config.py

archive = True
archive_private = 1
archive_volume_frequency = 2

ここで注意したいのが、このファイルに記載されている変数名がmm_cfg.pyでの名前と違う(WebUIやconfig.pckファイルのダンプでの変数名と同じ)であること。

これまでの記事で何度も繰り返しているが、mm_cfg.pyはあくまでもテンプレートであり、実際のリスト毎の設定はリスト作成時にconfig.pckファイルとして出力される。今ここで変更しようとしているのはconfig.pckなので、config.pckの変数名を記述する。

(ヽ´ω`) < config.pck内変数名の取得

実際に入力となる設定変更用のファイルを書く前に、設定を行う変数名を調べておく必要がある。

config.pck内で使用されている変数名は以下の2通りの方法で確認ができる。

WebUIからの確認

WebUIの各設定項目に太字で記載されている、"◯◯◯の詳細"というリンク文字列の"◯◯◯"が対応する変数名となる。

f:id:tsugi-hagi:20141216164422p:plain

処理対象のリストが1つだけであれば、変数名を確認したこの画面から、そのまま変更してしまったほうが早い。

dumpdbコマンドからの確認

コンソールからbin/dumpdb <config.pckファイルの場所>を実行することで、config.pckの中身をテキストで確認することができる。

[root@d09f4ab28203 mailman]# bin/dumpdb lists/mailman/config.pck
[----- pickle ファイル開始 -----]
<----- 1 番目のオブジェクト ----->
{   'accept_these_nonmembers': [],
    'acceptable_aliases': '\n',
    'admin_immed_notify': True,
    'admin_member_chunksize': 30,
    'admin_notify_mchanges': False,
    'admin_responses': {   },
    'administrivia': True,
    'advertised': True,
    'anonymous_list': False,
    'archive': True,
    'archive_private': 0,
    'archive_volume_frequency': 1,
(以下省略)

ここでは各行の:より左側の部分、accept_these_nonmembersacceptable_aliasesが変数名となる。

(ヽ´ω`) < mm_cfg.py内の変数とconfig.pck内の変数の対応付けはどうやるの?

どこかに文章としてあるのかもしれないが、今のところ見当たらないです(ヽ´ω`)

ほとんどの場合はprefixとしてDEFAULT_が付いているかどうかなので、なんとなくはわかるかと。

(ヽ´ω`) < 設定ファイルの形式

変数名がわかったら、それに対する代入文を記述したPythonファイルを作成する。

基本的には下記の通り変数名 = 値を1行ずつ書いて行く。

archive = No
max_num_recipients = 10

値として使用可能なものは以下の通り

  • 数字
  • 文字列(シングルクォーテーションで囲む)
  • 真偽値(True, False)
  • 上記の値を含む配列
  • 上記の値を含む辞書

数字、文字列、真偽値は特に問題なく記述ができるはず。

配列・辞書

配列は複数の値を取りうる変数で、値は"[]"で囲まれる。

典型的な例としては、リストの管理者で、これは変数名ownerで設定される。

# bin/dumpdb lists/mailman/config.pck | grep "'owner'"
    'owner': ['ml-admin@hoge.com', 'john@foo.net', 'take@bar.jp'],

WebUI上で表示は以下の通りとなる。

f:id:tsugi-hagi:20141216164355p:plain

WebUIでの設定時は、指示通りテキストボックスに改行区切りで値を入れていく。

config_listコマンドで設定する場合、入力ファイルを以下のように作成する。

owner = ['ml-admin@hoge.com', 'john@foo.net', `take@bar.jp']

その他の形式にも言えることだが、入力ファイルには`bin/dumpdb'コマンドの出力そのまま

'owner': ['ml-admin@hoge.com', 'john@foo.net', 'take@bar.jp']

のように記述してはいけない。必ず変数名 = 値の形式で書くこと。

時間関係の関数

Defaults.pyの最上部に以下の定義がされている

def seconds(s): return s
def minutes(m): return m * 60
def hours(h): return h * 60 * 60
def days(d): return d * 60 * 60 * 24

これを見ると分かる通り、時間指定のベースは秒単位であり、minutes(), hours(), days()の関数が使用できる。

# 会員権停止の警告メールを3日おきに送信する
bounce_you_are_disabled_warnings_interval = days(3)

真偽値のエイリアス(Yes, On, No, Offの関係)

これまたDefaults.pyの最上部に以下の定義がある。

# Some convenient constants
try:
    True, False
except NameError:
    True = 1
    False = 0

Yes = yes = On = on = True
No = no = Off = off = False

真偽値のYes, yes, On, on, TrueNo, no, Off, off, Falseはそれぞれ同じ意味になるように定義されている。

更に

]# python
Python 2.6.6 (r266:84292, Jan 22 2014, 09:42:36)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> True == 1
True
>>> True == 0
False
>>> False == 0
True
>>> False == 1
False

より、Yes, yes, On, on Trueは1とNo, no, Off, off Falseは0と同値となる。つまり、Yesの代わりに1を使用したり、Offの代わりにnoを使うこともできる。

tryでTrueとFalseの名前を確認しているのは、Pythonの実装系によって定義されていない可能性を考慮しているものと思われる。

(ヽ´ω`) < 実際にやってみる

以上の内容を元に、実際にファイルの作成からコマンドの実行までを行う。 設定内容は以下の通り

  1. 通常のメーリングリストから、Aliasesのようなリストに役割を変更する
  2. Subjectのprefixを無しにする
  3. 配送メールの返信先を、元メールの送信者宛にする
  4. 非メンバーからの投稿を有効にする
  5. 管理者のアドレスを変更する(admin1@hoge.com, admin2@foo.net)
$ vi /tmp/aliases_settings.py

# 2) Subjectのprefixを無しにする
subject_prefix = ""

# 3) 配送メールの返信先を、元メールの送信者宛にする
reply_goes_to_list = 0

# 4) 非メンバーからの投稿を有効にする
generic_nonmember_action = 0

# 5) 管理者のアドレスを変更する(admin1@hoge.com, admin2@foo.net)
owner = ['admin1@hoge.com', 'admin2@foo.net']

3と4の値については、Defautls.pyに値の意味が記載されている。

# Mailman can be configured to "munge" Reply-To: headers for any passing
# messages. One the one hand, there are a lot of good reasons not to munge
# Reply-To: but on the other, people really seem to want this feature. See
# the help for reply_goes_to_list in the web UI for links discussing the
# issue.
# 0 - Reply-To: not munged
# 1 - Reply-To: set back to the list
# 2 - Reply-To: set to an explicit value (reply_to_address)
DEFAULT_REPLY_GOES_TO_LIST = 0

# What shold happen to non-member posts which are do not match explicit
# non-member actions?
# 0 = Accept
# 1 = Hold
# 2 = Reject
# 3 = Discard
DEFAULT_GENERIC_NONMEMBER_ACTION = 1

設定内容を記述したファイルができたので、これをリストに適用する。

# /opt/mailman/bin/config_list --inputfile=/tmp/aliases_settings.py <リスト名>

初めて設定した時は、WebUIやdumpdbコマンドで変更が正しく適用されているかを確認したほうが良い。

(ヽ´ω`) < 全てのリストに対して処理を行う

さて、ようやく本題。

単一のリストの設定を変更するだけであれば、わざわざ変数名を探してファイルを作って…という面倒な手順をふまずに、WebUIで変更を行ったほうが良い。

長々と前振りをしてまで、config_listの使い方を説明したのは、このコマンドを使用し全てのリスト(あるいは特定の複数)に対して、処理を行うケースを想定してのこと。

config_listコマンドに渡すリスト名のパラメータに、ワイルドカードが使えれば楽なのだが、残念ながらそうはなっていない。

ということで、以下の様な単純なスクリプトを作ってぶん回す。

#!/bin/bash

# Mailmanのインストールパス
MAILMAN_PATH=/opt/mailman

# 変更する設定内容
INPUT_FILE=/tmp/aliases_settings.py

# 処理対象のリスト
TARGET_LISTS=`ls $MAILMAN_PATH/lists`
# 特定のリストをファイル記述して処理
## TARGET_LISTS=`cat /tmp/target_lists.txt`

for list in $TARGET_LISTS;
do
    echo $list
    $MAILMAN_PATH/bin/config_list -v --inputfile=$INPUT_FILE $list
done

TARGET_LISTSの中の値で、任意のリストを指定できるので、

# "external-"から始まるリスト全てを処理対象とする
TARGET_LISTS = `ls $MAILMAN_PATH/lists/external-*`

単純なスクリプトなので、これをベースに目的に合わせて作りなおすと吉。

(ヽ´ω`) < withlistってコマンドが全リスト対象のオプションもあって便利そうなんだけど、コレじゃダメなの?

bin/withlistコマンドはPythonを使える人向けに、Mailman操作のプログラムインターフェースを提供するものなので、既に他の人が作成したスクリプトで設定を行うのには便利だけど、そうじゃないケースでは使いにくいかと。

(ヽ´ω`) < 運用計画はしっかりと

というわけで、config_listコマンドの使用方法はそこまで難しくはない。

が、変更を行うときに、単一のファイルで設定を完結できないのは少し面倒くさい。

可能な限りこの作業を繰り返さないために、Mailmanの構築時にしっかりと運用計画とmm_cfg.pyの内容を作成するのが良いです。