rpm プログラミング with python を読み砕く : 1
引用元ドキュメントから自分勝手に要点のみを抜粋
本章(本連載)の概要
- python を使って RPM を使う
- 必要なモジュールをインストールする
- RPM データベースを使ってプログラミングする
- RPM ファイルを使ってプログラミングする
- プログラムからパッケージをインストールする
Python 開発環境のセットアップ
本章の内容は python-1.5 はサポートしてなく、python-2.2 以上でサポートする。GUI を使う場合、python のベースパッケージとは別にインストールする必要がある。PyGTK は GNOME デスクトップ環境で使用される GTK+ ツールキットと python をバインドします。UI が優れているので Red Hat の redhat-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'])