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

第66回Plamo-5.3.1とget_pkginfoスクリプト

前回、年末ギリギリの12/31にリリースしたPlamo-5.3について紹介しました。ここ数年、12月に新バージョンをリリースした後は、ユーザからの反応を待つ意味もあって、春ごろまでは冬眠モードに入っていたものの、さすがに丸一年ぶりのリリースとなると、積み残しパッケージの整理や旧バージョンからのアップデータの準備などの残務が山積みで、年明け後も忙しい日々が続いています(苦笑⁠⁠。

加えて、年末年始に報告された新しいセキュリティ問題やPlamo-5.3を試したユーザからのバグレポートも集まってきました。そこで、それらをまとめてPlamo-5.3の改訂版であるPlamo-5.3.1をリリースすることにしました。

今回はPlamo-5.3.1に向けた近況報告と、最近開発したPlamo Linux用の更新パッケージチェック用スクリプトを紹介しましょう。

Plamo-5.3.1の現状

Plamo-5.3.1はPlamo-5.3に見つかっている各種不具合を修正した改訂版です。修正箇所はCVE等で報告されたセキュリティ問題への対応から、パッケージ作成ミスによる不具合までさまざまで、それらのうちから主要なものを紹介しましょう。

Python

Python2系が2.7.3のままだったので2.7.9に更新しました。あわせて、これからはPython3系が主流になるだろうと考えて、"Python"というパッケージ名はPython3系を指すことにして、Python2系は"Python2"というパッケージ名にすることにしました。

その結果、Plamo-5.3では"python"(Python2系)と"Python3"(Python3系)だったパッケージ名が、Plamo-5.3.1では"Python2"(Python2系)と"Python"(Python3系)になりました。

パッケージ名はわかりやすくはなったとは思うものの、ベース名が変ったためupdatepkgだけでは更新できなくなったので、バージョンアップ時には旧バージョンをremovepkgで削除後、新バージョンをインストールする作業が必要になります。

gfortran/gccgo

動作に必要なライブラリ類が抜けていたので32ビット版のgfortran/gccgoパッケージを更新しました。64ビット版は必要なライブラリがきちんと含まれていたので変更していません。同じビルドスクリプトを動かしたはずなのに、なぜ64ビット版と32ビット版で違いが生じたのかまでは追求していません。

KDE PIM関連

KDEのPIM(Personal Information Management)関連の機能は筆者自身ロクに使っていなかったこともあり、関連パッケージの不足やライブラリの不適合を見逃していました。

そのため、アカウント関連のライブラリ(libaccounts_glib, accounts_qt)やFacebook API用ライブラリ(libkfbapi⁠⁠、Google API用ライブラリ(libkgapi)などを追加するとともに、64ビット版ではakonadiパッケージを再構築しました。

xfce関連

Xfce用の新しいテーマ集やアイコン集を追加しました。あわせてデフォルトで適用するテーマを変更したので、Xfceの見た目がずっとクールになりました。

図1 デフォルトテーマやアイコンを変更したXfceの画面
図1 デフォルトテーマやアイコンを変更したXfceの画面

Systemd 関連

最近普及してきたSystemdの機能を利用しようとして、xfce4-sessionが正常終了できなかったり、xorg-serverが余計なエラーメッセージを出していたので、ビルド時に --disable-systemd を明示して再構築しました。

microcode_ctl

Plamo-5.3で収録していたmicrocode_ctl-1.21では最近のIntel CPUへ対応できないようなので、Intelが公開している最新のmicrocode集とともにmicrocode_ctl-2.1_6 に更新しました。

microcode_ctl-1.21で提供されていたAMD製CPUへのmicrocodeは、現在ではlinux_firmwareパッケージの一部として提供され、Plamo-5.3にも含まれているので、microcode_ctlパッケージを更新してもAMD製CPUへの影響は無さそうです。

ptexlive

PDF操作用のpopplerライブラリへの参照が古いままだったのを修正しました。最近のOSには欠かせない「共有ライブラリを使った動的リンク」という仕組みは、便利ではあるものの、何ら変更していないはずのバイナリがいつの間にか動かなくなることがある、という問題を改めて認識させられました(苦笑⁠⁠。

Linux-PAM

Linux-PAMが1.1.5のままだったので、最新の1.1.8に更新しました。あわせて、パッチで対応していたpam_console.soを廃止して、関連する設定を修正しました。

grub-2.02

前回触れた、Btrfs上にカーネルを置くとgrubが正しくインストールできない、という問題が解決するかと思ってgrubを開発中の2.02に更新しました。しかしながら、詳しく調べたところ、この問題はgrubのせいではなく、パーティションを切るときにfdiskを使うかcfdiskを使うかに依存していました。

Plamo-5.3のインストーラで使っているパーティション作成ツールfdiskとcfdiskは、fdiskがコマンドラインで指示する形式なのに対し、cfdiskはメニュースタイルで指示できるので、cfdiskの方が好まれているように思います。

実のところ、fdiskとcfdiskはコマンドの入力方法こそ違え、HDD上にパーティションを作成する処理は同じだろうと思っていました。しかしながら両者が作成したパーティションを比較したところ、最初のパーティションをどのセクタから始めるかが異なっており、fdiskでは最近の大容量HDDで標準的な2048セクタ目からパーティションを切るのに対し、cfdiskではかっての標準だった63セクタ目からになっていました。

以下の例は仮想環境(VirtualBox)上なのでHDDの容量はずいぶん小さいものの、fdiskで切ったパーティションでは最初のパーティション(/dev/sda1)が2048セクタ目から始まっています。

$ sudo fdisk -l
Disk /dev/sda: 17.2 GB, 17179869184 bytes, 33554432 sectors
Units = sectors of 1 * 512 = 512 bytes
...
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1            2048    33550000    16773976+  83  Linux
/dev/sda2        33550001    33554431        2215+  82  Linux swap / Solaris

一方、cfdiskで切ったパーティションでは、同じ/dev/sda1が63セクタ目から始まっています。

$ sudo fdisk -l
Disk /dev/sda: 34.4 GB, 34359738368 bytes, 67108864 sectors
Units = sectors of 1 * 512 = 512 bytes
...
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1   *          63    66412709    33206323+  83  Linux
/dev/sda2        66412710    67108863      348077   82  Linux swap / Solaris

このようにcfdiskでrootパーティションを切ると、HDDの先頭から最初のパーティションまでの空き領域がfdiskで切った場合よりもはるかに小さくなり、Btrfs上のカーネルをロードするために必要なモジュール等を収め切れないため、grubのインストールに失敗していたようです。

この問題をきちんと解決するにはインストーラの改修が必要になるので、次のバージョンアップ時の課題ということにしました。

脆弱性関連の修正

新たに報告された情報や見落していた情報を整理した結果、以下のような更新を行いました。

openssl-1.0.1k

CVE-2014-3571等で報告されているDTLS(Datagram TLS)関連の修正を反映したバージョンに更新しました。

curl-7.40.0

libcurlのTLSセッションID関連の不具合やURL injection問題を修正したバージョンに更新しました。

binutils-2.25

CVE-2014-8484等で報告されたlibbfd関連の不具合を修正したバージョンに更新しました。

libevent-2.0.22

evbuffer APIのオーバーフロー関連の不具合を修正したバージョンに更新しました。

jasper-1.900.1 ビルド4(P4)

jasper自体のバージョンは変っていないものの、報告されているヒープオーバーフロー等を修正するパッチをあてて再構築し、ビルド番号を更新しました。

ここで紹介した以外にも、firefox/thunderbirdの定例的な更新やmateデスクトップ環境の初期化回りの調整、動画再生をGPU側で支援するlibva関連の更新など、Plamo-5.3のDVDイメージをまとめて以後、すでに90近くのパッケージが更新されているようです。

$ find Plamo-5.x/x86/plamo -newer plamo-5.3_x86_dvd.iso -type f -a -name "*txz" -print | \
  grep -v 'old/' 
Plamo-5.x/x86/plamo/00_base/etc-5.0-noarch-P26.txz
Plamo-5.x/x86/plamo/00_base/grub-git_20150121-i686-P2.txz
Plamo-5.x/x86/plamo/00_base/hdsetup-5.2-i586-P3.txz
Plamo-5.x/x86/plamo/00_base/linux_firmware-201501-noarch-P1.txz
Plamo-5.x/x86/plamo/00_base/linux_pam-1.1.8-i686-P1.txz
Plamo-5.x/x86/plamo/00_base/lsb_release-1.4-noarch-P3.txz
...
$  find Plamo-5.x/x86/plamo -newer plamo-5.3_x86_dvd.iso -type f -a -name "*txz" -print | \
   grep -v 'old/' | wc -l
89

更新パッケージチェック用スクリプト

この連載でも何度か触れたように、ディストリビューションというのは生き物で、更新が滞れば衰えてゆきます。その意味で、新バージョンのリリース直後でも、このように活発にパッケージが更新されるというのはありがたい話ではあるものの、Plamo Linuxの場合、ユーザがこれらパッケージ更新を簡単に知る方法が無いことが以前から気になっていました。

もちろん、セキュリティ関連などの重要な更新はメーリングリストやホームページ等でアナウンスするものの、それほど緊急性の高くない更新は広報していないので、それらをチェックするには更新履歴を記録したChange.Logを確認するしかありません。

DVDイメージ等から手元にPlamo Linuxのパッケージツリーを用意して、cronとwget等のミラーリング機能を使って更新されたパッケージを定期的にダウンロードする、というのも、ちょっと敷居が高いでしょう。

以前から、何かいい方法はないかなぁ、とあれこれ考えてはいて、たとえば「パッケージの更新時刻」を元に、新しいパッケージを紹介するような機能を検討したこともあります。すなわち、サーバ側に全パッケージの更新時刻を記録しておいて、クライアント側から「ある時刻以降に更新されたパッケージ」を調べるようなリクエストを送れば該当するパッケージの一覧を返すような機能です。

この機能を使えば「サーバ上で更新されたパッケージ」はわかるものの、果してそのパッケージがクライアント側に必要なのかまではわかりません。Plamo Linuxの場合、KDEやMate,Xfceといったデスクトップ環境はユーザが選択可能なので、デスクトップ環境としてXfceを選んだユーザに、KDEやMate用パッケージの更新情報が届いてもあまり意味は無いでしょう。

また、繰り返し問い合わせがあった場合、以前に問い合わせた時刻から後に更新したパッケージのみを調べるにはクライアント側で問い合わせ時刻を管理する必要がありますし、以前は更新を見送ったパッケージを再度チェックしたい場合には問い合わせ時刻を巻き戻すような処理も必要で、仕組みとしてはずいぶん複雑になりそうです。

更新時刻での管理が難しいとすると、パッケージのバージョンやビルド番号で管理することになるものの、サーバ側に収めているパッケージの情報と、ユーザ側でインストールしているパッケージの情報を簡単に照合する方法をなかなか思いつきませんでした。

Plamo Linuxは小規模なディストリビューションなものの、32ビット版、64ビット版、それぞれに1300強のパッケージがあります。サーバ側に用意しておいた全パッケージのリストをダウンロードして、ユーザ側でインストール済みのパッケージのリストと照合する、という作業は、シェルスクリプトでやるにはちょっと大変だし、時間もずいぶんかかりそうです。照合作業を高速化するためにSQLite3あたりを使ってパッケージ情報をデータベース化する方法も考えたものの、毎回データベースファイルをやりとりするというのもちょっと牛刀な気がします。

そのあたりをあれこれ考えているうちに、ふと思い出したのがPythonの持っているpickleという機能です。

pickleとは、一般には「ピクルス」いわゆる「酢漬け」という意味なものの、Pythonの世界では、Pythonが扱うあらゆる形式のデータをシリアライズする機能を意味します。すなわち、あるマシンで作ったPythonのリスト型や辞書型のデータをpickleしてファイルにしておけば、そのファイルを受けとった別のマシンのPythonで元のデータを簡単に復元できる、ということです。

Plamo Linuxのパッケージは、"ベース名"-"バージョン"-"アーキテクチャ"-"ビルド番号"."拡張子"という形式になっています。たとえば、bash-4.2.53-x86_64-P1.txz というパッケージの場合、ベース名は"bash"、バージョンは"4.2.53"、アーキテクチャは"x86_64"、ビルド番号は"P1"、拡張子は"txz"です。これらのうち、ベース名(bash)システム上で一意になっているので、ベース名をキーにした辞書型のデータを使えばパッケージ情報は効率よく管理できそうです。

サーバ側で最新のパッケージ情報を辞書型に整理して、そのデータをpickleでファイルにしておけば、ユーザ側ではそのファイルをダウンロードしてPythonで復元するだけで、サーバ上の最新パッケージ情報を容易に再現できます。一方、ユーザ側でインストールしているパッケージの情報も同様の辞書型のデータにしておけば、パッケージの有無やバージョン、ビルド番号の違いなどは、辞書型データのキーの有無対応する要素の比較で簡単にチェックできるでしょう

そう考えて、最新のパッケージ情報を拾ってpickleするサーバ側のPythonスクリプトと、ローカルにインストール済みのパッケージの情報をまとめてサーバのpickleデータと比較するようなスクリプトを書いてみることにしました。


さて、だいぶ長くなってしまったのでスクリプトの詳細は次回に譲ることにしましょう。紹介予定のスクリプトの最新版は、githubで公開しているPlamo Linuxのページに登録されているので、次回まで待てない人は、こちらから直接ダウンロードして試してみてください。

このスクリプトを実行すると、ローカルにあるパッケージとサーバ上のパッケージを比較して、違いがあるパッケージを報告します。

$ python get_pkginfo.py 
local package: binutils-2.24-x86_64-P1
new   package: binutils-2.25-x86_64-P1
URL: ftp://ring.yamanashi.ac.jp/pub/linux/Plamo/Plamo-5.x/x86_64/plamo/01_minimum/devel.txz/binutils-2.25-x86_64-P1.txz

local package: curl-7.39.0-x86_64-P1
new   package: curl-7.40.0-x86_64-P1
URL: ftp://ring.yamanashi.ac.jp/pub/linux/Plamo/Plamo-5.x/x86_64/plamo/01_minimum/network.txz/curl-7.40.0-x86_64-P1.txz

local package: firefox-34.0-x86_64-P1
new   package: firefox-35.0-x86_64-P1
URL: ftp://ring.yamanashi.ac.jp/pub/linux/Plamo/Plamo-5.x/x86_64/plamo/04_xapps/firefox-35.0-x86_64-P1.txz
 ...

-dオプションを指定すると、更新されているパッケージをダウンロードしてきます。

$ python get_pkginfo.py -d
local package: binutils-2.24-x86_64-P1
new   package: binutils-2.25-x86_64-P1
URL: ftp://ring.yamanashi.ac.jp/pub/linux/Plamo/Plamo-5.x/x86_64/plamo/01_minimum/devel.txz/binutils-2.25-x86_64-P1.txz
downloading: binutils-2.25-x86_64-P1.txz
[    1922656 /    1922656 ]

local package: curl-7.39.0-x86_64-P1
new   package: curl-7.40.0-x86_64-P1
URL: ftp://ring.yamanashi.ac.jp/pub/linux/Plamo/Plamo-5.x/x86_64/plamo/01_minimum/network.txz/curl-7.40.0-x86_64-P1.txz
downloading: curl-7.40.0-x86_64-P1.txz
[     797712 /     797712 ]
...

このスクリプトは現在も開発中なものの、Plamo-5.3.1にはパッケージとして組み込む予定で、Plamo Linuxのユーザにとって便利なツールになることを期待しています。

おすすめ記事

記事・ニュース一覧