IAM Role対応s3cmdのRPMを作成する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本日の課題

こんにちは植木和樹です。本日もS3ネタです。本日は2部構成となっております。

Amazon Linuxで提供されていないパッケージのRPMを作る

chefで環境構築の自動化をしていく時にやっかいなのが、Amazon LinuxのリポジトリにRPMがないパッケージの扱いです。別途epelやrpmforgeリポジトリを追加してインストールできれば良いのですが、どこからもRPMが提供されていない場合はソースファイルを入手して自分でmake & make installするレシピをexecuteリソースでゴリゴリ書いていく必要があります。

自前ビルドでがんばるのは良いのですが、ビルドするためにはmakeやgccや *-devel パッケージをインストールしなければいけなかったり、なによりビルドに時間がかかってしまい時間のムダです。一度つくったバイナリはRPMにして再利用したいものです。

IAM Role対応のs3cmdを利用する

S3をファイルシステムとしてマウントする s3fs、chefからS3からファイルを取得する s3_fileときて最後は個人的本命のs3cmdです。s3cmdを使うとS3のバケット一覧取得、ファイルアップロード・ダウンロード、S3とのファイル同期などS3に対する様々な操作ができるようになります。

ただこのs3cmd、現在公式サイトから提供されているRPMではIAM Roleに対応していません。s3cmdは2013年6月30日現在、4つのバージョンが入手可能です。

1.0.0
リリース日:2011-01-10 現在rpmで配布されているバージョン
1.1.0-beta2
リリース日:2012-01-07 マルチパートアップロードなど機能追加
1.5.0-alpha1
リリース日:2013-02-19 Singed URLなどさらに機能追加
1.5.0-alpha3
githubやSourceForgeから入手可能 1.5.0-alpha2でIAM Roleに対応!

IAM Role対応版を使いたいので今回はSourceForgeからソースコードを入手してインストールすることにします。もちろんインストールはRPMで行いたいですよね!

事前準備

これから作業を行うEC2サーバのOSはAmazon Linux 2013.03.1 64bitです。またS3を扱うためにIAM Roleを設定済みです。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

第1部: RPM作成支援ツール checkinstall をインストールする

checkinstallとは

一昔前まではRPMを作るとなると、SPECファイルというMakefile的なものを作成していました。いまはcheckinstallというRPM作成を支援してくれるツールがあります。一般的にソースコードからビルド&インストールする場合は以下の手順になります。checkinstallは「4.make installしてファイルをインストール」を監視して、どのディレクトリにどんなファイルがインストールされたかを調べ、その情報を基にRPMを作成してくれます。

  1. ソースコード(tar+gz)を入手してファイルを展開する
  2. ./configureでビルドオプションを指定しMakefileを作成する
  3. makeしてバイナリをビルド
  4. make installしてファイルをインストール

checkinstallをインストールする

checkinstallはgithubから最新版を入手してください。古いバージョンだとCentOS6.3や6.4で(Amazon Linuxでも?)ビルドできない問題があるようです。yumでcheckinstallのビルドに必要なパッケージもインストールします。

$ sudo yum install gettext rpm-build git gcc -y
$ git clone http://checkinstall.izto.org/checkinstall.git
$ cd checkinstall

$ vi Makefile
$ vi checkinstall
$ vi checkinstallrc-dist
$ vi installwatch/Makefile
(後述するようにいくつかのファイルを修正してインストール先ディレクトリなどを変更する)
$ make
$ sudo make install

checkinstallで修正したファイル

デフォルトでは /usr/local にインストールされるので、バイナリは/usr以下に、設定ファイルは /etc/checkinstall に置かれるよう修正します。

$ git diff
diff --git a/Makefile b/Makefile
index 2e28adc..846ab5e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
 # $Id: Makefile,v 1.6.2.1 2008/11/09 07:48:18 izto Exp $

 # Where to install.
-PREFIX=/usr/local
+PREFIX=/usr
 BINDIR=$(PREFIX)/sbin
 LCDIR=$(PREFIX)/lib/checkinstall/locale
-CONFDIR=$(PREFIX)/lib/checkinstall
+CONFDIR=/etc/checkinstall

 all:
        for file in locale/checkinstall-*.po ; do \
diff --git a/checkinstall b/checkinstall
index 978360f..3a3fb3b 100755
--- a/checkinstall
+++ b/checkinstall
@@ -492,7 +492,7 @@ function copy_dir_hierarchy {
 ckversion
 echo

-CHECKINSTALLRC=${CHECKINSTALLRC:-${INSTALLDIR}/checkinstallrc}
+CHECKINSTALLRC=${CHECKINSTALLRC:-/etc/checkinstall/checkinstallrc}
 if ! [ -f $CHECKINSTALLRC ]; then
    echog "The checkinstallrc file was not found at:\n$CHECKINSTALLRC"
    echo
diff --git a/checkinstallrc-dist b/checkinstallrc-dist
index d4feb4e..13ffb70 100644
--- a/checkinstallrc-dist
+++ b/checkinstallrc-dist
@@ -16,7 +16,7 @@
 DEBUG=0

 # Location of the "installwatch" program
-INSTALLWATCH_PREFIX="/usr/local"
+INSTALLWATCH_PREFIX="/usr"
 INSTALLWATCH=${INSTALLWATCH_PREFIX}/bin/installwatch

 # Location of the makepkg program. "makepak" is the default, and is
@@ -117,7 +117,7 @@ RESET_UIDS=0
 NEW_SLACK=1

 # Comma delimited list of files/directories to be ignored
-EXCLUDE=""
+EXCLUDE="/selinux"

 # Accept default values for all questions?
 ACCEPT_DEFAULT=0
diff --git a/installwatch/Makefile b/installwatch/Makefile
index ae34fc1..0b35dd5 100644
--- a/installwatch/Makefile
+++ b/installwatch/Makefile
@@ -4,14 +4,14 @@
 # Well, the only configurable part is the following variable.
 # Make sure the directory you specify exists.

-PREFIX=/usr/local
+PREFIX=/usr

 # End of configurable part

 VERSION=0.7.0beta7

 BINDIR=$(PREFIX)/bin
-LIBDIR=$(PREFIX)/lib
+LIBDIR=$(PREFIX)/lib64

 all: installwatch.so

checkinstallをcheckinstall自身でRPMにしてインストールし直す

さて先ほどまでの手順でcheckinstallはシステムにインストールされましたが、このままではcheckinstall自身がrpmコマンドで更新・削除できません。そこでcheckinstall自身で自身をRPM化してもらいましょう。なお作成されたRPMはrootユーザの所定ディレクトリに作成されるので、事前にディレクトリを作っておきます。

それとcheckinstallの設定ファイル /etc/checkinstall/checkinstallrc がすでに存在していると、2度目のmake installの時にコピーされずRPM化の対象外になってしまいますので事前にファイルを削除してしておきましょう。

$ sudo mkdir -p /root/rpmbuild/SOURCES
$ sudo rm /etc/checkinstall/checkinstallrc
$ pwd
/home/ec2-user/checkinstall
$ sudo /usr/sbin/checkinstall

checkinstall 1.6.3, Copyright 2010 Felipe Eduardo Sanchez Diaz Duran
           このソフトウェアはGNU GPLの下でリリースしています。

The checkinstallrc file was not found at:
/etc/checkinstall/checkinstallrc

デフォルトの内容を使うものとします

The package documentation directory ./doc-pak does not exist.
Should I create a default set of package docs?  [y]: y

パッケージのドキュメンテーションを準備..OK

使用するパッケージ方式を選んでください。
Slackwareなら[S], RPMなら[R], Debianなら[D]を入力 R

**************************************
**** RPM package creation selected ***
**************************************

このパッケージは以下の内容で構成されます:

1 -  Summary: [ CheckInstall installations tracker, version 1.6.2 ]
2 -  Name:    [ checkinstall ]
3 -  Version: [ 20130630 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ Applications/System ]
7 -  Architecture: [ x86_64 ]
8 -  Source location: [ checkinstall ]
9 -  Alternate source location: [  ]
10 - Requires: [  ]
11 - Provides: [ checkinstall ]

変更するものの番号を入力してください。Enterで続行します: (エンターキーを押す)

Installing with make install...

(中略)

**********************************************************************
 Done. The new package has been saved to

 /root/rpmbuild/RPMS/x86_64/checkinstall-20130630-1.x86_64.rpm
 You can install it in your system anytime using:

      rpm -i checkinstall-20130630-1.x86_64.rpm
**********************************************************************

RPMファイルが /root/rpmbuild/RPMS/x86_64/checkinstall-20130630-1.x86_64.rpm に作成されました。内容を確認したら、rpmコマンドでインストールしましょう。

$ sudo ls /root/rpmbuild/RPMS/x86_64
checkinstall-20130630-1.x86_64.rpm

$ sudo rpm -qpl /root/rpmbuild/RPMS/x86_64/checkinstall-20130630-1.x86_64.rpm
/etc
/etc/checkinstall
/etc/checkinstall/checkinstallrc
/etc/checkinstall/checkinstallrc-dist
/usr
/usr/bin
/usr/bin/installwatch
/usr/doc
/usr/doc/checkinstall
/usr/doc/checkinstall/BUGS
/usr/doc/checkinstall/COPYING
/usr/doc/checkinstall/CREDITS
/usr/doc/checkinstall/Changelog
/usr/doc/checkinstall/FAQ
/usr/doc/checkinstall/INSTALL
/usr/doc/checkinstall/README
/usr/doc/checkinstall/RELNOTES
/usr/doc/checkinstall/TODO
/usr/lib
/usr/lib/checkinstall
/usr/lib/checkinstall/locale
/usr/lib/checkinstall/locale/de
/usr/lib/checkinstall/locale/de/LC_MESSAGES
/usr/lib/checkinstall/locale/de/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/es
/usr/lib/checkinstall/locale/es/LC_MESSAGES
/usr/lib/checkinstall/locale/es/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/id
/usr/lib/checkinstall/locale/id/LC_MESSAGES
/usr/lib/checkinstall/locale/id/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/it
/usr/lib/checkinstall/locale/it/LC_MESSAGES
/usr/lib/checkinstall/locale/it/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/ja
/usr/lib/checkinstall/locale/ja/LC_MESSAGES
/usr/lib/checkinstall/locale/ja/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/no
/usr/lib/checkinstall/locale/no/LC_MESSAGES
/usr/lib/checkinstall/locale/no/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/pt_BR
/usr/lib/checkinstall/locale/pt_BR/LC_MESSAGES
/usr/lib/checkinstall/locale/pt_BR/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/ru
/usr/lib/checkinstall/locale/ru/LC_MESSAGES
/usr/lib/checkinstall/locale/ru/LC_MESSAGES/checkinstall.mo
/usr/lib/checkinstall/locale/zh_CN
/usr/lib/checkinstall/locale/zh_CN/LC_MESSAGES
/usr/lib/checkinstall/locale/zh_CN/LC_MESSAGES/checkinstall.mo
/usr/lib64
/usr/lib64/installwatch.so
/usr/sbin
/usr/sbin/checkinstall
/usr/sbin/makepak

$ sudo rpm -ivh /root/rpmbuild/RPMS/x86_64/checkinstall-20130630-1.x86_64.rpm
準備中...                ########################################### [100%]
   1:checkinstall           ########################################### [100%]

$ rpm -qi checkinstall
Name        : checkinstall                 Relocations: (not relocatable)
Version     : 20130630                          Vendor: (none)
Release     : 1                             Build Date: 2013年06月30日 06時54分22秒
Install Date: 2013年06月30日 06時57分09秒      Build Host: ip-10-240-XXX-XXX.ap-northeast-1.compute.internal
Group       : Applications/System           Source RPM: checkinstall-20130630-1.src.rpm
Size        : 460317                           License: GPL
Signature   : (none)
Packager    : checkinstall-1.6.3
Summary     : CheckInstall installations tracker, version 1.6.2
Description :
CheckInstall installations tracker, version 1.6.2

CheckInstall  keeps  track of all the files created  or
modified  by your installation  script  ("make install"
"make install_modules",  "setup",   etc),   builds    a
standard   binary   package and  installs  it  in  your
system giving you the ability to uninstall it with your
distribution's  standard package management  utilities.

無事checkinstallのRPMがインストールできました!

第2部:IAM Role対応版s3cmdをインストールする

最初に説明した通り1.5.0-alpha3はSourceForgeから入手します。またs3cmdはpythonで書かれていてMakefileは提供されておらず、同梱されている setup.py スクリプトでインストールします。それではcheckinstallを介してsetup.pyを実行しRPMを作成しましょう。

$ cd
$ pwd
/home/ec2-user
$ wget http://sourceforge.net/projects/s3tools/files/s3cmd/1.5.0-alpha3/s3cmd-1.5.0-alpha3.tar.gz
$ tar xzf s3cmd-1.5.0-alpha3.tar.gz
$ cd s3cmd-1.5.0-alpha3
$ sudo /usr/sbin/checkinstall python ./setup.py install

checkinstall 1.6.3, Copyright 2010 Felipe Eduardo Sanchez Diaz Duran
           このソフトウェアはGNU GPLの下でリリースしています。

The package documentation directory ./doc-pak does not exist.
Should I create a default set of package docs?  [y]: y

パッケージのドキュメンテーションを準備..OK

使用するパッケージ方式を選んでください。
Slackwareなら[S], RPMなら[R], Debianなら[D]を入力 R


このパッケージの説明を書いてください
説明の末尾は空行かEOFにしてください。
>> S3cmd is a command line tool for uploading, retrieving and managing data in Amazon S3.
>> (エンターキーを押す)

**************************************
**** RPM package creation selected ***
**************************************

このパッケージは以下の内容で構成されます:

1 -  Summary: [ S3cmd is a command line tool for uploading, retrieving and managing data in Amazon S3. ]
2 -  Name:    [ s3cmd-1.5.0 ]
3 -  Version: [ alpha3 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ Applications/System ]
7 -  Architecture: [ x86_64 ]
8 -  Source location: [ s3cmd-1.5.0-alpha3 ]
9 -  Alternate source location: [  ]
10 - Requires: [  ]
11 - Provides: [ s3cmd-1.5.0 ]

変更するものの番号を入力してください。Enterで続行します: (エンターキーを押す)

(中略)

**********************************************************************
 Done. The new package has been saved to

 /root/rpmbuild/RPMS/x86_64/s3cmd-1.5.0-alpha3-1.x86_64.rpm
 You can install it in your system anytime using:

      rpm -i s3cmd-1.5.0-alpha3-1.x86_64.rpm
**********************************************************************

RPMができあがりました!インストールして動作確認してみましょう。

$ sudo rpm -ivh /root/rpmbuild/RPMS/x86_64/s3cmd-1.5.0-alpha3-1.x86_64.rpm
準備中...                ########################################### [100%]
   1:s3cmd-1.5.0            ########################################### [100%]

$ s3cmd ls
s3://〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
s3://〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
s3://〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
s3://〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
(バケットの一覧が表示される!!)

事前にアクセスキーを設定しなくてもコマンドがインストールされただけでS3へアクセスできるようになるのは便利ですね!それではせっかくなので、作成したRPMファイルをS3へアップロードしておきましょう。

$ for f in `sudo find /root/rpmbuild/RPMS/x86_64 -type f`; do
  echo ${f}
  sudo s3cmd put ${f} s3://bucknet_name
done
$ s3cmd ls s3://bucknet_name
2013-06-30 10:34    133481   s3://bucket_name/checkinstall-20130630-1.x86_64.rpm
2013-06-30 10:34    147674   s3://bucket_name/s3cmd-1.5.0-alpha3-1.x86_64.rpm

まとめ

checkinstallを利用することでSPECファイルを書かなくても簡単にRPMを作ることができました。また、これを使ってIAM Roleに対応したs3cmdのRPMを作成し、S3にアップロードすることもできました。S3にファイルを置いておければ、先日ご紹介したs3_fileリソースを使ってchefレシピに組み入れることは簡単になるかと思います。ビルド手順書を見ながら毎回ソースからビルドされている方がいらっしゃいましたら、これを参考にRPM化してみてはいかがでしょうか。