rpm プログラミング with python を読み砕く : 2
引用元ドキュメントから自分勝手に要点のみを抜粋
パッケージファイルを読み込む
Python API は、インストールされた RPM パッケージの処理に加えて、RPM パッケージファイルを処理するメソッドを含みます。これらの大半のメソッドはヘッダオブジェクトを要求します。
- パッケージファイルからヘッダを読み込む
Python API は RPM パッケージのヘッダオブジェクトを読み込む便利な方法を提供します。hdrFromFdno() メソッドは、ファイルディスクリプタから RPM ヘッダを読み込みます。
- 注意
hdrFromFdno() メソッドは、ハイレベルな Python ファイルオブジェクトではなく、ローレベルな Python のファイルディスクリプタを使用します。以下に、ファイルをオープンして、RPM ヘッダを読み込み、ファイルをクローズする例を示します。また、パッケージファイル内で問題を検出したら例外を発生させます。
#!/bin/env python # -*- coding: utf-8 -*- import rpm, sys, os def readRpmHeader(ts, filename): h = None fd = os.open(filename, os.O_RDONLY) try: h = ts.hdrFromFdno(fd) except rpm.error, e: if str(e) == "パブリックキーが無効です": print str(e) if str(e) == "パブリックキーが信用できません": print str(e) if str(e) == "パッケージヘッダの読み込みに失敗しました": print str(e) h = None os.close(fd) return h def main(): ts = rpm.TransactionSet() h = readRpmHeader(ts, sys.argv[1]) if h != None: for i in xrange(1000,1006): print i, h[i] if __name__ == '__main__': main()
実行結果。
# ./readrpmheader.py python-2.5.1-2m.mo4.i686.rpm 1000 python 1001 2.5.1 1002 2m.mo4 1003 None 1004 An interpreted, interactive, object-oriented programming language. 1005 Python is an interpreted, interactive, object-oriented programming language often compared to Tcl, Perl, Scheme or Java. Python includes modules, classes, exceptions, very high level dynamic data types and dynamic typing. Python supports interfaces to many system calls and libraries, as well as to various windowing systems (X11, Motif, Tk, Mac and MFC). Programmers can write new built-in modules for Python in C or C++. Python can be used as an extension language for applications that need a programmable interface. This package contains most of the standard Python modules, as well as modules for interfacing to the Tix widget set for Tk and RPM. Note that documentation for Python is provided in the python-docs package.
- 検証フラグをセットする
RPM4.1 では、自動的にパッケージファイルを検証します。それが古いバージョンであったり、適切な署名がされていなかったりすると、不具合を引き起こすこともあります。ほとんどのケースでは、パッケージファイルの信頼性を確保できるので自動検証にはメリットがあります。しかしながら、デフォルトの動作を変更するためにトランザクション上で setVSFlags を呼ぶ出すことも可能です。
例えば、適切な署名を持っていない古いパッケージならば、以下のようにしてチェックを無視することができます。
# DSA署名を検証しないようにセットする ts.setVSFlags(rpm.RPMVSF_NODSA)
以下のリストは、トランザクションセットへ渡せるフラグです。これらのフラグはビットマスクです。1つないし複数のフラグを同時にセットできますが、バイナリで操作しなければなりません。Pythonやキーワードを使わずに、バイナリ操作に "|" を使ってください。
フラグ | 概要 |
---|---|
rpm.RPMVSF_NEEDPAYLOAD | ペイロードの最初のファイルハンドラ位置を委任する |
rpm.RPMVSF_NOHDRCHK | RPMデータベースヘッダをチェックしない |
rpm.RPMVSF_NODSA | ヘッダとペイロードのDSA署名をチェックしない |
rpm.RPMVSF_NODSAHEADER | ヘッダのDSA署名をチェックしない |
rpm.RPMVSF_NOMD5 | ヘッダとペイロードのMD5ダイジェストをチェックしない |
rpm.RPMVSF_NORSA | ヘッダとペイロードのRSA署名をチェックしない |
rpm.RPMVSF_NOSHA1HEADER | ヘッダのSHA1署名をチェックしない |
rpm._RPMVSF_NODIGESTS | ダイジェストをチェックしない |
rpm._RPMVSF_NOSIGNATURES | 署名をチェックしない |
全てのチェックを無効にするには setVSFlags に -1 を渡します。
ts.setVSFlags(-1)
依存関係の比較
2つのパッケージ間の依存関係を比較する依存関係セットがあります。一般的な使い方として、インストールされているパッケージのバージョンよりも新しいバージョンのパッケージファイルであるか、パッケージファイルを比較します。
ヘッダのデフォルト依存関係セットを取得するために、ヘッダオブジェクトのdsOfHeaderを呼び出すことができます。2つのヘッダからの依存関係セットを用意して、以下のようにしてどちらが新しいかを確認できます。
#!/bin/env python # -*- coding: utf-8 -*- import rpm, os, sys def readRpmHeader(ts, filename): fd = os.open(filename, os.O_RDONLY) h = ts.hdrFromFdno(fd) os.close(fd) return h def main(): ts = rpm.TransactionSet() h = readRpmHeader(ts, sys.argv[1]) pkg_ds = h.dsOfHeader() inst_h = '' for inst_h in ts.dbMatch('name', h['name']): inst_ds = inst_h.dsOfHeader() if pkg_ds.EVR() >= inst_ds.EVR(): print "パッケージファイルは同じ又は新しいのでアップグレード可能です" else: print "パッケージファイルはインストールされたものより古いです" if not inst_h: print "パッケージファイルはインストールされていないのでインストール可能です" if __name__ == '__main__': main()
実行結果。
# rpm -q python wxPython python-2.5.1-2m.mo4 パッケージ wxPython はインストールされていません。 # ./vercompare.py python-2.5.1-2m.mo4.i686.rpm パッケージファイルは同じ又は新しいのでアップグレード可能です # ./vercompare.py python-2.4.2-11m.i686.rpm パッケージファイルはインストールされたものより古いです # ./vercompare.py wxPython-2.6.3.3-2m.mo4.i686.rpm パッケージファイルはインストールされていないのでインストール可能です
- クロスリファレンス
このスクリプトはコマンドラインからファイル名を取得して、パッケージのヘッダをロードし、RPM データベース内にインストールされている全てのパッケージ内から同じ名前を探します。各々のマッチした名前に対して、このスクリプトはどちらが新しいかを比較します。