portsツリーのアップデートを、jailマシンを含めて一発で。

湿度も温度も高くて死にそうな日々の中、皆さん生きてますか?私は、そんな暑い中冷蔵庫のにおいが移ってしまった野菜でチャーハンを作ったら、凄い不味くて死にそうになりました。そんなm-birdです、こんにちわ。
さて、FreeBSDでjailマシンを運用して居る方も多いかと思いますが、こんな場合困るのが「どうやってportsツリーのアップデートをしよう」という話です。
portsツリーが最新なら、hostマシンから各マシンへjexecでjailマシンに入り、そこで"portupgrade -a"でも叩けばオールオッケー☆なのですけれど、しかしportsツリーの更新とパッケージの更新確認程度は自動でやりたい。一発でやりたい。ということで、下の様なシェルスクリプトを書いてみました。

これで一発で更新できる!かつる!

こんなの!cronに登録すると便利だよ!dailyメールで更新が必要なパッケージが届いて嬉しい!

#!/bin/sh

# jail path
jail_path=/usr/local/jails

# number of jail machine
num=3

# machine name
machine_name_1="webserver"
machine_name_2="vpnserver"
machine_name_3="dbserver"

#============================

if [ -x /usr/sbin/portsnap ]; then
	PORTSNAP=/usr/sbin/portsnap
elif [ -x /usr/local/sbin/portsnap ]; then
	PORTSNAP=/usr/local/sbin/portsnap
else
	echo "Cannot find portsnap(abort)"
	exit 64
fi

# HOST tree update
echo "HOST Ports/packages update check:"
(portsnap fetch && portsnap update) > /dev/null 2>&1
if [ $? -eq 0 ]; then
	/usr/local/sbin/portsdb -uU > /dev/null 2>&1
	/usr/local/sbin/portversion -vFL=
	flag=0
else
	echo "Failure of portsnap(*ERROR*)"
	flag=1
fi

#JAIL MACHINE tree update
if [ $flag -eq 0 ]; then
	# basejail update
	(ezjail-admin update -P) > /dev/null 2>&1
	(PORTSDIR=${jail_path}/basejail/usr/ports portsdb -uU) > /dev/null 2>&1

	# jail machine portversion
	i=1
	while [ $i -le $num ]; do
		echo ''
		eval echo \$\{machine_name_$i\}" Ports/packages update check:"
		eval chroot $jail_path/\$\{machine_name_$i\} /usr/local/sbin/portversion -vFL=
		i=`expr $i + 1`
	done
fi

exit $flag

スクリプトの冒頭にある、以下の部分を環境に合わせて書き換えて下さい。

  • jail_path - 各jailマシンのディレクトリが置いてあるディレクト
  • num - 合計のjailマシン台数(0オリジンじゃないよ、1始まり!)
  • machine_name_NUMBER - NUMBERの部分は1から連番で記述して下さい

という訳で、見るからの手抜きスクリプトですが、使えればいいんです。細けぇこたぁいいんだよ!
なお、上の記述では portsnap cronとありますので、cronに登録せずに使う場合はportsnap fetchと書き換えて利用して下さい。また、更新結果以外は/dev/nullに捨ててしまっているので、暫く何も表示されません。コーヒーでも煎れてまたーりお待ち下さい。

実行例

私の環境で、3台分の更新をしてみました。

[m-bird@Host ~]ssh$ sudo ./ports_tree_update_withjail.sh
Password:
HOST Ports/packages update check:
[Updating the portsdb <format:bdb_btree> in /usr/ports ... - 20334 port entries found .........1000.........2000.........3000.........4000.........5000.........6000.........7000.........8000.........9000.........10000.........11000.........12000.........13000.........14000.........15000.........16000.........17000.........18000.........19000.........20000... ..... done]
cups-base-1.3.9_3           <  needs updating (port has 1.3.10_2)
gnutls-2.6.4                <  needs updating (port has 2.6.5)
help2man-1.36.4_2           <  needs updating (port has 1.36.4_3)
libdnet-1.11_2              <  needs updating (port has 1.11_3)
libiconv-1.11_1             <  needs updating (port has 1.13)
...省略...
webserver Ports/packages update check:
[Updating the portsdb <format:bdb_btree> in /var/db/pkg ... - 20334 port entries found .........1000.........2000.........3000.........4000.........5000.........6000.........7000.........8000.........9000.........10000.........11000.........12000.........13000.........14000.........15000.........16000.........17000.........18000.........19000.........20000... ..... done]
ImageMagick-nox11-6.4.8.3   <  needs updating (port has 6.5.2.10) 
apache-2.2.11_3             <  needs updating (port has 2.2.11_7) 
apr-gdbm-db42-1.3.3.1.3.4_1  <  needs updating (port has 1.3.5.1.3.7_3) 
bash-3.2.48_1               <  needs updating (port has 4.0.24) 
...省略...
dbserver Ports/packages update check:
[Updating the portsdb <format:bdb_btree> in /var/db/pkg ... - 20334 port entries found .........1000.........2000.........3000.........4000.........5000.........6000.........7000.........8000.........9000.........10000.........11000.........12000.........13000.........14000.........15000.........16000.........17000.........18000.........19000.........20000... ..... done]
libiconv-1.11_1             <  needs updating (port has 1.13) 
mysql-client-5.1.30         <  needs updating (port has 5.1.35) 
mysql-server-5.1.30         <  needs updating (port has 5.1.35) 
perl-5.8.9                  <  needs updating (port has 5.8.9_3) 

ホストのportsツリーの更新をした後に各jail環境の更新をしている事が分かります。
因に、スクリプトの実行が完了するまでに二十数分掛かりました。

参考

上記のスクリプトは、以下のサイトのスクリプトを参考に作成させて頂きました。

修正(2009/07/02)

バグ修正をしました。
jailマシンのルートが収まっているディレクトリを指定する、jail_pathが一部用いられず、パス直打ちで指定していた部分を修正しました。
portsdbで-FオプションによるINDEXのフェッチを行っていた部分を、-uUオプションにして自前のINDEX作成にしました。
これにより、処理時間が伸びることとなりましたが、-FオプションによるINDEXファイルの更新が遅かったり、不整合を起こしたりすることが多いためです。