CnetOS 7 (on Raspberry Pi)でのrpmパッケージビルド環境の構築


# 前置き
Raspberry Pi上で動かすOSはRaspbianがやはり一番人気ですが、RedHat系も実は存在します。昔はPidora（Raspberry Pi用のFedora）が[公式HP](https://www.raspberrypi.org/)からもDownloadできるようになっていたのですが、なかなか更新されないせいか、人気がないせいか、いつの間にか消えていました。しかし、CentOSがリリースされたことで、これからは使う人が増えていくのではないかな、と期待しています。

しかし、このCentOSですが、EPELなどのサードパーティのパッケージは用意されていないですし、develパッケージはないものもありますし、Raspbian用にはdebianパッケージが用意されていてもCentOS(for armv7hl)用には当然rpmパッケージは用意されていないですし、自分でrpmパッケージをビルドする必要が出てきます（パッケージ管理しないのであれば不要ですが…）。そこで、Raspberry Pi上のCentOS7上で、自分用のパッケージビルドするための環境構築方法について記載します。

ということで、CentOS (on Raspberry Pi) でインストール直後に行う初期設定と、パッケージビルドするための環境構築について、少しだけ説明します。

# OSインストールおよび初期設定
## OSインストール
OSのインストール方法は他のOS（Raspbianなど）と変わらないので、他のページを参照してください。
OSイメージは[ここ](https://wiki.centos.org/Download)の"AltArch Releases"=>"RaspberryPi2 (img)"から入手します。

OSインストール後、以下でログインできます。
ユーザ名：__root__
パスワード：__centos__

## 初期設定
通常のRHEL系のサーバと同様、パスワードの変更、ネットワークの設定、`yum update`、firewalldやsshdの設定などのセキュリティ上やっておくべき設定、不要なサービスの停止などなどをします。また、Overclockの設定などもする人はするとよいと思います。ここでは、少しだけ説明します。

### キーボードの設定
以下のように`localectl set-keymap`でjp106に変更します。

```shell-session
# localectl list-keymaps
# localectl set-keymap jp106 
# localectl
```

### タイムゾーンの設定
以下のようにして変更できます。

```shell-session
# timedatectl list-timezones
# timedatectl set-timezone Asia/Tokyo
# timedatectl
```

### networkの設定
NetworkManagerを使用せずに、networkサービスを使用する場合、`/etc/sysconfig/network-scripts/ifcfg-eth0`を編集することになると思いますが、以下の記載があることを確認してください。ない場合は、追加してください。

```bash:/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
```

また、以下の`/etc/sysconfig/network`がない場合は追加してください。

```bash
NETWORKING=yes
```

### パーティション拡張
CentOSをインストールCDを使ってインストールする場合には不要な設定として、パーティション拡張があります。Raspbianの場合は、`raspi-config`でSDカードの未使用領域に対して容量拡張できるのですが、CentOS (on Raspbeey Pi)の場合`raspi-config`はありません。代わりに、`/root/`に存在する`README`に書いてある通りの方法でrootパーティションを拡張することができます。

```shell-session
# touch /.rootfs-repartition
# systemctl reboot
```

### NTPの設定
Raspbianでも同じですが、電源切ると1970年1月1日(UTC)にタイムリープします。そのため、NTPの設定は必要不可欠です。最近はntpdだけでなく、chronyというのもあるようです。[ここ](https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-Configuring_NTP_Using_the_chrony_Suite.html)によると、以下の基準で選択するようです。

> ・Chrony は、頻繁にネットワーク接続が一時停止したり、断続的に切断され再接続されるようなシステムの場合に検討してください。たとえば、モバイルや仮想システムなどです。
> ・NTP デーモン (ntpd) は、通常、常時接続のシステムの場合に検討してください。ブロードキャストまたはマルチキャスト IP を使用する必要のあるシステム、または Autokey プロトコル でパケット認証を実行する必要のあるシステムの場合は、ntpd の使用を検討してください。Chrony は、MD5、SHA1、またはより強力なハッシュ機能のあるメッセージ認証コード (MAC) を使用した対称鍵認証のみをサポートしますが、ntpd は PKI システムの活用も可能な Autokey 認証プロトコルもサポートします。Autokey は RFC 5906 で説明されています。 

Raspberry Pi上ではChronyを選択すべきでしょう。まず、chronyをインストールします。

```shell-session
# yum install chrony ntpdate
```

最低限、接続先のNTPサーバを変更します。

```diff:/etc/chrony.conf
  # Use public servers from the pool.ntp.org project.
  # Please consider joining the pool (http://www.pool.ntp.org/join.html).
- server 0.centos.pool.ntp.org iburst
- server 1.centos.pool.ntp.org iburst
- server 2.centos.pool.ntp.org iburst
- server 3.centos.pool.ntp.org iburst
+ server <NTPサーバ> iburst
```

また、NTPサーバとしても使用する場合、接続を許可するマシンのIPアドレス（またはサブネットアドレス）を設定するとよいでしょう。

```diff:/etc/chrony.conf
...
  # Allo NTP clienct access from local network.
  #allow 192.168/16
+ allow <ネットワークアドレスorIPアドレス>/<サブネット>
...
```

chronydを起動します。また今すぐ時刻合わせしたい場合は、`ntpdate`を実行します。chronydの場合、ntpdとは違い、`-u`オプションなしでも`ntpdate`を実行できます。

```shell-session
# systemctl start chronyd
# systemctl enable chronyd
# ntpdate <NTPサーバ>
```

# パッケージビルド環境の構築
タイトルではRaspberry Piに限定していますが、何も特別なことはありません。
まずは、パッケージビルドするためのパッケージをインストールします。

```shell-session
# yum install rpm-build rpmdevtools
# yum install yum-utils
# yum install make gcc gcc-c++
```

またビルド用のユーザを作成します。一応`sudo`できるように`wheel`に登録しておきます。

```shell-session
# useradd <ユーザ名>
# passwd <ユーザ名>
# usermod -G wheel <ユーザ名>
```

ビルドユーザになって、以下のようにすることで、`rpmbuild`するときの設定ファイル`~/.rpmmacros`とビルドするためのディレクトリ`~/rpmbuild`配下が作成できます。（以降の操作で、行頭を`$`としている箇所は先ほど作ったユーザにして実行、行頭`#`としている箇所は`root`ユーザで実行してください。）

```shell-session
# su <ユーザ名>
$ cd ~
$ rpmdev-setuptree
```

ただし、デフォルトのままだとdebugパッケージまで作成してしまうので、`~.rpmmacros`を修正してdebugパッケージを作成しないようにします。

```shell-session
$ echo "%debug_package %{nil}" >> ~/.rpmmacros
```

また、作成したrpmパッケージのディストリビューション情報は、デフォルトだと".el7.centos"になっています。そのため作成したrpmパッケージ名やRelease情報に".centos"が入ってしまいます。他のOSパッケージと合わせるため、ディストリビューション情報を".el7"にします。

```shell-session
$ echo "%dist .el7" >> ~/.rpmmacros
```

specファイル中の`%files`に書いてあるものがrpmパッケージに入れるものなのですが、これらのファイルはパッケージを固めるときに`BUILDROOT`の中に含まれている必要があります。デフォルトだと、`%files`に書いてないものが`BUILDROOT`に含まれているとエラーになってビルドに失敗します。これでは、ソースパッケージを`rpmbuild --rebuild`したときにビルドできない場合があるので、以下のように設定しておきます。

```shell-session
$ echo "%_unpackaged_files_terminate_build 0" >> ~/.rpmmacros
```


さらに、作成したパッケージがarmv7hnl-32用にならないように以下の設定を行います（2016年4月9日追加）。

```shell-session
$ echo "%__isa_name armv7hl" >> ~/.rpmmacros
```

以上でパッケージビルドするための環境は完了です。
`mockbuild`ユーザで、`rpmbuild --rebuild`としたり、`rpmbuild -ba`とすることで、rpmパッケージを作成することができます。

# x86_64レポジトリの追加
(2016年4月10日追加)
OS提供のnoarchのパッケージで、x86_64のレポジトリにはあるのに、armv7hlのレポジトリにはないという場合があります。そのため、以下のファイルを作成することで、x86_64のレポジトリからnoarchのパッケージをインストールすることができるようになります。

```shell-session:/etc/yum.repos.d/CentOS-x86_64.repo
[base-x86_64]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=x86_64&repo=os&infra=$infra
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[updates-x86_64]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=x86_64&repo=updates&infra=$infra
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[extras-x86_64]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=x86_64&repo=extras&infra=$infra
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[centosplus-x86_64]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=x86_64&repo=centosplus&infra=$infra
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
```

ただし、上記設定をすると`yum update`などに失敗する場合があります。その場合はenabled=0にしてx86_64用のレポジトリを無効にしてから`yum update`するなどしてください。

# サードパーティレポジトリの追加
サードパーティのレポジトリを追加します。ただし、armv7hl用のパッケージはないので、少々修正が必要です。

## EPEL
epel-releaseをインストールします。

```shell-session
# rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
```

現在のところarmhfp用のパッケージがないため、このままだとエラーになります。応急処置ですが、`$basearch`を`x86_64`に固定してしまえば、エラーはなくなり、noarchのパッケージがインストールできるようになります。（※あくまで応急処置です。パッケージが出たら元に戻してください。戻す時は、`yum clean all`を忘れずに。）

```shell-session
# mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.org
# sed -e 's/$basearch/x86_64/g' /etc/yum.repos.d/epel.repo.org > /etc/yum.repos.d/epel.repo
```

## Nux Dextop
こちらもEPELと同様に行います。まずはnux-dextop-releaseをインストールします。

```shell-session
# rpm -ivh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
```

こちらもこのままではエラーになるので、応急処置として`$basearch`を`x86_64`に変更し、noarchのパッケージだけでもインストールできるようにします。

```shell-session
# mv /etc/yum.repos.d/nux-dextop.repo /etc/yum.repos.d/nux-dextop.repo.org
# sed -e 's/$basearch/x86_64/g' /etc/yum.repos.d/nux-dextop.repo.org > /etc/yum.repos.d/nux-dextop.repo
```

上記を行った後、`yum update`してビルド環境は構築完了です。