RELEASE
2014.10.31

シンプルなビルドパイプラインツールwalterをリリースしました


walter-logo

 APソリューショングループの相野谷(@ainoya)です.このたびATLと共同で,CIやCDにおけるビルドパイプラインの実行を手助けする小さなツールwalterを開発しました.

開発の動機: Jenkinsプラグインに強く依存するビルドパイプライン設定

 Jenkinsを使ってCIを実現する場合,複数のジョブを繋げて一連の処理フロー(ビルドパイプライン)を作るのが一般的かと思います.Jenkinsには,ビルドパイプラインを構成するための便利なプラグインがあり,これを使って失敗時の実行制御や,ジョブの並列実行制御を簡単に設定できます.

 ところが,こうしたプラグインで実際にCIを運用してみると,ちょっと惜しい点がいくつか出てきました.


  • パイプラインの全体実行フローをJenkins上でしか確認できない
  • Jenkinsジョブを実際にキックするまで動作が確認できない
  • 設定の移行がしづらい.GUI中心で行うビルドパイプライン設定を簡単に他のJenkinsへエクスポートできない

  •  dockerやansibleを使って,サーバ構成をソースコードと同じように集約して管理できているのに,Jenkins上でのビルド設定だけJenkins側に寄ってしまっている….この不満点を解決するために,Goでwalterという小さなツールを書きました.

    walterの概要

     walterというツールでは次のようなことができます;


  • 設定ファイルでのビルドパイプラインの記述: ansible playbookやtravis-ciの設定ファイル(travis.yml)のように,コードベースと同じ管理方法で設定ファイルを扱いやすくする
  • ローカル環境でもビルドパイプラインの実行が可能: CIサーバなしでビルドパイプラインを実行できる
  • シンプルな利用方法: 複雑なGUIや,専用のDSLを理解しなくとも単純な記述でビルドパイプラインが構成できる

  •  walterの動作は単純で,独自の設定ファイル(yaml)に記述した実行ルールにしたがって,ジョブを順番に実行していきます.記述方法はtravis-ciの設定ファイル(travis.yml)に似ていますが,walterではジョブの並列実行処理を簡単に書けるようになっています.

    ユースケース

    walterではpipeline:の下にビルドパイプラインの実行順序と,処理の内容を記述します. 各ジョブの詳細はstageで定義された各プロパティに書いていきます.

    各ジョブの設定を記述するstageは次のプロパティを持っています.


  • stage_name: stageの名前
  • stage_type: stageの記述形式.commandと設定すると,command:プロパティに書いたシステムコマンドを実行する.(省略した場合のデフォルトはcommand)
  • command: ジョブで実行するシステムコマンドの記述
  • run_after: 設定したstageが実行終了した後に実行したいstageを記述します.後述の通り,run_afterに記述したジョブは並列で実行される

  •  具体例として,walterのサンプル設定ファイル(pipeline.yml)を下に示します.

     上記でpipeline.ymlに定義されたビルドパイプラインは下図のように表すことができます. 図に示した通り,pipelineのトップレベルに定義したstageは,それぞれのジョブの終了を待って順番に実行されます.一方,run_afterに記述されたジョブは並列に実行されます.


    walter-pipeline-sample

    その他の実行例として,dockerコンテナをビルドしつつアプリケーションを用意する…というサンプルを用意しています.ご参考にしていただければと思います.

    walterを試してみる

     GitHubでwalterのビルド済みバイナリを配布しているので,これをダウンロードすればwalterを実行できます.試しに,mac環境でwalterを実行してみましょう.

    1. mac用ビルド済みバイナリを取得.
    2. sampleのビルドパイプライン設定ファイルを取得.
    3. walterを実行します.-cオプションで実行対象のビルドパイプライン定義ファイルを指定します.(無指定時のデフォルトは./pipeline.ymlです)

    pipeline-execution

     pipelineで指定した順序通りにstageが実行されたでしょうか?stageの記述や実行順序を変更してみて,挙動が変わるか確かめてみてください.そしてbugが見つかったらissuesまでお願いいたします:-)

    Microservices with walter

     複数のサービス/サーバ群で構成されるアーキテクチャでは,各々のサービス間に依存関係がある場合,それによってデプロイ順序に制約がかかります.もとはモノリシックだったサービスが,分割されて複数サービスとして運用されるようになった場合にありがちです.

     こうした場合にも,前述で説明したwalterの使い方を応用すれば,複数のサービス/サーバ群で構成されるアーキテクチャのビルドパイプラインも楽に記述できます. 下図のように,事前にあるべき必要な2種類のサービスを先にデプロイしておき,それに依存する残りの4種のサービスをデプロイする,といった要件にも対応可能です.

    walter-msa

     複数サーバのプロビジョニングに関しては,ansibleだけでもwait_for記法や並列実行オプションを使えば実現可能です.しかしながら個人的な感覚としては, ansibleは適切な粒度で実行したほうが取り回しがしやすいと考えています.ansibleによるプロビジョニングの実行単位を適度に区切りつつ, walterでそれらの実行単位をつなぎあわせ,制御することで全体構成の見通しを良くするのが狙いです.

    開発の現状と今後の予定

     現状のビルドパイプラインの構成方法に対する不満点を解決するために,walterというツールを書きました.コードの品質はまだまだプロトタイプの状態ですが,エラー処理やリトライ機構などを中心に品質を上げていく予定です.もちろん,社内での実運用を通しての改善も随時フィードバックしていきます.また,さらなる利便性を向上を目指して,

  • ジョブ間のメッセージパッシング機能強化: パイプラインの実装はgoroutineを使っているので,これを活用して各ジョブの実行データの連携を強化する
  • より分かりやすい記述: yaml形式での煩雑な記述からの脱却.ビルドパイプラインの記述方法を見通しの良いものにする(DSLにしたくないが,記述性とのトレードオフを考えたい).
  • ChatOpsとの親和性強化: Slackへの対応,より細やかな通知連携機能の強化
  • Jenkinsとの連携: ビルドパイプライン実行中のジョブ進捗をJenkins(または外部)に適切にフィードバックする仕組み

  • などなど機能の充実に取り組んでいく予定です.


    コードはGitHubで公開しているので,皆様に使っていただき使用感を教えていただければ幸いです.

    RELEASE
    2014.10.27

    Clojure夜会でLTしました


    APソリューショングループの吉田と相野谷(@ainoya)です.

    先日リクルートテクノロジーズで行われたClojure夜会で,下記2つのLTをさせていただきました.

    吉田: “会社でClojure使ってみて分かったこと”

    Clojureを業務で使用した実例の紹介です.Clojureで実装を行う上で良かった点や,苦労した点についてLTしました.

    相野谷: “JavaOneでRich Hickeyのセッションを聞いてきた話”

    今月頭にサンフランシスコで開催されたJavaOneに参加し,Clojureの作者であるRich Hickeyのセッションを聞いてきたので,その所感をLTしました.

    Clojure夜会の様子

    イベントは参加申し込み100人という予想を超える盛況ぶりで,Clojureへの注目の高まりが感じられました.主催の@tnoborio)さん,@kawasimaさん,発表者の皆様ありがとうございました.この場を借りてお礼申し上げます.

    2つのLTの発表内容の通り,Clojureは決してプログラマのおもちゃなどではなく,十分実用レベルに達している言語だといえます.netflix社のPigPen や,puppetのClojure化など,プロダクション環境でのClojure活用事例は日々増えており,Rich Hickeyもエンタープライズ領域でも活躍する言語だ,とセッションの中で自信を持って述べていました.

    Clojure夜会の場を通して,より多くの方々がClojureを知り,活用することに期待しています.

    TAGS: ,

    RELEASE
    2014.09.12

    Qiita Meetup #8で弊社活用事例を発表しました


    スマートデバイスグループの片渕(@hotchemi)です。

    今回Open Network Space Daikanyamaで行われたQiita/Qiita:Team Meetup #8に参加し,「100人で使うQiita:Team」というタイトルで筆者の所属するスマートデバイスグループのQiita:Team活用事例を発表致しました。当日のハッシュタグは#qiita_meetupとなります。

    解決すべき課題

    どの様なジャンルであろうとツールとは問題解決の手段なので,そもそも解決すべき課題が定まっていなければ導入する意義は薄くなりがちです。

    私の所属するスマートデバイスグループは100名を超える比較的大きな組織ですが,以下の様な課題感を抱えていました。

    • そもそもエンジニアが情報発信する文化が醸成されていない
    • 情報発信するプラットフォームが無いため,メールや会議中心のコミュニケーションとなっていた。技術情報なども全てメールでやり取りしていた
    • エンジニアが集まっているものの,コミュニケーションがチーム間で完結しておりチームを超えたナレッジ共有が成されていなかった

    これらの課題を解決する為,「 気軽に情報を発信でき,インタラクティブなコミュニケーションが可能でエンジニアフレンドリーなプラットフォーム 」を導入する為に動き出しました。

    導入までの道のり

    ツール検討時にはQiita:Teamの他にも,株式会社ソニックガーデンSKIPAtlassianConfluenceを検討しましたが,最終的に投稿のしやすさや使い方・UIのシンプルさを重視しQiita:Teamを選択しました。

    上記の2ツールも非常に有用なので,組織のコンテキストに応じてセレクトするのが良いと思います。

    導入に当たって

    1ヶ月のトライアル期間を経て採用に至ったわけですが,導入段階ではとにかく書く事の敷居を下げる事に注力しました。

    具体的には,

    • よく使いそうなタグ「iOS,Android,ランチ,ポエム」等を予めピックアップしてあげる
    • 初めから全員を巻き込むのではなくアーリーアダプタ層に記事を書き溜めてもらい徐々に和を広げていく
    • 議事録や日報もQiita:Teamに書いて貰い,ツールに触れる時間を増やす
    • 初めて触る人用のプロジェクトページを作成し,ツールの意義や雰囲気を理解して貰う
    • 地道に啓蒙活動を続ける

    などの施策を打つ事によって,徐々にメンバーが記事を書いてくれるようになりました。

    いかに優れたツールであっても使って貰えなければ意味がないので,この辺りは地道な啓蒙活動が必要なのだというのが振り返ってみた率直な感想です。

    組織の文化を醸成するという事は一朝一夕ではできないので,根気の良さが求められると思います。

    導入成果

    現在は1日平均20件(技術ネタ10,日報4,議事録6)程度の投稿があり,予想していたよりもタイムラインの流れが速いという嬉しい問題が起こっています。markdownというフォーマットが足かせになるかと思っていましたが,非エンジニアであってもmarkdownを覚えて投稿してくれています。

    また,徐々にですが以下の成果が出始めています。

    • エンジニア-QAメンバー間でテストの観点や書籍に関する知見を共有するなど,これまでにないコラボレーションが生まれた
    • 社内で勉強会を気軽に開催しやすくなった
    • 細かい要望などメンバー一人一人の声を拾いやすくなった
    • 本家Qiitaに投稿してくれる人も出てきた

    課題

    勿論課題が無いわけではなく,想定していたよりもタイムラインの流れが速くなり一つ一つの投稿をしっかり見る時間がないという問題や,社内のユースケースだとどうしても特定メンバーのみで共有したい情報をどうするかという問題が出てきています。

    Incrementsの人と話した所、上記の問題へのソリューションを検討しているとの事でしたので,楽しみに待ちたいと思っています。

    まとめ

    • Qiita:Teamを活用する事でチームを超える交流が生まれた
    • 議事録や技術情報などグループ内ナレッジの一元化に成功
    • メールベースの情報発信からQiitaでのリアルタイムな情報共有へ
    • 100人規模のチームでも特に問題なく運用する事が可能!
    • 情報量が多くなると追い切れないという課題はある

    リクルートテクノロジーズでは今後もエンジニアリングやチームビルディングの改善活動について,積極的に知見を共有していきたいと考えています。

    RELEASE
    2014.09.02

    Google GlassはNexus 5で十分にプロトタイプできるか?


    こんにちは、ATLでウェアラブルデバイスの研究をしている吉村です。ふとしたことからGoogle Glassに触れることになってここ3〜4回ほど記事を書かせていただいていたわけなのですが、このデバイスはなかなか面白いものです。ボイスコマンドで制御され、通知が入れば首を振るだけで視野の右上にぼんやりと画面が投影されて確認でき、終われば勝手に画面が消えている…といった形のUXは、通知→ポケットから取り出して起動→情報を確認→終了する、といったような一般的な携帯電話が提供するものとは全く違い、当然アプリにもこれまでとは全く違うUXが求められます。…この辺りはもう何回も書いているわけなのですが ;)


    しかし、これの上で動作するアプリを作ろうにもエミュレータは公式にはなく、実機を用意しようにも入手経路や費用面でいろいろと苦労させられるのが現状です。いろいろ考えた末、Nexus 5を使用してGlasswareを(ギリギリ)プロトタイプできるような感触を得たので、今回はそれについて書かせてもらえたらと思います。ふわふわした話になってしまう可能性がありますが、その辺はなにとぞよろしくお願いいたします m(__)m


    最初に断わっておきますが、これはあくまでも私が研究に携わった中で得た一つの知見としてとらえていただければ幸いです!

    ここで挙げる方法が常に最善なはずはありませんし、そうでない場合を自分もいくつか経験しています。


    Nexus 5?

    素のAndroid 4.4(XE16以降がベースにしているバージョン)が動く、比較的手軽なデバイスだからです。今回はAndroidベースとはいえ違うシステムで動作させるものをプロトタイプしようとしているので「素の」というところがかなり重要になります。一方でハードウェアスペック的にはGoogle GlassはどちらかというとNexus Sに似ているので、ひょっとするとCyanogenMod 11をNexus Sで動かした方が適当な場合もあるかもしれません。


    ワークフロー

    基本的には適当なエミュレーションレイヤーを挟み込み、共通項の多いActivityを中心にモデリングを進め、そして一通り片付いたらGlassへポートする、という段階的なアプローチがある程度有効です。


    モデリング

    だいたい以下のような感じにGlass固有のAPIをモックするようなレイヤーを挿入します。


    LiveCard→Ongoing Notification

    GlasswareではServiceLiveCardを組み合わせるケースが一般的ですが、これはServiceNotification、あるいはWidgetRemoteViewsでエミュレートするのが良いのではないかと思います。


    だいたいこのように書かれるところ:


    これをAndroidのNotificationで動作させるためのエミュレーションレイヤーはこのような感じに:


    Mirror API→GCM+Notification?

    同様に、Mirror APIGoogle Nowで…としたいのですが、残念ながら今のところGoogle Nowに独自カードを提示させることはできません。そのため、現在のところはGoogle Cloud Messaging (GCM)などを使用してリモートでNotificationを飛ばせるようなサービスをどこかに立て、それを使うことでエミュレートするほかにはなさそうです。


    このようなサービスの書き方ですが、とりあえずGoGoogle App Engineを使用してこのような形に書くことができます(注: 最新のGoogle Cloud SDKでは多少変わっているかもしれません。)


    まずapp.yamlから。


    ありがたいことにGoにもGCM関係をハンドリングしてくれる gcm というライブラリがあり、ここではそれを使用させてもらうことにします。普通に開発環境で動かすにはgoapp経由でインストールするだけで良いのですが、このままだとGoogle App Engineへ展開した際に漏れてしまうので適当に作業ディレクトリへコピーしておきます。



    ロジックの実装ですが、reflector/reflector.goとして、以下のように書いておきます。GCM関連の処理はライブラリで行なうので、ここではデバイスの登録を受けつけてDatastoreに書いていたり拡散したいパラメータをライブラリに渡しているくらいなもので実にシンプルなものです。


    これを、以下のようにまとめて適当にGoogle App Engineへ展開しておきます。



    これでサーバ環境の準備は完了です。これでAndroid端末を http://your-application-id-goes-here.appspot.com/device へregid=…としてPOSTすることで登録ができ、その後適当に http://your-application-id-goes-here.appspot.com/ へmessage=….という形のデータをPOSTすることで外から通知を行なうことができるようになりました。


    あとはこれを端末で適当に受けてNotificationなど出すことで、外部からnon-obtrusiveな通知を送るためにMirror APIを使用しているような場合についてはかなり手荒ながらエミュレートができたかな、と思います。


    この例では通知対象を限定すらしていないので通知すると全端末に飛んでしまいます。とはいえテスト用途でとりわけ小規模な使い方をしている限りあまり問題にならないかと思いますが…



    GestureDetector→エミュレート


    次です。さて、GestureDetectorはAndroid SDKにもあるのですが、Glasswareの場合GDK特有のGestureDetectorを使用する必要があります(さもないと検出できない)。次のようなコードがあったとします。


    Glass:


    上のコードをAndroidで動作させるために必要なエミュレーションレイヤーはだいたい次のような形になります。実質的な検出ロジックにおいては実装を割愛していますが、こちらはAndroid SDKで普通に検出する場合とほぼ同等の実装になるのではないかと思います:



    GDKのGestureクラスは単なるenumであり、こちらも当然Android SDKとは互換性がないのでこちらも定義しておきます。



    最後にActivityレイヤーですべてのMotionEventを解析するようにします。



    これで最初に挙げたGoogle Glass用のコードが動作するはずです。


    GCM→Standalone GCM

    GlassはGoogle Play Servicesを持っていないので、GCMを使用する場合にはStandalone版を使用することになります。Standalone版はAndroidでも特に問題なく使えるので、こちらを使用しておけばそのままGlassで動作させることができます。


    Card→LayoutInflater

    Cardはパラメータを受けとってGlass標準のレイアウトを作成するヘルパー的な役目をしていますので、簡単なものであればLayoutInflaterを使用して適当なカスタムレイアウトをロードさせるようにするのが適当でしょう。


    Glass:


    このようなコードがある場合、Androidでは以下のようにエミュレーションを行なうことになるでしょう。この例ではaddImageなどのメソッドは定義していませんが、もっと複雑な例では必要に応じて追加することになると思います。


    メニュー

    無理にカスタム設計するよりも、透明ActivityOption Menuによるシステム標準のエミュレーション機構に頼るのが最善です。ただ、これをそのままAndroidで動かすと見かけがかなり違ってきてしまいますが…


    Glass:


    メニューを起動するための透明Activityについては以下のようになります。



    VoiceTrigger関連


    メタデータはそのままでOKですが、クラス参照は次のような形でスタブ化しておく必要があります。



    当然これだけではボイスコマンドを聞いてくれませんので、ボイスコマンドに対応するServiceをandroid.intent.action.MAIN/android.intent.category.LAUNCHERから別に起動できるようにするようにしておきます。


    また、Tasker/AutoVoiceなどを併用することでボイスコマンドを使用して起動させることが可能になります。

    ※詳細な方法はlifehackerの記事によくまとまっているのでそちらをご参照ください :)


    ポーティング

    エミュレーションレイヤーを外して、非互換性があるようなら適当に直します。この際、アプリ自体が単純だったりレイヤーの設計がうまく行っていれば特にそれほど問題になることはないのですが、実際のポーティングでは以下のようなところが問題になりやすい感じがします。


    OpenGL ES 2.0

    Glassが搭載しているGPUはNexus Sと同じSGX540なので、Nexus 5とはかなり違います。このためシェーダーのコンパイルに失敗したりすることがあるので、このような場合はNexus S+CyanogenMod 11あたりで動作を確認するのが良いでしょう。


    発熱

    GlassのCPU自体はNexus Sと同等なのですが、フォームファクタが違いすぎるので無理をさせてしまうとすぐに高温になります。高温な状態になると”ok, glass”と交互に”Glass must cool down to run smoothly.”というメッセージが表示されてくるので注意しましょう。


    image-0


    まとめ

    Google GlassとAndroid携帯端末はとても良く似ています。基本的にフロント面から遠くなればなるだけ共通項が増えてくるようなイメージを少しでも伝えられたでしょうか。ここに挙げた差分は自分で研究に参加している時にたまたま当たったものだけでありますが、大まかなところではこのくらいではないかと思います。懸念通りふわふわしたエントリになってしまいましたが、もしGoogle Glassで開発をしたくなったときこれが開発効率向上の役に立つことを祈ります。

    TAGS: ,

    RELEASE
    2014.09.01

    O2O/IoT/Wearable時代におけるWeb以外のネットワーク技術(MQTT/BluetoothLE)について、YAPC::Asia Tokyo 2014で発表してきました


    7月からラボにジョインした加藤(lyokato)です。


    YAPC::Asia Tokyo 2014 一日目(29日)にて 「O2O/IoT/Wearable時代におけるWeb以外のネットワーク技術」というタイトルで発表させていただきました。


    IoTとO2O、それぞれの分野で最近注目を集めているMQTTとBluetooth LEについての内容になります。


    まずMQTTについてですが、MQTTがどんなものか、近い機能の分野で名前をよく見かける他のプロトコルとどう違うのかという話を、

    次に、Bluetooth LEとはどんなものか、iBeaconでどのように利用されているのか、WebやWearableとどう連動していくのかという話をさせて頂きました。



    発表資料はこちらです。



    自分自身、無線通信技術をずっとやってきたわけでもなければ、machine to machineのような業界でやってきたわけでもなく、つい最近になってこの分野に興味を持ち勉強しはじめたばかりの初学者にすぎません。

    自分と同様に、この分野に興味を持ち始めたWebやネイティブアプリのエンジニアが手をつけるとっかかりになればよいなと思います。


    スタッフを始めとする関係者の皆様、お疲れ様でした&ありがとうございました!