ククログ

株式会社クリアコード > ククログ > debやrpmの中身を一部書き換えてパッケージを再作成する方法

debやrpmの中身を一部書き換えてパッケージを再作成する方法

開発したソフトウェアを簡単に導入してもらえるようにするための工夫として、debやrpmといったパッケージを用意し、パッケージを含むリポジトリから インストールできるようにするということがよく行われています。

debやrpmといったパッケージを提供する側にとっては、提供したパッケージを問題なく更新できるように、(パッケージの一部だけ変更したものを用意するなどして)パッケージ更新時の挙動を検証したくなることがあります。

今回はそんなときのために、debおよびrpmの内容を一部書き換えてパッケージを再作成する方法について紹介します。

debの内容を書き換えてパッケージを作成する方法

例として、helloパッケージを変更してみることにします。 apt download helloを実行して得られた、hello_2.10-3_amd64.debの次のバージョンである2.10-4を作成してみます。

これを実現するためには次の手順が必要です。

  • debパッケージを展開する
  • 展開したdebパッケージのバージョンに関する情報を書き換える
  • 展開したdebパッケージを再度debパッケージとして再構成しなおす

最初のdebパッケージを展開するためには、次のコマンドを実行します。

dpkg-deb -R (対象の.deb) (展開先のディレクトリ)

したがってhello_2.10-3_amd64.debをtmpディレクトリに展開するならば次のコマンドを実行します。

dpkg-deb -R hello_2.10-3_amd64.deb tmp

debパッケージをこのようにして展開すると、次のような階層のディレクトリが作成されます。

$ tree
tmp
├── DEBIAN
│   ├── control
│   └── md5sums
└── usr
    ├── bin
    │   └── hello
    └── share
        ├── doc
        │   └── hello
        │       ├── NEWS.gz
        │       ├── changelog.Debian.gz
        │       ├── changelog.gz
        │       └── copyright
        ├── info
...(省略)

DEBIANディレクトリにはdebパッケージのメタ情報やメンテナースクリプトといったものが含まれます。 その他にはパッケージをインストールしたときの階層そのままにファイルが配置されます。

次に、パッケージのバージョンに関する情報を書き換えてみましょう。

sed -i -e 's/^Version: 2.10-3/Version: 2.10-4/' tmp/DEBIAN/control

controlファイルにバージョン情報が書かれているのでその値を変更します。

あとは、再びdebパッケージとして再構成すればよいです。 展開済みのディレクトリから再度パッケージを構築するには次のようなコマンドを実行します。

dpkg-deb --build (展開済みディレクトリ) (パッケージ名)

バージョン2.10-4のパッケージを再構築するには次のコマンドを実行します。

dpkg-deb --build tmp hello_2.10-4_amd64.deb

作成したdebの情報を確認してみましょう。dpkg-deb -Iで内容を確認できます。

$ dpkg-deb -I ./hello_2.10-4_amd64.deb
 new Debian package, version 2.0.
 size 53064 bytes: control archive=1872 bytes.
     757 bytes,    20 lines      control
    3601 bytes,    49 lines      md5sums
 Package: hello
 Version: 2.10-4
 Architecture: amd64
 Maintainer: Santiago Vila <sanvila@debian.org>
 Installed-Size: 277
 Depends: libc6 (>= 2.34)
 Conflicts: hello-traditional
 Breaks: hello-debhelper (<< 2.9)
 Replaces: hello-debhelper (<< 2.9), hello-traditional
 Section: devel
 Priority: optional
 Homepage: https://www.gnu.org/software/hello/
 Description: example package based on GNU hello
  The GNU hello program produces a familiar, friendly greeting.  It
  allows non-programmers to use a classic computer science tool which
  would otherwise be unavailable to them.
  .
  Seriously, though: this is an example of how to do a Debian package.
  It is the Debian version of the GNU Project's `hello world' program
  (which is itself an example for the GNU Project).

期待通りにバージョンを変更した2.10-4のdebパッケージが再作成できていることがわかります。

rpmの内容を書き換えてパッケージを作成する方法

例として、How to create a GNU Hello RPM package/jaを参考に作成できる、hello-2.8-1.el8.x86_64.rpmパッケージを変更してみることにします。(以下AlmaLinux 8で実行するものとします。適宜環境によって読み替えてください。)

rpmの場合、バージョン(リリース)を変更したパッケージを作成するには、rpmrebuildコマンドを使うと簡単です。

もしrpmrebuildがインストールされていない環境であれば次のコマンドを実行してインストールします。

$ dnf install -y epel-release
$ dnf install -y rpmrebuild

rpmrebuildは次のようにして使います。

rpmrebuild --release=(リリースバージョン) --package (rpmパッケージ)

例えば、hello-2.8-1.el8.x86_64.rpmからhello-2.8-2.el8.x86_64.rpmというパッケージを作成するには次のコマンドを実行します。

rpmrebuild --release=2.el8 --package hello-2.8-1.el8.x86_64.rpm

作成したパッケージの情報を確認してみましょう。rpm -qiで確認できます。

$ rpm -qi ./hello-2.8-2.el8.x86_64.rpm 
Name        : hello
Version     : 2.8
Release     : 2.el8
Architecture: x86_64
Install Date: (not installed)
Group       : Unspecified
Size        : 110826
License     : GPLv3+
Signature   : (none)
Source RPM  : hello-2.8-2.el8.src.rpm
Build Date  : Mon Oct  7 02:22:13 2024
Build Host  : 6102fed6fc36
Relocations : (not relocatable)
URL         : http://ftp.gnu.org/gnu/hello
Summary     : The "Hello World" program from GNU
Description :
The "Hello World" program, done with all bells and whistles of a proper FOSS
project, including configuration, build, internationalization, help files, etc.

期待通りに、次のリリースバージョン2.8-2.el8であるrpmパッケージを再作成できていることがわかります。

では、debのときと同じようにrpmの内容を変更するのはどうするとよいのでしょうか。 その場合には、rpmrebuild --modifyを実行します。

rpmrebuild --modify=(変更するためのコマンド) --package (rpmパッケージ)

例えば、hello-2.8-1.el8.x86_64.rpmのNEWSの内容の一部を次のように書き換えてみます。

  • 変更前 * Noteworthy changes in release 2.8 (2012-04-19) [stable]
  • 変更後 Version 2.8 (2012-04-19)

このように変更するには次のコマンドを実行します。1

rpmrebuild --release=2.el8 --modify="find $HOME -name NEWS | \
  xargs sed -i -e 's/^\* Noteworthy changes in release (.+) \((.+)\).+/Version \1 \(\2\)/'" --package hello-2.8-1.el8.x86_64.rpm

rpm2cpioを使って、パッケージの内容を取り出してみましょう。

$ rpm2cpio ~/rpmbuild/RPMS/x86_64/hello-2.8-2.el8.x86_64.rpm | cpio -id ./usr/share/doc/hello/NEWS
$ head usr/share/doc/hello/NEWS 
Version ?.? (????-??-??)

Version 2.8 (2012-04-19)

The build system has been overhauled to be more in line with
mainstream modern GNU practice, and various translations have been
updated (thanks to the Translation Project!).

Version 2.7 (28 March 2011)
* Distribution:

期待通りに該当行がVersion 2.8 (2012-04-19)へと置き換えられていることがわかります。2

まとめ

今回はdebおよびrpmの内容を一部書き換えてパッケージを再作成する方法について紹介しました。

今回紹介したやりかたは、パッケージのCIなどを実施したいときに、パッケージを最初からビルドしなおさなくてすむので有用です。 機会があったら試してみてください。3

  1. rpmパッケージは$HOME/.tmp/rpmrebiuld.XXX配下に展開されます。

  2. rpmrebuildで再構成するrpmパッケージによっては、再構成後に一部のファイルが意図せず追加されたり、あるいは欠損することがあります。場合によっては.moファイルが欠損するケースがあるようです。欠損するファイルがあるかどうかは、rpmrebuild -eで対話的に実行したとき、# MISSING:と表示される行があるかで判断できます。

  3. fluent-package(deb)のCIfluent-package(rpm)のCIで実際に使っています。