SRPM も Yum で最新に保ちたい

Yum はいいね。最初に Debian から Fedora にしてみたときには apt-get がなくてキレそうだったけど、今ではすっかり Yum の虜。
サーバは CentOS にして*1、パッケージの少なさにまたもやキレそうだっけど、EPEL のおかげでそれも解決。そのついでに覚えた yum-priorities プラグインがこれまた最高。自分ビルドのパッケージを exclude やら lock やらで死守していたあの頃の手間はいったい何だったのか……。
ただ、まだ1つ、問題が残っている。YumSRPM を管理してくれない。SRPM に管理も何もないと思われるかもしれないが、こういう事態になって困るのだ:

  1. 出来合いのパッケージにやや不満 (最新バージョンが使いたい、ビルドオプション変えたい、パッチ当てたい、などなど)。
  2. Fedora とかから SRPM をもらってくる。
  3. rpmbuild とかして悦*2
  4. そんなことはすっかり忘れてしまった頃、Fedora の方でセキュリティフィックスが出る……。

そう。SRPM に手を出した途端、最新版が出てないか四六時中気にするあの不毛な生活に逆戻りだ。
というわけで、手持ちの SRPM が最新かどうかをチェックするスクリプトを作ってみました((yumdownloader --sourceSRPM が落とせるようになっているのと rpmdev-vercmp コマンドがある(EPEL の rpmdevtools パッケージにあります) のが前提になります。))。/var/local/srpm にある *.src.rpm よりも新しい SRPM が出てないかを報告してくるので、cron とかで回します*3:

#! /bin/sh

set -e

export LC_ALL=C
export LANG=C

cd /var/local/srpm

SrpmFileNamePattern='^\(.\+\)-\([^-]\+\)-\([^-]\+\)\.src\.rpm$'

function listSrpmUri()
{
        local Packages="$( ls *.src.rpm |sed -e "s/${SrpmFileNamePattern}/\1/" |sort |uniq )"
        yumdownloader --source --urls $Packages |grep -E '\.src\.rpm$'
}

function getSrpmFileNamePart()
{
        local SrpmFile="$1"
        local Part="$2"
        echo "$SrpmFile" |sed -e "s/${SrpmFileNamePattern}/\\${Part}/"
}

function isNewerThan()
{
        local SrpmFile1="$1"
        local SrpmFile2="$2"
        local Version1="$( getSrpmFileNamePart "$SrpmFile1" 2 )"
        local Version2="$( getSrpmFileNamePart "$SrpmFile2" 2 )"
        local Release1="$( getSrpmFileNamePart "$SrpmFile1" 3 )"
        local Release2="$( getSrpmFileNamePart "$SrpmFile2" 3 )"

        rpmdev-vercmp '' "$Version1" "$Release1" '' "$Version2" "$Release2" \
                |grep -F "${Version1}-${Release1}" |grep -Fi 'newer' >/dev/null
}

function getSrpmId()
{
        SrpmPackageFileName="$1"
        echo $( getSrpmFileNamePart "$SrpmPackageFileName" 2 ) -  \
                $( getSrpmFileNamePart "$SrpmPackageFileName" 3 ) \
                |sed -e 's/ //g'
}

function checkUpdate()
{
        local SrpmUri="$1"
        local RemoteFile="$( echo "$SrpmUri" |sed -e 's|^.*/\([^/]\+\)$|\1|' )"
        local PackageName="$( getSrpmFileNamePart "$RemoteFile" 1 )"

        CurrentSrpms=''
        for LocalFile in *.src.rpm
        do
                if [ "$( getSrpmFileNamePart "$LocalFile" 1 )" != "$PackageName" ]
                then
                        continue
                fi

                if ! isNewerThan "$RemoteFile" "$LocalFile"
                then
                        return 0
                fi

                CurrentSrpms="${CurrentSrpms} $( getSrpmId "$LocalFile" )"
        done

        echo "${PackageName}:${CurrentSrpms} --> $( getSrpmId "$RemoteFile" )"
}

function main()
{
        for SrpmUri in $( listSrpmUri )
        do
                checkUpdate "$SrpmUri"
        done
}

main
exit 0

*1:2〜3年のスパンで見たときの管理の手間が、Fedora のときとは全然違うよ。当たり前だけど。

*2:もちろん、できた RPMrpm -ivh とかしたりはしない。サイトローカルのリポジトリに置いて yum だ。

*3:そういえば、yum-cron の方が yum-updates よりも全然いいね、サーバでは。どのパッケージが更新されたのかちゃんと報告してくれるし、「Hi」「Thank You, Your Computer」なんて馴れ馴れしいことも言わない。