HerokuにGroongaはインストールされていないので、HerokuでGroongaを使うためにはGroongaをビルドしなければいけません。今回はHerokuでGroongaをビルドする方法を説明します。
Herokuにインストールされていないソフトウェアを使えるようにする仕組みがbuildpackです。GroongaはHerokuにインストールされていないソフトウェアなので、buildpackの仕組みに従う必要があります。
buildpackの仕組みに従うには次の作業が必要です。
順に説明します。
まず、次の2つを一緒に説明します。詳細は後述しますが、同じ処理の単位で実行しなければいけないからです。
この2つを実現するビルド用のHerokuアプリケーションを作ります。Groongaの場合はheroku-groonga-builderというのがそれです。
このHerokuアプリケーションは次のことをします。
heroku-groonga-builderは何もしないRackアプリケーション(config.ru
を置いているだけ)で、実際の処理はRakefileの中に書いています。
ソースのダウンロード、ビルド、アーカイブの処理は次のようなイメージです。
% curl -O http://packages.groonga.org/source/groonga/groonga-4.0.2.tar.gz % tar xf groonga-4.0.2.tar.gz % cd groonga-4.0.2 % ./configure --prefix=$HOME/vendor/groonga % make % make install % cd - % tar cJf heroku-groonga-4.0.2.tar.xz vendor/groonga
実際は次のようにrake
を実行して↑の処理を実施しています*1。
% heroku run:detached rake
detachedを使っているのは、Groongaのビルドにとても時間がかかるからです。だいたい6時間くらいかかります*2。
アーカイブしたGroongaは同じプロセス内でアップロードする必要があります。なぜなら、プロセスが終了するとビルドしたアーカイブも消えるからです。これが後述すると書いていた同じ処理で実行しなければいけない理由です。
アーカイブしたGroongaはGitHubのreleaseページにアップロードしています。例えば、Groonga 4.0.2の場合は次のページです。
Heroku上からアップロードするのでGitHubにアクセスするためのAPIキーをHerokuアプリケーションに渡さないといけません。APIキーはセキュリティー上で重要な値です。heroku-groonga-builderではこの情報を環境変数で渡しています。環境変数名はGITHUB_TOKEN
です。
環境変数で渡すには次の2つの方法があります。
heroku config:set GITHUB_TOKEN=xxx
heroku run:detached rake GITHUB_TOKEN=xxx
前者はHerokuの仕組みを使って設定する方法で、後者はRakeの仕組みを使って設定する方法です。前者はheroku config:get GITHUB_TOKEN
で、後者はheroku ps
で後から値を確認できるので、安全性という面ではどっちもどっちです。毎回新しいAPIキーを生成してそれを使い、ビルドが終わったら破棄するくらいがよいのではないかという案がありますが、実装はしていません。
APIキーを使ってアップロードする方法にはいくつかあります。Go言語で書かれたgithub-releaseというツールを使う方法や、Octokitなどのライブラリーを使う方法です。
heroku-groonga-builderは以前はgithub-releaseを使っていましたが、今はOctokitを使っています。
HerokuでビルドしたGroongaができたのでそれを使ってHerokuアプリケーション用の環境をセットアップします。これをするモジュールがheroku-buildpack-groongaです。これはbuildpackの一種です。
実はheroku-buildpack-groongaの中でGroongaをビルドするという選択肢もあるのですが、そうするとgit push heroku master
する毎にGroongaのビルドのために6時間くらいかかるので現実的ではありません。ビルド済みのGroongaをダウンロードすることで時間を短縮しています。
buildpackは次の3つのプログラムが必須です。すべて新規で実装します。実行ファイルになっていれば実装言語は問いません。bashで実装してもRubyで実装しても構いません。
bin/detect
bin/compile
bin/release
bin/detect
は、このbuildpackを使おうとしているHerokuアプリケーションがこのbuildpackが要求する事前条件を満たしているかをチェックします。例えば、Rubyのbuildpackは「Gemfile
が存在すること」が事前条件で、heroku-buildpack-groongaは「groonga/
ディレクトリーが存在すること」が事前条件です。
bin/compile
は、Herokuアプリケーションが必要なソフトウェアをインストールします。例えば、heroku-buildpack-groongaならアーカイブを展開します。
bin/release
は、Herokuアプリケーションが使うデフォルトの設定を返します。例えば、環境変数だったりサービスを起動するコマンドラインなどの設定を返します。heroku-buildpack-groongaは環境変数PATH
の設定などを返します。
詳細は公式サイトのドキュメントやheroku-buildpack-groongaの実装を参照してください。なお、heroku-buildpack-groongaはRubyで実装しています。
buildpackの動作確認用Herokuアプリケーションがあると便利です。heroku-buildpack-groongaを使ったHerokuアプリケーションは次のコマンドで作成できます。
% heroku apps:create --buildpack https://github.com/groonga/heroku-buildpack-groonga
buildpackを修正した場合はHerokuアプリケーションをgit push heroku master
してください。heroku ps:restart
では新しいbuildpackは動きません。既存のbuildpack実行結果を再利用します。
buildpackが動くようになったらリリースします。リリース用のプラグインがあるのでインストールします。
% heroku plugins:install https://github.com/heroku/heroku-buildpacks
これでheroku buildpacks:publish
が使えるようになります。buildpacks:publish
時に指定する名前は#{グループ}/#{名前}
とする習慣があるようなので、heroku-buildpack-groongaはgroonga/groonga
を使っています。
% heroku buildpacks:publish groonga/groonga
これでbuildpackをS3からダウンロードできるようになります。URLは次のようになります。
https://codon-buildpacks.s3.amazonaws.com/buildpacks/#{グループ}/#{名前}.tgz
例えば、groonga/groonga
ならこうなります。
https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/groonga.tgz
ユーザーにはS3からダウンロードしてもらうようにしましょう。
Heroku用Groongaのビルド方法を説明しました。ビルドするには次の4つの手順があります。
このうち、前半の2つがheroku-groonga-builderで実施していることで、後半の2つがheroku-buildpack-groongaが実施していることです。
HerokuにインストールされていないソフトウェアをHerokuで使えるようにしたいときの参考にしてください。
おまけで、Rroonga用のbuildpackであるheroku-buildpack-rroongaの作り方についても簡単に説明します。
このbuildpackはGroongaのbuildpackとRubyのbuildpackを一緒に使います。次のようなイメージです。
bin/detect
が呼ばれたとき
bin/detect
相当の処理をするbin/compile
が呼ばれたとき
bin/compile
を実行bin/release
も実行して結果をマージして保存bin/release
が呼ばれたとき
bin/compile
のときに保存したbin/release
をマージした結果をそのまま出力関連記事: HerokuでRroongaを使う方法
オープンソースのカラムストア機能付き全文検索エンジンのひとつにGroongaがあります。Groongaを使うと全文検索機能付き高性能アプリケーションを開発することができます。
Groongaでは各種ディストリビューション向けにパッケージを提供*1しています。そのため、比較的簡単にインストールできるようになっています。
今回はGroongaのパッケージを公開するのに独自リポジトリでの提供をやめ、Launchpadを利用してパッケージを公開するようにした話を紹介します。
Groongaは各種ディストリビューション向けに独自にリポジトリを提供しています。リリースの際にはchroot環境でパッケージをビルドする仕組みになっています。これはこれで良いのですが、Groongaのビルドには最低2GBのメモリが必要ですし、Debian/Ubuntu/CentOS向けにビルドしていることやアーキテクチャの違いなども含めると、毎回結構な数のパッケージをビルドしていることになります。ビルドするためのPCの負荷もなかなかのものです。並列で走らせてもビルドが完了するまでに時間もかかります。ビルドのために別のPCを確保したので、PCの負荷については改善できましたが、リリースのためのコストという面では問題がありました。
そこで、Ubuntuではパッケージのビルドとリポジトリのホスティングを請け負ってくれるPPA(Personal Package Archive)という仕組みを利用することにしました。
Launchpadに移行するメリットは次のとおりです。
一方、Launchpadに移行するデメリットは次のとおりです。
Groongaの場合はEOLになったらすぐにサポートもやめているので、上記のデメリットは問題になりません。デメリットよりも移行することで得られるメリットが勝っているので移行することにしました。
Launchpadでパッケージを公開するのに必要な情報はPackaging PPA BuildingASourcePackageにあります。公開するための手順を、最初にする作業と毎回する作業とに分けて説明します。
ここでは一度だけする必要がある作業を説明します。
まずは、Launchpadのアカウントが必要です。Create an accountでアカウントを作成します。
Launchpadのアカウントでログインして、プロファイルのページからPGPの鍵を登録します。 Ubuntu Weekly Recipe 第46回 PPAの活用の「公開鍵の登録」を参照すると良いでしょう。
PPAを利用するにはCode of Conductへの署名が必要です。具体的な手順としてはUbuntu Weekly Recipe 第46回 PPAの活用の「CoCへの署名」を参照すると良いでしょう。
ただし、ubuntuパッケージをlaunchpad ppaで公開する方法にも書いてあるように、CoCテキストのダウンロードは、ブラウザで表示されている指定されたテキストをコピーしてそれに署名するやりかたに変更になっています。
Groongaの場合は、リリース担当者が変わることもあるので、Groongaチームを作ることにしました。チームを作るにはログインした状態でRegister a teamで登録します。
リリース担当者を必要に応じてチームのページからAdd memberで登録します。
チームを作成した時点では、PPAは利用できるようになっていません。そこで公式リリース版とベータ版用途の次の2つのPPAを作成することにしました。
後述しますが、ソースパッケージをアップロードするのにdputを使います。そのため、~/.dput.cfに設定を追加しておきます。
[groonga-ppa] fqdn = ppa.launchpad.net method = ftp incoming = ~groonga/ppa/ubuntu login = anonymous allow_unsigned_uploads = 0 [groonga-nightly] fqdn = ppa.launchpad.net method = ftp incoming = ~groonga/nightly/ubuntu login = anonymous allow_unsigned_uploads = 0
ここではリリースごとにする作業を説明します。
最初にする作業をすべて終えたら、いよいよパッケージのアップロードにうつります。
Groongaの場合には、すでにdebパッケージをビルドするためにdebian/*ファイル群があったので、それらを利用してソースパッケージをビルドしました。
必要な手順は次のとおりです。
上記を対象となるリリース(precise/saucy/trusty)ごとに行います。 きちんとアップロードできるとアップロードを受理したことを通知するメールが届きます。あとはビルドが完了するまで待つだけです。
パッケージのビルド結果はView package detailsから確認できますし、もしビルドに失敗した場合には通知メールが届きます。
よくあるのは、controlファイルにビルドに必要な依存関係の記述が抜けていたりすることです。失敗した場合の通知メールにはビルドログへのリンクもありますし、上記詳細ページをたどることでもログを確認できます。ビルドに失敗したソースパッケージはDelete packagesというリンクにアクセスすることで削除可能です。
Groongaの場合には、ここまでの手順をまとめてRubyスクリプトにして(upload.rb)省力化しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def upload(code_name) in_temporary_directory do FileUtils.cp(@source_archive.to_s, "#{@package}_#{@version}.orig.tar.gz") run_command("tar", "xf", @source_archive.to_s) directory_name = "#{@package}-#{@version}" Dir.chdir(directory_name) do FileUtils.cp_r(@debian_directory.to_s, "debian") deb_version = "#{current_deb_version.succ}~#{code_name}1" run_command("dch", "--distribution", code_name, "--newversion", deb_version, "Build for #{code_name}.") run_command("debuild", "-S", "-sa", "-pgpg2", "-k#{@pgp_sign_key}") run_command("dput", @dput_configuration_name, "../#{@package}_#{deb_version}_source.changes") end end end |
上記はupload.rbの抜粋です。
Launchpadでパッケージを公開するようにしたことで、従来aptのリポジトリを登録してもらっていた手順が次のように変更になりました。
% sudo apt-get -y install software-properties-common % sudo add-apt-repository -y universe % sudo add-apt-repository -y ppa:groonga/ppa % sudo apt-get update
これでGroongaをインストールするのに、従来通りにapt-getで簡単にインストールできるようになりました。
% sudo apt-get -y install groonga
今回はGroongaのパッケージを公開するのに独自リポジトリでの提供をやめ、Launchpadを利用してパッケージを公開するようにした話を紹介しました。 すでにdebパッケージがつくれる状態であれば、対象となるリリースごとに必要とされるライブラリに違いがあったり、他のソースパッケージが必要だったりしない限り、Launchpadでパッケージを公開するのは比較的容易です。まだソースアーカイブしか公開していないけど、ゆくゆくはUbuntu向けにパッケージもきちんと提供したいというソフトウェアがあれば、Launchpadを活用してみてはいかがでしょうか。
*1 Debian/Ubuntu/CentOSの場合はpackages.groonga.orgでリポジトリを提供していて、Fedoraの場合にはFedora公式リポジトリからインストールできるようになっています。
クリアコードは今年もインターンシップを実施します。インターンシップをどのように実施するかを3行で説明すると次の通りです。
詳細はインターンシップページを確認してください。過去に実施したインターンシップの詳細はGitHubにあるメモを参照してください。興味のある方はぜひ応募してください。
今回は、インターンシップで開発する題材として使えそうな開発内容を久しぶりに紹介します。
Groongaという全文検索エンジンがあります。HTTPサーバーとして全文検索機能を提供できます。GroongaをHTTPサーバーとして使うと、Webブラウザーで管理画面を使えます。管理画面では、データベースのスキーマを定義したり、登録されている文書を確認することができます。
どのようなUIになっているかは groongaでブラウザベースの管理ツールを使うには - Qiitaを参照してください。
この管理画面を改良する、というのが今回紹介する題材です。どのように改良するかを紹介する前に現状のよいところを整理します。
現在の管理画面のよいところは次の通りです。これらは改良後も維持したい点です。
少し補足します。
まず、すべてクライアント側で動作する点についてです。これにより、別途Webアプリケーションを用意する必要がなく、簡単にインストールできます。これが魅力的です。
次に、全文検索機能の確認についてです。Webブラウザー上で確認できると、手軽に試行錯誤できます。これは開発時に魅力的な機能です。
前述の現在のよいところを維持した上で、管理画面を次のように改良したいです。
それぞれの項目の詳細は[groonga-dev,02321] 管理画面を改良したい!を参照してください。
現在の管理画面はjQueryとjQuery UIで実装していますが、それをAngularJSを使って実装するのはどうかという案があります。AngularJSにはいくつか国際化対応のためのライブラリーもあるよう*2なので、改良したいことを実現しやすい雰囲気があります。
AngularJSベースにする場合は、一気に現在の管理画面を置き換えるのではなく、別のサブパスに配置して、現在の管理画面と共存しながら徐々に機能を移していく方法をとります。現在の管理画面は意外と機能が多く、一気に書き換えると途中で挫けてしまうかもしれないからです。
この開発内容では次の技術を使うことになるでしょう。
久しぶりにインターンシップの題材になりそうな開発内容を紹介しました。プログラミングが好きでフリーソフトウェアに関心がある方はぜひ応募してください。
*1 HTML + CSS + JavaScriptで実装している。
*2 メッセージそのものを翻訳時のキーとして使うという点からangularjs-i18nがよさそうな印象です。
2014/06/22にプログラミングが好きな学生のためのリーダブルコード勉強会を開催しました。後述の通りチャレンジングな目標設定にしたので、学生のみなさんがついてこられるのかという点が不安でしたが、9割以上の参加者が満足し*1、半数以上の人がこれからコードを読んでいこうという思いを持ってくれたようです*2。このため、この勉強会で目指していたことは達成できたと言えます。よかったです。
そんなプログラミングが好きな学生のためのリーダブルコード勉強会の内容を紹介します。2週間後の7/6にも同じ内容の勉強会があり、まだ応募できるので、面白そうだと思ったらまわりの学生さんに勉強会のサイトを紹介してあげてください。
この勉強会では、リーダブルコード(本)に書いているようなリーダブルコードの書き方や、本に書いていないようなリーダブルコードの書き方を伝えることは、「しないこと」にしました。
そうではなく、リーダブルコードを見つける方法を伝えることにしました。
これは、勉強会当日のことよりも、将来を重視したためです。
リーダブルコードの書き方をたくさん伝えることで、勉強会当日だけのリーダブルコード力の増加分を最大化できます。レベルアップが実感しやすいので学生のみなさんの満足度もあがるでしょう。
しかし、当日だけのレベルアップ分の最大化を目指すことはやめました。もっと学生のみなさんのためになることがあると考えたからです。それは、当日だけではなくもっと長い目で見たときによりレベルアップしていること、です。プログラミングが好きな学生のみなさんなのでこれからもプログラミングを続けていくことでしょう。そのため、将来まで考慮することは妥当なことだと判断しました。
よって、たとえ当日のレベルアップ分は少なくなったとしても、勉強会後もレベルアップするための方法を伝えることを目指すことにしました。
当日のレベルアップ分の最大化ではなく、勉強会後もレベルアップするための方法を伝えることを目指すことにより、勉強会当日だけでみればレベルアップ分は小さいとしても、将来を見据えればレベルアップ分は大きくなるはずです。これを目指すことにしました。これがチャレンジングな目標設定だとは認識していて、正しいことだと確信していますがうまくいくか不安でした。
勉強会後もレベルアップするために、「既存のコードからリーダブルなコードを発見する方法」を伝えることにしました。それにはコードを読む習慣が必要です。コードを読まないと既存のコードから発見することはできません。何もないところから新しく作り出す*3ことはできても、見つけることはできないからです。
そこで、この勉強会では、強制的に読む機会を作ることにしました。こうすることにより「どうやって読めばよいのか」を学んで、勉強会後は自分で読めるようになることを目指します。
強制的に読む機会を作るために、次のように実装を他の人と交換して開発を継続する流れにしました。
他の人の実装を元に課題の実装を継続するので、他の人がどのように実装していたかを読んで理解する必要があります。これが「強制的に読む機会」です。
この読む機会を通じて「既存のコードからリーダブルなコードを発見すること」を体験してもらいました。
既存のコードからリーダブルなコードを発見することは難しいことです。リーダブルじゃないコードを発見する方がよっぽど簡単です。なぜなら、リーダブルじゃないコードはいびつなので目立つからです。目立っているのですぐにはっけんできます。
一方、リーダブルなコードはわかりやすく書かれているので簡単に理解できて読んでいてつまづきません。そのため、気づかずにスルーしてしまいます。コードを読み慣れていない人は、よっぽど意識していないと発見できません。
この勉強会ではリーダブルなコードを発表する時間を設けることにより、「意識してリーダブルコードを発見すること」を体験するようにしました。
学生のみなさんが発見できるのか不安だったのですが、実際にやってもらったところ、みなさん1つ以上発見していて驚きました。意識してやってもらうとできるようです。勉強会の実施側としてこれは有用な発見でした。
当日、参加した学生のみなさんに伝え忘れたことがあったのでここに書いておきます。見つけたら、他の参加した学生のみなさんにも教えてあげてください。
今回の勉強会では、自分の実装がその後どうなったのかを確認する時間をとりませんでした。今回は「書く、読む、書く」のサイクルを1回だけ実行する時間しかなかったからです。2回目以降はこれからそれぞれが実行していくことを期待しています*4。
次のサイクルとして以下のことを実行してみるのはどうでしょうか。
他に、「グループの他の人のコードを見て悪いところを見つけたら改良してpull requestを送る」というのも思いつくかもしれませんが、あまりオススメできません。「よいコードを探す」という方向ではなく「悪いところを探す」という意識でコードを読む傾向になってしまうかもしれないからです。
コードレビューのときなどは、「悪いところを探す(問題がないか探す)」読み方は必要な読み方です。しかし、この勉強会の目的にしていたこととは違う方向性のことです。注意してください。
なお、他の人のリポジトリーを探すときはGitHubで「sezemi」で検索してください。
当日の資料はGitHubのclear-code/sezemi-2014-readable-codeにあるので復習したいときは活用してください。
(参加した学生の方は、アンケートには書ききれなかった勉強会で思ったことや、その後こういったことを始めた、継続しているといったことを自分のブログに書いてくれると嬉しいです。その場限りで終わってしまったのかその後のアクションに影響はあったのかが気になるのです。)
プログラミングが好きな学生のためのリーダブルコード勉強会を開催しました。リーダブルコード力を継続的にレベルアップできるようになることを目指しました。アンケート結果や懇親会で聞いた話*5などからうまくいったと言えそうです。ただ、改善しないといけないところも見えているので、7/6の開催分ではさらに改良する予定です。7/6の分はまだ参加登録できるので、まわりの学生の方に勉強会のサイトを教えてあげてください。
勉強会の中でも何度か話した大事なことをここにも書いておきます。
今回はプログラミングが好きな学生のみなさんが集まりました。「プログラミングが好きなこと」はかけがえのない素晴らしいことなので大事にしてください。「好きなこと」は誰かから強制されて持てる気持ちではありません。自分の中からでてきた気持ちのはずです。プログラミングが好きなら、コードを読んでそこから学んでいくことを続けるのはツライことではなく、楽しいことになるはずです。好きなことをして楽しくレベルアップしていけるならさらに楽しくプログラミングできるでしょう。これからも「プログラミングが好きなこと」を大事にしていってください。
それでは、「読む人」の視点を持ってこれからもがんばってください!
今回はメンターのみなさんがいなかったらうまく進みませんでした。本当に助かりました。ありがとうございました!
そんな頼もしいメンターのみなさんを紹介します。(参加した学生のみなさん向け。)
勉強会で紹介があったイベントなどのURLを覚えている分だけ以下に示します*6。参加した学生のみなさんは参考にしてください。
(実は、クリアコードもインターンシップをやっていたりします。)
この勉強会のような内容を自社の新人研修や社内研修でも実施して、リーダブルコード力を継続的にレベルアップしていく開発チームにしたい、という方はコードリーダー育成支援というサービスがあるのでお問い合わせください。
*1 アンケート結果より。
*2 アンケート結果より。
*3 この新しく自分でリーダブルなコードの書き方を開発する方法は今回は対象外としました。
*4 アンケートでは半数以上が実行しようという思いを持ったようなのは前述のとおりです。
*5 懇親会ではみなさんたくさん話をしてくれました。考えるきっかけになる勉強会だったようでよかったです。
*6 間違っていたらごめんなさい。