rpm プログラミング with python を読み砕く : 1

引用元ドキュメントから自分勝手に要点のみを抜粋

本章(本連載)の概要

  • python を使って RPM を使う
  • 必要なモジュールをインストールする
  • RPM データベースを使ってプログラミングする
  • RPM ファイルを使ってプログラミングする
  • プログラムからパッケージをインストールする
Python 開発環境のセットアップ

本章の内容は python-1.5 はサポートしてなく、python-2.2 以上でサポートする。GUI を使う場合、python のベースパッケージとは別にインストールする必要がある。PyGTK は GNOME デスクトップ環境で使用される GTK+ ツールキットと python をバインドします。UI が優れているので Red Hatredhat-config-packages は PyGTK を使用しています。
PyGTK
PyQt は Qt C++ UI ツールキットと python を接続します。Qt フォームは KDE デスクトップ環境で使用される標準的なライブラリです。
PyQt

Tkinter は python の一部として標準で組み込まれている。Tcl 言語の Tk ツールキットを基にしています。主な利点は python に組み込まれているため、Windows も含む多くのプラットフォームで動作します。主な決定は、PyQt や PyGTK と比較して、ウィジェットの UI がリッチではないことです。
Tkinter

Python API 階層構造
クラス 概要
rpm RPM API のベースモジュール
rpmts トランザクションセット
rpmte トランザクション要素、トランザクションセットのパッケージ
rpmmi RPM データベースへのクエリに使用されるイテレータ
Rpmds 依存関係セット
Rpmfi ファイルセット
Header パッケージヘッダ

一般的には、RPM Python API は標準 Python API の中にインテグレートされています。本章のサンプルは RPM 4.1 Python API を使用しています。4.1 と以前のバージョンでは、API が大きく異なります。

RPM データベースプログラミング

全てのスクリプトrpm.TransactionSet が必要です。また、自動的RPM データベースをオープンします。本章のサンプルプログラムは、Red Hat命名規則に従います。これは、python で書かれた Red Hat インストーラープログラムに沿うもので、RPM ソース内のサンプルを読み易くします。

  • RPM データベースへのアクセス

トランザクションセットは、データベースレベルで RPM データベースに作用する多くのメソッドを提供します。個々のパッケージにアクセスするには、これらのメソッドを使用する必要があります。例えば、RPM データベースを初期化したり、デフォルトのシステムデーターベースの代わりに別の RPM データベースへアクセスすることもできます。

詳細は省略。

  • RPM データベースへのクエリ

マッチイテレータを作成するためにトランザクションセットの dbMatch を呼び出します。パラメータなしで呼び出すとインストールされているパッケージの完全なセットを探索するマッチイテレータを作成します。基本的なサンプルを示します。

#!/bin/env python

import rpm

ts = rpm.TransactionSet()
mi = ts.dbMatch()
for h in mi:
    print "%s-%s-%s" %(h['name'], h['version'], h['release'])
  • パッケージヘッダと特定パッケージへのクエリ

python のディクショナリを用いて、各々のヘッダエントリにアクセスできます。また dbMatch へパラメータを渡すことで特定パッケージをクエリすることができます。RPM データベース内でインデックス化されたタグへのアクセスは、そうでないものよりも高速に動作します。インデックス化されたタグの定義は /var/lib/rpm 配下のファイルを参照してください。例えば、Name や Requirename はインデックス化されているので高速です。

#!/bin/env python

import rpm, sys

ts = rpm.TransactionSet()
mi = ts.dbMatch('name', sys.argv[1])

if not mi:
    print "No packages found."
else:
    for h in mi:
        print "package : %s-%s-%s.%s" \
               %(h['name'], h['version'], h['release'], h['arch'])
        print "license : %s" %(h['license'])
        print "vendor : %s" %(h['vendor'])
        print "packager : %s" %(h['packager'])
  • 高度なクエリ

マッチイテレータにおけるパターンメソッドは、1つ以上のタグやパターンによるセットのような高度なクエリを提供します。

rpm.RPMMIRE_DEFAULT 正規表現に "\.", ".*" と "..$" も追加しています
rpm.RPMMIRE_GLOB fnmatch を使用する Glob スタイルのパターン
rpm.RPMMIRE_REGEX regcomp を使用する 正規表現
rpm.RPMMIRE_STRCMP strcmp を使用する文字列比較


これらのパターンについては、fnmatch(3), glob(7), regcomp(3), regex(7), strcmp(3) のオンラインマニュアルを参照してください。サンプルを示します。

#!/bin/env python

import rpm, sys

ts = rpm.TransactionSet()
mi = ts.dbMatch()

if not mi:
    print "No packages found."
else:
    mi.pattern('name', rpm.RPMMIRE_GLOB, sys.argv[1])
    for h in mi:
        print "package : %s-%s-%s.%s" \
               %(h['name'], h['version'], h['release'], h['arch'])