玩式草子─ソフトウェアとたわむれる日々

第55回Plamo-5.2へのアップデート用スクリプト

前回はPlamo Linux 5.1から5.2の7ヵ月間にどれぐらいのパッケージが更新されたかを概観し、およそ460個のパッケージが更新されていることを紹介しました。Plamo Linuxでは、パッケージの更新用にupdatepkgというコマンドを用意しており、このコマンドを使えば、古いパッケージの削除と新しいパッケージのインストールが同時に行えます。

それでは、このコマンドを使って更新された460個のパッケージを更新してしまえばPlamo-5.1が5.2になるのかというと、そう単純には行かない問題もあります。今回はそのあたりの話題を取りあげましょう。

無くなったパッケージ

今回のバージョンアップはメンテナンスリリースという位置付けだったので、パッケージ類の大規模な整理は行なわなかったものの、Plamo-5.1にあって5.2では無くなったパッケージがいくつかあります。

前回紹介したように、更新したパッケージや追加したパッケージはファイルの作成時刻を手がかりに簡単に見つけることができるものの、無くなったパッケージは更新履歴であるChange.Logを頼りに調べるしかありません。また、KDEやLibreOfficeでは、バージョンが上がった際にいくつかのパッケージが統合されたり分割されたりしているようです。

それらをざっと調べたところ、Plamo-5.2で無くなったパッケージは、より処理が高速になったというlibjpeg-turboで置き替えたjpegバージョン2.1になってUTF-8以外のファイルシステムに非対応になったvlcおよびvlcのみが使っていたgoom2k4, libaacs, projectM, それからKDEのバージョンが上がった際に分割されたkdeadmin, kdegames, kdenetwork, kdesdk, kdetoys, printer_applet, 同じくLibreOfficeのバージョンが上がった際に整理されたlibobasis_javafilter, libobasis_extension_python_script_providerの13個でした。

更新された後継パッケージが存在する場合、新しいパッケージをupdatepkgコマンドでインストールすれば古いパッケージは自動的に削除されるのに対し、後継パッケージのないこれら13のパッケージはremovepkgコマンドで明示的に削除する必要があります。

設定ファイルの問題

パッケージ管理ツールを利用すれば、古いパッケージからインストールした全てのファイルを漏れなく削除して、新しいパッケージのファイルで置き替えることが簡単にできます。しかし、単純に古いファイルを削除してしまうと困ることもあります。その典型的な例がシステムの設定ファイルで、たとえば/etc/passwdを削除して新しいファイルで置きかえてしまうと、利用者情報が失なわれてしまいます。

もちろん、このような問題はパッケージを作成する際にも考慮されており、Plamo Linuxの場合、パッケージにはpasswdではなくnpasswdという名前のテンプレートファイルを用意して、/etc/passwdが無い場合にのみnpasswdをpasswdにリネームすることで、/etc/passwdの上書きを防ぐようにしています。

一方、パッケージの更新によって、これらのテンプレートファイルに修正が加わることもあります。たとえば、Plamo-5.1から5.2の間でetcパッケージはP18からP21にまで更新され、Change.Logの履歴を見るとpasswdやgroupのテンプレートに対する変更も行われています。

 平成25年11月12日(火)
 
 ・etc-5.0 を更新。
   - polkituser のホームディレクトリを /home/polkituser に設定。
   - libvirt-qemu ユーザ、libvirt、cgred グループを追加。
   (plamo/00_base/etc-5.0-noarch-P19.txz)
 # TODO: PYTHONPATH 環境変数の見直し。

このような場合、修正・追加された設定を反映するには/etc/passwdや/etc/groupを修正しなければなりませんし、かと言って単純に新しいテンプレートファイルでこれらのファイルを上書きしてしまうと既存の設定を壊してしまいます。

前回、Plamo-5.1から5.2の間で更新したパッケージの一覧を紹介しました。その際、ソフトウェアのバージョンは変らないものの、パッケージのビルド番号が更新されているパッケージが複数あることを指摘しました。それらのパッケージではこの種の設定ファイルレベルの修正が多くみられ、その修正を既存のPlamo-5.1環境に反映するためには何らかの工夫が必要となります。

アップデート用スクリプト

上述の問題は、アップデートに関するドキュメントファイルなどに記載して、ユーザに預けてしまうのもひとつの手でしょう。しかし「メンテナンスリリースを名乗っているのに自動アップデートできないのか」と思われるのもしゃくにさわるところです。

そこで、Plamo-5.1から5.2へのアップデートでは、更新したパッケージのみを提供するのではなく、更新するための手順も提供することにしました。

具体的には、Plamo Linuxとして提供している00_baseから11_mateまでの各カテゴリごとに更新したパッケージを集めると共に、各カテゴリごとにupdate.shというシェルスクリプトを用意し、このスクリプトで先に紹介した問題点を吸収することにしました。

このスクリプトでどのような処理をしているかは、実際のスクリプトを見てもらう方がわかりやすいでしょう。以下に示すのは00_baseカテゴリ用のupdate.shからの抜粋です。

  1  #!/bin/sh
  2  
  3  chk=`whoami | grep root`
  4  if [ "$chk.x" = ".x" ]; then
  5    echo "This command should be used by root or use sudo"
  6    exit
  7  fi

パッケージを更新するにはルート権限が必要となるので、まず最初にルート権限で実行しているかをチェックし、ルートでなければその旨を表示して終了します。

 15  # これらのパッケージは設定ファイルのみの修正なので、updatepkgでパッケージを
 16  # 入れ替えるのではなく、必要な修正のみを適用する
 17  # 
 18  # aaa_base-5.0-noarch-P2.txz  sysvinit-2.88dsf-i586-P10.txz
 19  # etc-5.0-noarch-P21.txz      network_configs-0.1-noarch-P3.txz
 20  # hdsetup-5.2-i586-P1.txz     shadow-4.1.4.2-x86-P13.txz
 21  
 22  # for aaa_base-5.0_64-noarch-P2.txz
 23  echo "updating for aaa_base-5.0-noarch-P2.txz"
 24  
 25  if [ ! -d /run ]; then
 26    mkdir /run
 27  fi
 28  chmod 0755 /run
 29  

このあたりからインストール済みの設定ファイル等の修正が始まります。まず最初に取りあげたのはPlamo Linuxのディレクトリ構成などを提供するaaa_baseパッケージです。このパッケージでは、Plamo-5.1(aaa_base-5.0-noarch-P1.txz)から5.2(aaa_base-5.0-noarch-P2.txz)の間に、各種サーバ類が利用する/runというディレクトリが追加されていました。この修正を反映するために、現在の環境にこのディレクトリが無ければ作成し、適切なパーミッションを設定しています。

 30  # for etc-5.0-noarch-P21.txz
 31  # update /etc/group 
 32  echo "updating for etc-5.0_64-noarch-P29.txz"
 33  echo "update /etc/group"
 34  
 35  chk=`grep libvirt /etc/group`
 36  if [ "$chk.x" == ".x" ]; then
 37      groupadd -g 47 libvirt
 38  fi
 39  
 40  chk=`grep cgred /etc/group`
 41  if [ "$chk.x" == ".x" ]; then
 42      groupadd -g 48 cgred
 43  fi
 44  
 45  # update /etc/passwd
 46  echo "update /etc/passwd"
 47  
 48  sed -i -e 's|polkituser:x:21:21:PolicyKit daemon:/dev/null:/bin/true|polkituser:x:21:21:PolicyKit daemon:/home/polkituser:/bin/true|' /etc/passwd
 49  
 50  chk=`grep libvirt-qemu /etc/passwd`
 51  if [ "$chk.x" == ".x" ]; then
 52      useradd -u50 -g36 -d /var/lib/libvirt -s /bin/false libvirt
 53  fi
 54  

次はetcパッケージの変更点の反映です。etcパッケージは/etcディレクトリに展開される各種設定ファイルを提供しており、先に紹介したnpasswdngroupもこのパッケージに含まれています。ここでは、npasswdやngroupに追加された設定を、groupadduseraddを使って実際の/etc/passwdや/etc/groupに反映しています。

合わせて、sedを使って/etc/passwdを修正し、/dev/nullにしていたpolkituserのホームディレクトリを/home/polkituser/に変更しました。

 55  echo "update /etc/template/Source/.xinitrc"
 56  cat << "EOF" | patch -p0 
 57  --- /etc/template/Source/.xinitrc	2011-12-19 17:53:28.000000000 +0900
 58  +++ /etc/template/Source/.xinitrc	2013-11-22 08:56:00.000000000 +0900
 59  @@ -14,7 +14,7 @@
 60   #WM="twm"
 61   WM="xfce"
 62   #WM="kde"
 63  -#WM="gnome"
 64  +#WM="mate"
 65   
 66   unset TERM
 ...

この部分ではetcパッケージが提供するユーザ用各種設定ファイルのテンプレートを、シェルのインライン展開とpatchコマンドを用いて修正しています。ここで修正している/etc/template/Source/.xinitrcファイルは、新規ユーザ作成時にそのユーザのホームディレクトリにコピーされ、X Window System起動時に参照される設定ファイルとなります。

実のところ、このファイルを修正したところで、すでに作成されたユーザの.xinitrcファイルは更新されないので、厳密に言えばPlamo-5.2と同じにはならないものの、作成済みユーザの設定ファイルまで修正するのは大きなお世話のように思うので、テンプレートファイルの修正のみに留めました。

125  # hdsetup-5.2
126  echo "update /usr/lib/setup/Plamo-5.2"
127  
128  if [ -f /usr/lib/setup/Plamo-5.1 ]; then
129    mv /usr/lib/setup/Plamo-5.{1,2}
130  fi
131  

hdsetupパッケージはパッケージ管理ツールとPlamo Linuxのバージョンを示すファイルを提供しています。Plamo-5.1から5.2の更新では、Plamo Linuxのバージョンを示すファイル(/usr/lib/setup/Plamo-5.2)のみが更新されただけなので、それに合わせてファイル名を変えています。

132  # shadow
133  echo "updating for shadow-4.1.4.2-i586-P13.txz"
134  
135  cat <<"EOF" | patch -p0
136  --- /usr/sbin/adduser	2011-12-12 09:00:00.000000000 +0900
137  +++ /usr/sbin/adduser	2013-11-23 09:00:00.000000000 +0900
138  @@ -11,7 +11,7 @@
139   # Time-stamp: <2011-12-07 00:22:20 kojima>
140   
141   DEFAULT_GROUP=users
142  -DEFAULT_AGID=audio,dialout,video,cdrom,pulse,pulse-access,mlocate
...

shadowパッケージは/usr/bin/passwd等、ユーザ認証用のコマンドを提供しているパッケージです。このパッケージもPlamo Linux用に追加したユーザ登録用スクリプト(adduser)のみの修正だったので、該当ファイルを直接修正することにしました。

231  # sysvinit
232  echo "updating for sysvinit-2.88dsf-i586-P10.txz"
233  
234  cat <<"EOF" | patch -p0
235  diff -upr w1/etc/rc.d/rc.M w2/etc/rc.d/rc.M
236  --- /etc/rc.d/rc.M	2013-04-06 12:38:03.000000000 +0900
237  +++ /etc/rc.d/rc.M	2013-12-21 14:38:37.000000000 +0900
238  @@ -70,10 +70,13 @@ if [ -d /proc/asound ] ; then
239     if look_mod snd-seq-oss ; then
240       modprobe snd-seq-oss
241     fi
242  -  if [ -x /usr/sbin/alsactl -a -f /etc/asound.state ] ; then
243  -    alsactl restore
244  -  else
...

sysvinitパッケージは、システムを起動するためのinitコマンドとシステム起動時に実行される各種スクリプトを収めたパッケージです。Plamo-5.2ではシステム起動時に実行されるスクリプトがいくつか修正されているので、その変更を実際のファイルに反映しています。

503  #  おまけ ;-P
504  # /var/log/initscripts.log/sysvinit
505  #
506  vers=`ls /usr/lib/setup/Plamo* | tail -n1 | cut -d"/" -f5`
507  echo "%s %r ($vers) %v" > /etc/motd.in
508  

これは「おまけ」とコメントに書いている通り、おまけ的な処理で、ログイン時に表示されるPlamo Linuxのバージョン番号を"5.2"に直しています。

510  # 以下のパッケージはバイナリも変更されているのでパッケージを更新する
511  #
512  # btrfs_progs-3.12-i586-P1.txz  kmod-13-i586-P3.txz                  nvi-1.79-i586-P4.txz
513  # bzip2-1.0.6-i586-P3.txz       less-382-i586-P2.txz                 openssh-6.4p1-i586-P1.txz
514  # dhcp-4.2.5_P1-i586-P2.txz     libtirpc-0.2.3-i586-P2.txz           openssl-1.0.1e-i586-P2.txz
515  # glibc-2.16.0-i586-P6.txz      linux_firmware-201311-noarch-P1.txz  sudo-1.8.8-i586-P1.txz
516  # iproute2-3.12.0-i586-P1.txz   lsb_release-1.4-noarch-P1.txz
517  
518  for i in *txz ; do
519    updatepkg -f $i
520  done
521  
522  # lzo は 04_xapps から移動してきたが、バージョン等は変ってないのでイジらない。

パッケージの更新だけでは修正することが難しい処理が終われば後は簡単です。00_baseカテゴリでは512行から516行に記述されている14個のパッケージが更新対象として収められているので、それらを順にupdatepkgを使って更新します。

ここで取りあげた00_baseカテゴリにはシステム全体に影響する設定ファイルやスクリプトが多いため、アップデート用のスクリプトもずいぶん長くなってしまいましたが、他のカテゴリでは無くなったパッケージを削除する程度の処理で間にあいます。

たとえば02_x11カテゴリに用意したupdate.shでは、無くなったjpegパッケージを削除するだけで、残りはupdatepkgに任せています。

 1  #!/bin/sh
 2  
 3  chk=`whoami | grep root`
 4  if [ "$chk.x" = ".x" ]; then
 5    echo "This command should be used by root or use sudo"
 6    exit
 7  fi
 8  
 9  # jpegパッケージ(jpeg-8d-{x86_64,i586}-P1.txz)は libjpeg_turbo で replace された
10  
11  removepkg jpeg
12  
13  # 他のパッケージはそのまま更新すればよさそう
14  
15  for i in *.txz ; do
16      updatepkg -f $i
17  done

32ビット用、64ビット用それぞれに、前回紹介した463個の新パッケージとこれら更新用スクリプトをカテゴリごとに整理して、FTPサイトのUpdate/5.1_5.2/以下に公開することで、やっとPlamo-5.2に関する作業は一段落となりました。


実のところ、今回紹介したようなアップデート用スクリプトで既存ファイルの内容を書き替えてしまうのはあまり行儀いい方法とは言えず、セキュリティ意識の高い人からはお小言を食らうかも知れません。

本来、それぞれのパッケージは独立、完結しているべきで、今回、アップデート用スクリプトで対処したような問題も、各パッケージレベルで解決するのが筋でしょう。しかし、そのためにパッケージやパッケージ管理システムを高機能化、複雑化して、中身を見えにくくしてしまうのもあまりいい方向とは思いません。

このあたりのバランスをどうとるかは悩ましい問題ではあるものの、Plamo Linuxのような趣味性の強いディストリビューションでは、手のうちを全部見せてしまって「分かりやすさ」「見えやすさ」を重視する方が「らしい」かな、という気がしています。

おすすめ記事

記事・ニュース一覧