オレオレyumリポジトリでRPMパッケージを管理する

この投稿は [グレンジ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/grenge) の 4日目の記事です。

こんにちは、[株式会社グレンジ](https://www.grenge.co.jp/)でサーバーサイドエンジニアをしています。
新卒の島田（[@konnyaku256](https://twitter.com/konnyaku256)）です。

みなさん、CentOSをご存知でしょうか？
最近はあまり聞かなくなってきた気がしますが、ソフトウェア開発の現場ではまだまだ現役だったりすることもあるかと思います。
そんな、CentOSですが、古さゆえの問題は多いです。
なかでも特に厄介なのは「 **yumリポジトリ存在しない問題** 」です。
CentOSやRet Hat Enterprise LinuxをはじめとするRed Hat系のLinuxディストリビューションでは、いろいろなソフトウェアがRPMパッケージとして提供されており、これらはyumコマンドやrpmコマンドを利用して簡単にインストールできます。
しかし、一般に公開されているyumリポジトリでは、ソフトウェアのバージョンが都度更新されたり、リポジトリごと消滅したりするため、あるときインストールしたソフトウェアのバージョンが、次のときにはなくなっていてインストールできない場合があります。
この問題は、ソフトウェアのバージョンを固定して厳密に管理したい場合、かなり致命的です。

今回は、そんな問題を解決するための一例として、現在インストールされているRPMパッケージから独自のyumリポジトリを作成してWebサーバーに配置し、
任意のRPMパッケージをいつでもインストールできるようにする方法を紹介したいと思います。

# 検証環境
CentOS 6.9

# yumリポジトリの作り方
## 事前準備
次のコマンドを実行して、必要なツールをインストールします。

```sh
# yum関連のツールをインストール（今回は、yum-utilsの中のyumdownloaderを使用します）
$ yum install yum-utils

# yumリポジトリを作成するためのコマンドをインストール
$ yum install createrepo
```

# rpmファイルをダウンロードする
まず、現在の環境にインストールされているRPMパッケージ名の一覧を取得します。

```sh
$ rpm -qa --queryformat "%{NAME}\n"
```

次のような一覧が表示されます。

```sh
php
php-fpm
...
```

ここで、取得したRPMパッケージ名の一覧をテキストファイルとして保存しておきます。
例えば、download.list に次のように一覧を保存します。
ファイルを開いて、

```sh
$ vi ~/download.list
```
rpmパッケージ名の一覧を記述します。

```download.list
php
php-fpm
```

次に、yumdownloaderを使って、インストール済みのrpmファイルを任意のディレクトリに展開します。
さきほど保存したテキストファイルのパッケージ一覧を使用します。

```sh
$ cat ~/download.list | xargs -L 1 yumdownloader --resolve --destdir ~/myrepo/
```

次のコマンドでrpmファイルが展開されていることを確認します。

```sh
$ ls ~/myrepo/

php-5.3.3-49.el6.x86_64.rpm
php-fpm-5.3.3-49.el6.x86_64.rpm
```

# yumリポジトリを作る
createrepoを使って、さきほどrpmファイルを格納したディレクトリにyumリポジトリを作成します。

```sh
$ createrepo ~/myrepo/
```

~/myrepo/repodata/に次のようなxmlファイルが生成されていることを確認します。

```sh
$ cat ~/myrepo/repodata/repomd.xml
```

```repomd.xml
<?xml version="1.0" encoding="UTF-8"?>
<repomd xmlns="http://linux.duke.edu/metadata/repo" xmlns:rpm="http://linux.duke.edu/metadata/rpm">
 <revision>1638530430</revision>
<data type="filelists">
  <checksum type="sha256">61e2f5075d84c1c8b4629ed2cedeb985de159ca687667dcc607d628c9bfc2050</checksum>
  <open-checksum type="sha256">2d4753f39ec5227662136f6ef4df566bac48f93eaff6eb52bdb426fba9c4d283</open-checksum>
  <location href="repodata/61e2f5075d84c1c8b4629ed2cedeb985de159ca687667dcc607d628c9bfc2050-filelists.xml.gz"/>
  <timestamp>1638530430</timestamp>
  <size>513</size>
  <open-size>1297</open-size>
</data>
<data type="primary">
  <checksum type="sha256">8903aa6f4da26daf690ea02885f041a28f6b6f6a3c5cd570cc423c2c66eb3232</checksum>
  <open-checksum type="sha256">af208b0143542e51e69543f73f83b76df6375312b2a961477b9487eefc0dd18a</open-checksum>
  <location href="repodata/8903aa6f4da26daf690ea02885f041a28f6b6f6a3c5cd570cc423c2c66eb3232-primary.xml.gz"/>
  <timestamp>1638530430</timestamp>
  <size>1632</size>
  <open-size>7539</open-size>
</data>
<data type="primary_db">
  <checksum type="sha256">67ea92d712185ef2a86a34be2b337095893ccc50b1f5628e10601bd2de38dd90</checksum>
  <open-checksum type="sha256">83465e1f0ddaad871e8ecb8b7ed0f8d5771e03a9acb8a2fcf248a7b1036e970d</open-checksum>
  <location href="repodata/67ea92d712185ef2a86a34be2b337095893ccc50b1f5628e10601bd2de38dd90-primary.sqlite.bz2"/>
  <timestamp>1638530430.57</timestamp>
  <database_version>10</database_version>
  <size>4789</size>
  <open-size>28672</open-size>
</data>
<data type="other_db">
  <checksum type="sha256">26c6271942e90758a2e5746703f5e77cdda9d8dec2c8d672c9ea968c1cab1bc7</checksum>
  <open-checksum type="sha256">e7c4b055391689b0103a170ccd71096fc1a53f75b94c73927e1ecaa4e612de00</open-checksum>
  <location href="repodata/26c6271942e90758a2e5746703f5e77cdda9d8dec2c8d672c9ea968c1cab1bc7-other.sqlite.bz2"/>
  <timestamp>1638530430.26</timestamp>
  <database_version>10</database_version>
  <size>2595</size>
  <open-size>12288</open-size>
</data>
<data type="other">
  <checksum type="sha256">5814b40c8f419968a7f617d7d7d1f06e0fb323273b6233b78b3806e946b07821</checksum>
  <open-checksum type="sha256">b2844ac0af931a21d33854dc76bab10c423d2d522faed68de01ee0f3763dbdbd</open-checksum>
  <location href="repodata/5814b40c8f419968a7f617d7d7d1f06e0fb323273b6233b78b3806e946b07821-other.xml.gz"/>
  <timestamp>1638530430</timestamp>
  <size>1431</size>
  <open-size>6465</open-size>
</data>
<data type="filelists_db">
  <checksum type="sha256">f9c68417b4c796cfda63f4ba705b33a847ee7ea9d53368872eda50c67cdbde78</checksum>
  <open-checksum type="sha256">fed43887b1e57bf9e93aadf3640b0e9393cc7299b79a6593fd4a363a64a89fd9</open-checksum>
  <location href="repodata/f9c68417b4c796cfda63f4ba705b33a847ee7ea9d53368872eda50c67cdbde78-filelists.sqlite.bz2"/>
  <timestamp>1638530430.36</timestamp>
  <database_version>10</database_version>
  <size>1387</size>
  <open-size>7168</open-size>
```

# yumリポジトリを公開する
さきほど作成したyumリポジトリをWebサーバーに配置して、公開します。

Nginxの場合、/etc/nginx/nginx.confのroot（公開ディレクトリ）配下の任意のパスに配置するイメージです。
具体的な手順は環境によって異なると思うので割愛します。

# yumリポジトリの登録
RPMパッケージをインストールしたい環境で、/etc/yum.repos.d/にrepoファイルを作成します。
baseurlは前の手順で作成したサーバー上のyumリポジトリがあるパスに適宜読み替えてください。

```
$ vi /etc/yum.repos.d/myrepo.repo
```

```myrepo.repo
[myrepo]
name=myrepo
baseurl=http://example.jp/yum/myrepo/
enabled=0
gpgcheck=0

```

# yum install
登録したリポジトリを指定して、RPMパッケージをインストールします。

```sh
$ yum install -y --enablerepo=myrepo php-5.3.3-49.el6
```

# まとめ
いかがだったでしょうか。
今回のようにしておけば、Webサーバーが消えない限り「 **yumリポジトリ存在しない問題** 」は回避することができます。
また、ソフトウェアのバージョンを固定して厳密に管理することも可能です。
`yum install`するRPMパッケージの管理で困っている方の参考になれば幸いです。

明日は、[messhi](https://qiita.com/messhi)さんの記事が投稿される予定です。 お楽しみに！

# 参考
https://nandakagoodvibes.hatenablog.com/entry/2020/11/30/233046
https://knowledge.sakura.ad.jp/1086/