GentooでGenymotionを利用する

友人の結婚式に参加したら、新幹線のホームの階段から落ちてションボリでした。

Androidの開発では、Intel製のシステムイメージを利用する方法がわりとメジャーなようですが、私の環境ではVirtualBoxとは同時に動作させられないということで、もうちょっと調べてみると、VirtualBoxAndroidのイメージを動作させる、といった趣旨の記事がありました。
その記事で紹介されていたのはAndroVMというものでしたが、いまではこれはGenymotionというものになっているようでした。

Genymotionの導入(Macへの)については、こちらの記事が非常に詳しかったです。
Genymotion で Android の超爆速エミュレータ環境を構築する | アドカレ2013 : SP #6

Genymotion自体も、Windows/Mac/Linuxマルチプラットフォーム対応なんですが、LinuxについてはUbuntu/Debianだけが公式にサポートされています。

ただ、私の環境はGentooなので、当然ながら公式にサポートされていません。他にも公式にサポートされていないディストリビューションで涙を流した方もいるかもしれませんので、動作させるために自分でやったことをメモっておきます。

準備

まずはVirtualBoxをインストールし、GenymotionからLinuxのバイナリをダウンロードします。

この辺はそれぞれのディストリビューションで異なると思いますので、それぞれで行ってください。Genymotionからのバイナリダウンロードには、Genymotionへのサインアップが必要になります。

Genymotionのインストール

ダウンロードしてきたバイナリを、仮にgenymotionとして、~/workに置いた、という前提で話を進めます。

以下のコマンドを実行することで、genymotionのあるディレクトリ/genymotionに、実行ファイルを含めた各種ファイルが展開されます。PATHに追加するかどうかはお好みだと思いますので、その辺は御自由にどうぞ。

$ chmod a+x genymotion
$ ./genymotion

Installing to folder [/home/derui/work/genymotion]. Are you sure [y/n] ? n

- Trying to find VirtualBox toolset .................... OK (Valid version of VirtualBox found: 4.3.10r93012)
- Removing old installation ............................ OK
- Extracting files ..................................... OK (Extract into: [/home/derui/work/genymotion])

Installation done successfully.

You can now use these tools from [/home/derui/work/genymotion]:
 - genymotion
 - genymotion-shell

あとは、genymotion/genymotionを起動すればいい・・・んですが、公式じゃない場合はこの辺で躓くはずです。私はこんな感じになりました。ちなみに私のデスクトップ環境はAwesomeWMで、GnomeとかKDEとかは一回も入れたことが無いような状態です。

$ ./genymotion/genymotion
./genymotion/genymotion: error while loading shared libraries: libgstapp-0.10.so.0: cannot open shared object file: No such file or director

lddで調べてみると、何個かshared object filesが欠けている状態でした。まぁ想定通りではありますが。

依存の解決編

ここからはとりあえずGentooの話になってしまうのでご了承下さい。まず困ったのが、上記のlibgstapp-0.10.soが64bit環境においてはどこのパッケージに入っているのかさっぱりわからない、ということでした。equeryしても出てこないのでマジで困りましたが、捜してみると、gst-plugins-baseというパッケージに入っていることがわかりました。
GenymotionはQTを利用して作成されているようで、どうもqt-gstreamerも必要そうな匂いがしましたので、こちらをemergeすることにしました。

$ sudo emerge qt-gstreamer

これがズバリでした。起動してからは、前述のサイトを参考にしてもらえればわかりやすいと思います。

以上、誰の役に立つかはわかりませんが、メモ書きでした。

Kotlin + IntelliJでAndroid開発を始めてみる(とりあえず動作させてみる)

先日の続きで、IntelliJ上でKotlinを動作させられるようにした後からです。

現在では、Android + Gradleでプロジェクトを作成した場合、何か知りませんが色々と足りないようで、そのままだとKotlinにしたところで動作しません。なので、その辺を対処していきます。
なお、この対処は調べたりなんだりしてやっと動作するようになったものなので、本当に正しいのかは不明とします。

AndroidManifest.xml

AndroidManifest.xmlがなんなのかもよくわからない、というくらいではありますが、初期状態ではここにActivityの記述が無いため、まったく動作させられません。なので、以下のように書き換えました。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gpstracking.app"
        android:versionCode="1"
        android:versionName="1.0">
    <uses-sdk android:minSdkVersion="15"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity"
                android:label="@string/app_name">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

こんな感じにします。packageとかは自分の環境に合わせてください。

build.gradle

次に、Kotlin対応したと思しきbuild.gradleですが、実はこのままではエミュレーターで起動させたときとかに、

Unable to instantiate activity...

とか出て怒られます。エラーメッセージをちゃんと読むと、kotlinのライブラリとリンク出来ない・・・という感じのエラーが出ています。


デフォルトでは、libディレクトリ内にkotlinのランタイムが用意されるわけですが、これとは別に、コンパイル時にこれらとリンクするライブラリを依存に追加する必要があります。
ということで、以下のようになりました。

buildscript {
    ext.kotlin_version = '0.7.270'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
apply plugin: 'android'
apply plugin: 'kotlin-android'

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 19
    buildToolsVersion '19.0.3'

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin' // 無かったらここも追加
    }
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib:$ext.kotlin_version"  // デフォルトからここを追加
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

デフォルトで定義されるものも含めた定義になります。肝はkotlin-stdlibをcompileの依存関係に含めた部分になります。これが大事。

上手くいけば

Clean / Rebuild すれば、多分ちゃんと動作するようになります。Intel x86エミュレータで動作させてみましょう。ちゃんとHAXMが効いていないと、死ぬほど待ちますので、ちゃんと効かせましょう。

これから

とりあえず作ってみたいものがあるので、それができるまでは調べながら作ってみます。問題はAndroidのトレンドの移り変りが激しいことですね。さすがに系統立てて勉強しないときついかもしれません。

IntelliJでkotlin + Android開発を始めてみる

一回Androidアプリを作ってみたかったのですが、どんどん進むAndroidのバージョンと、Javaを(仕事でも書いているので)書きたくなかったため、その大体言語を捜していました。
Scalaとかでチャレンジもしてみましたが、Scala自体がわけわかめ状態になってしまい、こちらも断念。Scalaは構文とかもScalableな気がして怖いです。

そんな折り、Kotlinという言語を知りました。Ceyronとかなら聞いたことはありましたが、これは知らなかったので少し調べると、これもまたJVM言語ということでしたが、
ScalaよりはJavaに近いですが、完全なNullable制御が出来るということで、これいいんじゃね?ということでやってみることにしました。

kotlinの公式ページ

kotlinとは

IntelliJの開発で有名なJetBrains社が公開しているJVM言語(こういう呼びかたでいいんですかね?)です。Githubで公開されています。 https://github.com/JetBrains/kotlin

JetBrainsが作っているということは、当然(?)ながら、IntelliJに公式でプラグインが用意されています。Community Editionでも使えるので、試しに利用してみるだけならば無料で使えるのがありがたいところです。

言語の特徴としては、

  • 演算子オーバーロード
  • null安全を保証
  • クロージャ
    • あるマイルストーンから、関数が完全な第一級オブジェクトとして利用できるようになったそうです
  • パターンマッチング
  • 拡張関数
    • ある意味Kotlinの大きな特徴のようです。
  • プロパティ
    • getter/setterの山と(それなりに)おさらばできる機能です。

その他にも色々あります。使いやすくしたJava、という感じで、特にnull安全が個人的には期待できます・・・が、Android開発に使う場合は嫌でもoverrideした時に結局nullを許可しないとならないので、これはこれで考えものかと・・・。

IntelliJで利用する

ちょっと調べると色々な人やサイトで記述されているので、こちらを参考にしました。現在のIntelliJのバージョンと差異がありますが、特にやることは変わりません。
https://sites.google.com/site/tarokotlin/chap2/sec23

IntelliJ上でのAndroid開発についても、色々なところで書かれているので、こちらも以下のページを参考にしました。
http://d.hatena.ne.jp/CortYuming/20131001/p1

Android Studioでは、Gradleが標準になったということなので、今回はGradleで作成してみます。

Gradleを利用したAndroidモジュールを作成する

と言っても、環境構築ができていれば、単純にプロジェクトを設定していくだけです。

New Project -> Java -> Android -> Gradle: Android Moduleを選択

Gradle構成の場合、メインとなるプロジェクトと、メインとするモジュールをそれぞれこの時点で定義する必要があります。ここはよくわかりませんでしたが、何回か作り直したりしたら、なんとなくわかるようになりました。

kotlinを利用する

これも簡単で、プラグインが入っていれば、どこかのディレクトリの上で右クリック → New → Kotlin fileを選択して、ファイル名を入れるだけです。すると、右上に通知的なものが出てきますので、とりあえずそれをクリックしていけば、Kotlinの設定は終わってしまいます。

注意としては、kotlinのファイルはソースのルートディレクトリ(デフォルトではsrc/main)に、 *kotlin* というディレクトリ名で作成した上で、その中に格納するのがベターの様です。これも、エディター部分の上部に通知的なものとして表示されて教えてくれます。

とりあえずはここまでで、次は実際にKotlinで作ったアクティビティをエミュレーター上で動かしてみたいです。

OCamlでBDDを行うライブラリを作ってみた

社会人になって早7年目、やっと昇給という事象を経験できそうです。こんだけやって給料上がらんかったら転職した方がいいよ、と言われてますが、万が一上がらんかったらまた転職活動しないとならんのかな・・・。しんどいな。

さて、そんな身の回りのことはどうでもいいのですが、OCamlでちまちま色々なものを作ったりしています。ちまちますぎて何もできあがってないのが悲しいです。
そんな中で、とりあえず利用できるかなー、というくらいまできて、自分で利用したりしてみているライブラリがあります。

https://github.com/derui/simplespec

名前は気にしないでください。

作った動機

ぶっちゃけると
https://github.com/andrenth/ospec

これをめっちゃ参考にしています。というか基本的なコード部分はかなりクローンしていますが・・・。

ただし、個人的にインデントとかtuaregで上手い具合になってくれないと困る場面が多々あったので、文面を変えてあるのと、specのrunnerに、ocamlfindの機能を取り込んで、packageを利用している場合でもちゃんと実行できるようにしたりしています。
現在の機能としては非常に少なく、以下の機能しかないです。

  • describe/itでのテスト記述
  • before/afterやbeforeEach/afterEachとかでセットアップとかクリーンアップとかの処理ができるように
  • pendingとして、あとで書くテストを明示できるように
  • そこそこのパターンのmatcherを用意
  • コンパイルしないと動作が難しいようなものでも、コンパイルさせて動作させられるように
    • この辺はもうちょっとなんとかしたいです。

ospecでは、こんなものは当然、という感じで、さらにHaskellでいうQuickCheck相当の機能まで取り込んでいるようです。

作っている間に学んだこと

Camlp4は(慣れれば)よくわからないなりになんとかなる。

なんじゃそりゃ、という感じではありますが、実際そんな感じです。どうしてもわかんなかったら、やたらと複雑なCamlp4のソースを眺めてれば、何となくな書き方はわかった気になります。

それとToplevelは面白いです。こういうもの以外での用途が私の頭では思い浮かびませんが、もっと便利な利用方法はあるんでしょう、多分。

実際どんな感じになるのか

shouldの一部機能を使うとこんな感じ。

describe "The number one" begin
  it "shoud to be implement late" pending;
  it "should equal 2 when added to itself" begin
    (1 + 1) should = 2;
    let eq = (=) in
    (1 + 1) should eq 2;
    let eq x = (=) 2 x in
    (1 + 1) should eq;
  end;

  it "should equal 0 when subtract to itself" begin
    (1 - 1) should = 0;
    1 should (fun x y -> (1 - x) = y) 0;
    1 should (fun x -> (1 - x) = 0);
  end
end

shouldにはパターンマッチを書いて、そのパターンにマッチしなかったらアウト、とかもできます(ちょっと怪しいですが)。

まとめ

Camlp4の可能性は半端ない。そして難易度も半端無い。

でもOCamlDSLを書きたい人とか、メタプログラミングしたかったら必携なので、そういう場合はあきらめて格闘しましょう。

Threes!のクローン作ってみた

最近久しぶりにがっつりめに風邪を引きました。休むほどではないのですが、体力なのか年なのか、やたらと長引いています。どれくらい長引いているかというと、一週間くらい咳と鼻水がずっと出てるくらい、でしょうか。
これだけ治らないのは記憶にないくらい久しぶりなので、鼻うがいというのも試してみてます。鼻がつまりすぎているとなかなか難しいもんですね、これ。

Threes!について

Android/iOSで遊べるゲームです。非常にシンプルなルールなんですが、かなり絶妙な難易度でして、寝る前とかに始めるとついつい何回もやってしまって、寝る時間を逃がす程度にはハマっています。
有料ですが、動作などもサクサクと動作しますし、基本的にやればやるほど上達する感が大分いいかんじです。よければいかがでしょうか?

公式
https://play.google.com/store/apps/details?id=vo.threes.exclaim

発端(というか動機)

何げなくページ巡回をしていたら、以下のページが目にとまりました。
Vim界隈だけではないと思いますが、有名人の id:thinca さんが、threes!のVim版を作ったということでした。

threes.vim 作った:永遠に未完成

これを見て、「そうだ、Go言語で何作ろうかと思ってたけど、これ作ろう」、ということで作りました。
制作期間はとりあえず2日くらいなので、リファクタリングとか何もできてねーですが、一通り動作するようにはなってます。

動作させるとこんな感じです。

h,j,k,lで動作、qでとりあえず今のゲームを終了します。これ以上動かせなくなった場合でも同様に終了します。終了すると、現在のスコアを表示して終わります。

動作、スコアの表示とかは、とりあえずゲームをしながら調べたので、間違ってる可能性も非常に高いですが、まぁそこはそれということで。
それと、sttyを内部で利用している関係上、Windowsでは動きません。

作ってみて

Go言語はやはりRuby/Python/Perlではなく、Cとかの方に近いと再認識しました。特に配列やスライス関係のリテラルとかで。
やっていると、配列をがりがり弄るよりは、map/filterとかをできたら楽なのになー、という点が多くありました。まぁ、パフォーマンスを考えると配列を直接いじったりした方が早いのかもしれませんが、毎回rangeを打つよりは、map/filterでやりたいなー、と思う今日この頃でした。

それ以外では、基本的に標準ライブラリだけでやっています。標準ライブラリが大事な所をカバーしているため、その辺はあまり苦労しませんでした。
一番苦労したのはやっぱり配列とかスライスを直接走査したり操作したりしなければならないところが多かった、という点でしょうか。まだGo言語の設計についていまいちよく理解していないので、もっといいやりかたはあると思います。

しかし、大分久しぶりに形があるものを作った気がします。最近そんなもの作ってないなー、と思いながら作ってました。いやー、やっぱりゲーム関係は作ってて楽しいですね。

[Google Apps Script]GASでスプレッドシートの内容をXMLで取得する

ものすごい久しぶりに風邪引きました。3年振りくらいだろうか。熱とかはなくて、基本的には鼻水と咳と喉の痛みだけですが、ここまで久しぶりだと新鮮です。

発端

最近、プロジェクトのユニットテスト環境を改善しようと色々やっていたのですが、そろそろS2JUnit4から脱却する必要を感じてきたため、DBUnit + JUnitのRuleアノテーションを使った環境を作ってみました。

DbUnitは名前だけなら前から知っていたのですが、実際に使ったことはなかったため、色々と調べることになりましたが、一番問題になったのは基本的にXMLを読み込む、ということ。
プロジェクトとしては、Gitを使うようになったのと、データをどのように編集したかがわからない、ということもあったので、テキスト形式なのはありがたいのですが、いかんせんXMLは編集しづらいのです。

こういうときのためのVBAだとは思いますが、正直あれは書きたくないです。

ということで、消去法として、Google Apps Scriptでスプレッドシートの内容をXMLとして出力したらいいんでね?という短絡的な思考に落ち着きました。

まずは調べる

Google Apps Scriptは、Google Appsの色々な機能を統合的に利用できるライブラリを利用できる、JavaScriptの実行環境のようです。まぁつまりはただのJavaScriptなので、こっちの方がVBAよりよっぽどやりやすいですね。Web系ではJavaScriptが必須なので、いじるにしても抵抗がありません。

ただ、個人的には生のJavaScriptをいまさらガリガリと書く気にはあまりなれない(やるしかなけりゃやりますが)ので、外部ライブラリとしてお気に入りのUnderscore.jsを追加します。
追加する手順については以下のページを参考にしました。

http://qiita.com/soundTricker/items/5a7e050a2a20f3e3938a

あとはこれで、XMLファイルとしてダウンロードさせることができればとりあえずはOKです。

XMLの作成はXmlServiceを、コンテンツとしてダウンロードさせたければContentServiceを使えばよさそうです。
ここまでわかればあとはリファレンスを読み読みしながらできそうなので作ってみました。

作ってみた

// define underscore.js.
var _ = Underscore.load();

var Apps = {
  convertRowToDataRow : function (tableName, column, rowValue) {
    if (!column || column.length === 0) {
      return null;
    }
    
    if (!rowValue || rowValue.length === 0) {
      return null;
    }
    
    var item = XmlService.createElement(tableName);
    _(column.length).times(function (index) {
      if (!_.isUndefined(column[index]) && !_.isUndefined(rowValue[index])) {
        
        var value = rowValue[index];
        if (rowValue[index] instanceof Date) {
          var moment = Moment.moment(rowValue[index]);
          value = moment.format('YYYY-MM-DD HH:mm:ss');
        }
        
        item.setAttribute(column[index], value);
      }
    });
    Logger.log('created ' + tableName + ' table.');
    return item;
  },
  
  getFilenameByPrompt : function () {
    var ui = SpreadsheetApp.getUi();
    var response = ui.prompt('ダウンロードするファイル名を入力:');

    // Process the user's response.
    if (response.getSelectedButton() == ui.Button.OK) {
      return response.getResponseText();
    } else {
      return '';
    }
  }
  
}

function exportSheetAsTable(sheet, root) {
  
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();
  
  if (numRows < 2) {
    return;
  }
  
  var column = values.shift();
  var numColumns = column.length;
  
  _.each(values, function (row) {
    var child = Apps.convertRowToDataRow(sheet.getName(), column, row);
    if (child) {
      root.addContent(child);
    }
  });
}

function exportSheetsAsXML() {
  var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  
  var root = XmlService.createElement('datasets');
   
  _.each(sheets, function (sheet) {
    exportSheetAsTable(sheet, root);
  });
  
  var document = XmlService.createDocument(root);
  var xml = XmlService.getPrettyFormat().format(document);
  return xml;
}

function createExportedXml() {
  var xml = exportSheetsAsXML();
  Logger.log(xml);
  
  var filename = Apps.getFilenameByPrompt() + '.xml';
  
  var file = DriveApp.createFile(filename, xml);
  
  // Display a modal dialog box with custom HtmlService content.
  var template = HtmlService.createTemplateFromFile('dialog.html');
  template.file = file;
  
  var htmlOutput = template.evaluate()
     .setWidth(400)
     .setHeight(150);
  SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'XMLダウンロード');
  
  file.setTrashed(true);
}

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "XMLとしてエクスポート",
    functionName : "createExportedXml"
  }];
  sheet.addMenu("変換", entries);
};

実際にやっていること自体は単純と言えば単純で、

  • 各シートをテーブルとみなして、各行をdatasetsの一行として利用
  • 全部を1ファイルにまとめて、一旦Google Driveにファイルを作成する。
    • 作成したファイルはすぐにゴミ箱送りにしておく
  • ダウンロードリンクをはったダイアログを出す

単純にダウンロードさせることが思ったよりも難しかったため、Driveの機能を使いました。こっちの方がシンプルのような気がします。

まだいくつかやっといた方がいいと思われるものはあります。

  • DbUnitの場合、DateとTimestampでフォーマットが異なるので、これをなんとかわかりやすい状態で記述できるようにしたい
    • マークかなんか付けられればいいんやけど・・・。
  • flat datasets形式のXMLをアップロードして、それを展開できるようにしたい
    • いいXML編集環境があればいいんですが
感想

実際に今のプロジェクトでもいくつか使っているものはあるけど、これくらいちゃんと作ろうとしたときでも、結構必要なライブラリが標準で提供されているので、作りやすかったです。

やっぱりUnderscoreとかその他のライブラリをそのまま使えるというのもなかなかよさげです。諸事情から、あまり積極的には使えませんが、ちょっとしたマクロを書くにしても、こっちの方が楽ですね。

こんなことをしているよりかは、プロジェクトの方でDbUnitとかをもっとちゃんと使えるようにした方がいいですね。そうですね。

Vagrant上でGitlabを試してみる

はじめに

割と前から、Gitlabの存在は知っていましたが、「どうせ業務でも使えんし、個人利用だと完全にオーバースペックだしなー」ということで、触ったことはありませんでした。

現在の業務では、当初からSVNを使っているプロジェクトで、大体3年半くらい継続して開発が行われています。
ただ、その間に何度かブランチのマージミスに起因するリリースミスをやらかしています。私自身もやらかしていて、そういう経緯と歴史から、SVNの管理は次のようになっていました。

  • trunkをそのままリリースする
  • リリース日までに開発するものは、trunkから作成したブランチ上で作業する
  • trunkになんらかの修正があったら、ブランチにすぐ反映する

この管理でしばらくやっていますが、前提として、複数ブランチの開発はしないというものを付けています。前は、SVNでチケット単位でのブランチモデルを使っていましたが、それが原因で盛大なマージミスを何回かやっており、客先からも懸念されていたため、この制限については客先も了承していたので、危ないときもありましたが、とりあえず安定してきていました。

しかし、状況が変わり、

  • 他のプロジェクトとの関連機能が多くなる(他のプロジェクトは完全に別)
  • しかし自分のプロジェクトだけの修正はできれば高い頻度で出したい

という客先からの希望が出てくるようになりました。SVNで複数ブランチを使って作業するのはかなり危険(私の経験では)と判断し、それならば、ということで、GitとGitlabを代わりに利用すればいいんじゃまいか、ということで、試しに私の方で構築することにしました。
Gitlabは私が入れてみたかったから、というのもありますが、コードレビューを効率的に行える環境も求められてきているので、一応そういう動機もあります。

実際にやってみる

やたらと長い前置きになりましたが、とりあえず構築したメモになります。

その前に私の環境と、今回使ったBoxを。

Host : Gentoo Linux (3.11.4)
VirtualBox: 4.3.6
Vagrant : 1.4.3
Box : http://github.com/mitchellh/vagrant-aws/raw/master/dummy.box

Boxはdummyという名前で入っていることを前提にしています。
ちなみにGitlabの公式ページでは、Debian/Ubuntuと書かれていますが、とりあえずここでは実験も兼ねていますので、特に気にせず行きます。

まずは今回のVMを格納するディレクトリを作って、Vagrantの初期化をします。この時点では、vagrantのpluginをインストールしていなかったので、ついでにやっときます。

$ vagrant plugin install vagrant-aws
$ mkdir gitlab_sample
$ cd gitlab_sample
$ vagrant init dummy

作成されたVagrantfileに、AWS接続のための色々な設定を書いてやる必要があります。

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # All Vagrant configuration is done here. The most common configuration
  # options are documented and commented below. For a complete reference,
  # please see the online documentation at vagrantup.com.

  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "dummy"

  config.vm.provider :aws do |aws, override|
    aws.access_key_id = 'アクセスキー'
    aws.secret_access_key = 'シークレットキー'
    aws.region = 'ap-northeast-1'
    aws.instance_type = 'm1.small
    aws.ami = 'ami-0d13700c'
    aws.security_groups = [セキュリティグループ]
    aws.keypair_name = 'キーペアの名前'
    aws.tags = {
      'Name' => 'gitlab_sample'
    }
    override.ssh.username = 'ec2-user'
    override.ssh.private_key_path = 'キーペアのフルパス'
  end

end

これでsmallインスタンスであがるはずですので、実行してみます。ちなみにmicroインスタンスでいけば無料枠でいけたのですが、試しにやってみたら、後述のgitlabインストール時に、メモリ不足でそもそも起動できませんでした。

$ vagrant up --provier=aws
# なんか失敗しますが、sudo じゃないと作成できない場所に/vagrantを作成しようとしてエラーになっているだけなので気にしなくてOKです。
$ vagrant ssh

さて、ここからがやたらと大変です。CentOSは基本的に一つ前のバージョンとかしかありません。なので、必要なものは随時自分でインストールする必要があります。
調べたところ、CentOS 6.4 用の GitLab 自動インストールスクリプトを書いたという非常にありがたいページがありました。

が、せっかくなので、上も参考にしますが、公式HPで紹介されている方法でやっていきたいと思います。

・・・と思ったのですが、作業が予想以上に膨大になりましたので、https://github.com/derui/gitlab-installer-ec2/に、これらの作業をまとめたスクリプトを作りましたので、こちらを参照してください。
残念ながら、時間の無い状態でやったため、エラーチェックとかも何もありません。また、このインストールスクリプトは、rubyのインストール周りについては、上記のページを盛大に参考にさせていただいています。

このスクリプトで、一応インストールまではできると思いますが、いかんせん実地でやったのをまとめただけですので、色々と問題がある可能性が非常に高いです。参考にされる方は、くれぐれも自己責任でお願いします。

ちなみにインストールには最低でもsmallくらいじゃないと快適にできません。microでも動作するような気はしますが、公式でも「Very slow」と言われていますので、ちょっとお金を出した方が多分早いです。

以降、vagrant sshした中でやっていきます。

$ sudo yum update
ruby1.8.7が入っているため、一旦削除します。
$ sudo yum remove ruby
$ sudo su

# これでいけるようにしました。なお、必ずEC2上で構築できる、というわけではありませんのでご了承下さい
$ curl -O https://raw.github.com/derui/gitlab-installer-ec2/master/install.sh | sudo bash 2>&1 | tee gitlab-installer-ec2.log

さて、ここからは実際に構築する上で、ハマった点などを書いていきます。

redisのインストール

上述のスクリプトの中には、redisのインストールが書かれていなかったため、gitlabのsetupでエラーが出てしまっていました。なので、redisのインストールをこちらを参考にして行いました。
ただyumするだけですが。

apache2へのインストール

業務で実際に利用する環境はapache2が入っているのですが、Gitlabでは公式にはnginxしかサポートしていません。
ですが、当然ながらみながみなnginxであるわけはないので、recipesということで、unofficialな設定などをあつめたサイトへ誘導されていました。

https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache

SSLでの接続設定と、HTTP Onlyでの接続設定と両方がありますが、SSL推奨ということでそちらを使います。
また、SSLでの接続だと、証明書とかが必要になったので、以下のページを参考にオレオレ証明書ではありますが、用意しました。

http://albatrosary.hateblo.jp/entry/2013/04/30/123019

これについては、ぶっちゃけ自前で用意してもらうのがいいような気がしてますので(opensslのオプションがよくわからん)、スクリプトの中ではコメントアウトしています。

やってみて

正直、すでにEBSに格納しているSVNがあるのであれば、新しいサーバーを一つたてて、EBSをアタッチした状態から始めた方が早いなー、と思いました。ApacheとNginxの設定方式がやたら違うので・・・。

ただ、既存の環境がかなりhttpdに依存してしまっているので、どうしようかなー、という感じです。Amazon Linuxの場合、既存のrubyを削除しなければならないということもあり、ちょっと導入にためらうのもどうかな?という気がします。

なんにせよ、方法がある程度確立できればいい、というのが今回の趣旨だったので、それについてはできたと思います。

後、EC2を私用で初めて使ってみましたが、金額が頭に浮かんで心臓に悪いです。AWSこわい。