Elaboration in, Garbage out

Twitt*r ではメモできない何かそれ的なモノ・コトを

javascript 初心者が react に触ってみる。その 2(React 成分 1 割)

前回までやったこと

gre.hatenablog.com

前回何も考えず文章書いていたら、完全に自分用のメモになっちゃってますね。

今回の範囲

今回はそうならないように気をつけて行ったら、半分以上 React ではなくなってしまいました。

  • React の開発用にエディタ (Atom) を整備
  • react のチュートリアルを JSX → JS の変換を Production 環境さながらにやってみよう!
    • そしたらいろいろ調べないと理解できないぞっていう。ES6 (EcmaScript) とか、CommonJS とか。
    • あとは uglifyjs で圧縮かけて、gulp で自動で JSX -> JS の変換をがんばるぞ。

ここまでいけば、他人に渡すときには package.json と gulpfile.js、.babelrc を渡してセッティングしてもらうだけですね、という状態になる。まー boilerplate の作成はまだ早いかなー。

で、予想以上に長くなってしまった。javascript 覚えることおおい。

エディター整備

atom を使っているので、javascript 関連の Atom のパッケージを入れていきます。だいたい次の記事に書いてます。

あと、時代は JSLint ではなく ESLint らしい。

開発したコードをブラウザに読み込ませるまで

まえがき

注意:長いです。はい。ここまで長くなるとは思わなかった。

Babel を使う

Babel って何者さ

React で JSX(JavaScript Xml)を使っているので、それを babel というツールjavascript のコードにする。Facebook が最近 Reactify というツールではなく babel を使うように推奨しているそうです。

Babel はもともと 6to5 (ECMAScript 6 -> 5 に変換する?)という名前だったらしく、そのプラグイとして JSX から javascript への変換も提供されているそうです。

ECMAScript の話(脱線)

ところで、React はんどーなってんのーっていうのが javascript 初心者にはよーくわからんかった。ただ、おじさんがIE8でReact.jsを使うために頑張った話 - ugon105の日記 を読む限り、es5-shim や html5-shiv というものを利用して IE8 対応させているので、おそらく React は HTML5 と ES5 で成り立っているのだろう、と邪推。本当は正攻法で調べるべきなんだろうけれども、まぁ一旦ここで切りあげ。

いろいろ調べると、ES6 の文法のほうが python プログラマ中の下の人にとっては書きやすそうだったので、一応参考となるリンクは調べた。

Babel の使い方

Babel はデフォルトでは(最近かわって)何もしない設定なので、どのような変換を行うかを指定する必要がある。 Plugins · Babel に変換の一覧があるので、npm でインストールして、/some/git/repos/.babelrc というファイルを作成して、そこでどのような変換をかますかを記述する。

  • Babel 自体のインストール
npm install -g babel
npm install babel-plugin-transform-react-jsx --save-dev
  • .babelrc ファイルの中身
{
  "plugins": ["transform-react-jsx"]
}
  • JSX -> JS に変換
babel ./project/static/scripts/jsx/example.jsx  | diff ./project/static/scripts/jsx/example.jsx -

差分を抜粋

<   render: function() {
<     return (
<       <div className="commentBox">
<         <h1>Comments</h1>
<         <CommentList />
<         <CommentForm />
<       </div>
---
>   render: function () {
>     return React.createElement(
>       'div',
>       { className: 'commentBox' },
>       React.createElement(
>         'h1',
>         null,
>         'Comments'
>       ),
>       React.createElement(CommentList, null),
>       React.createElement(CommentForm, null)

確かに JSX のほうが書きやすそう(小並感)

browserify を使う

こいつなにもの?

Browserify lets you require('modules') in the browser by bundling up all of your dependencies.

javascript はほとんどブラウザの中でしか動かないものでしたが、Node.js 登場以降はサーバサイドで動くようになったそうです(もちろんNode.js 以前にもサーバで機能する javascript は存在はしていた)。で、サーバサイド開発の中で CommonJS という javascript の方言みたいなものが登場(Lisp のなかの clojure みたいな感じでしょうか)。それがモジュール管理など便利になったんだけれどもブラウザさんは「おまえのゆーとることはよーわからん」と。ブラウザさんに解釈可能なように変換するために、browserify (ブラウザ(Browser)-化(ify))ということなんでしょうか。その 1 では単語だけ出しましたが、ようやく理解しました。

このへんの詳しい説明は JavaScriptのモジュール管理(CommonJSとかAMDとかBrowserifyとかwebpack) | tsuchikazu blog などなど、調べたらいっぱい出てくるので割愛。

使い方

まずは browserify を入手します。

npm install browserify --save-dev

先ほど JSX から JS に変換したコードを browserify に渡してあげます。

babel /path/to/example.jsx  | $(npm bin)/browserify - > /path/to/example.js

これでブラウザがやっと認識して、ちゃんと文字も表示できるようになりました。

ちなみに、browserify には、 -t オプションで変換をかました後に browserify を行うという機能もあり、 他のブログの多くはこっちで行っている。でもこっちほうが最初はわかりやすいかなー(個人的に)。

休憩

いったんここで HTML に上述の example.js を読み込ませます。すると、

[BABEL] Note: The code generator has deoptimised the styling of "http://localhost:5000/static/scripts/js/example.js" as it exceeds the max of "100KB".

というエラーがでてきました。ファイルおっきすぎるでーっていう警告ですね。ファイルを小さくしろと怒られています。

uglifyjs で圧縮かけるよ

uglify は「醜くする」という意味(つまり、難読化をするようなライブラリに見えるの)ですが、圧縮オプションがあり、ファイルを小さくすることも可能のようです。React 界隈ではこれが使われているみたい?。早速インストール。

npm install uglify-js --save-dev

で、圧縮をかけます。-c オプション(Compression) で圧縮されます。パイプラインをつなぎこむと読みにくいので、先ほど出力をしたファイルを使います。

$(npm bin)/uglifyjs /path/to/example.js -c > /path/to/example_uglified.js

比較をすると、半分ぐらいになっていることがわかります。

drwxr-xr-x  5 nya  nya     170 11 22 16:28 .
drwxr-xr-x  5 nya  nya     170 11 11 19:26 ..
-rw-r--r--  1 nya  nya  668115 11 22 15:53 example.js
-rw-r--r--  1 nya  nya  335178 11 22 16:28 example_uglified.js

ちなみに、これでも先ほどの「ファイルおっきすぎやで」という警告はでます。React がおっきいのかね。

gulp を使うよ

ばっくりと gulp の説明

そろそろ、このあたりから一回一回コマンドうって変換するの面倒やわーってなります。 一連の面倒なコマンドを一度にびゃびゃっと実行してくれるツールが有ります。grunt というものもありますが、GitHub でのスター数が gulp (17,624) > grunt (10,205) *1 ですし、Google Trend みても Grunt は縮小傾向なので、gulp にします。

f:id:huacha:20151122170026p:plain

設定と使い方

まずはインストールから。私はグローバル(-g)でも入れましたが、($(npm bin)/gulp で使えますし)別に入れなくてもいい気がします。もちろんローカル側には必要です。

npm install -g gulp 
npm install gulp --save-dev

その後、gulp の設定ファイル(gulpfile.js)を作ります。

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require("vinyl-source-stream");
var uglify = require('gulp-uglify');
var buffer = require('vinyl-buffer');

gulp.task('transform', function () {
  browserify('./path/to/example.jsx', {transform: ['babelify']})
    .bundle()
    .on("error", function (err) { console.log("Error : " + err.message); })
    .pipe(source('example.js'))
    .pipe(buffer())
    .pipe(uglify({ preserveComments: 'license',
                   compress: true}))
    .pipe(gulp.dest('./path/to/output/'));
});

gulp.task('default', ['transform']);

これに必要なモジュールも一式インストールします。

npm install --save-dev gulp-uglify vinyl-buffer vinyl-source-stream

ちなみにこの gulpfile.js もすっげぇ苦労しましたが、次のリンクが参考になりました。

とりあえず、イケてない感がすごいです。初心者にパイプライン的な実行で型を意識しろってのは無茶では。

で、gulp コマンドだけで実行できるようになります。

じゃあ開発するぞ!

……jsx 書き換えるたびに gulp コマンドを叩くのもなーというめんどくさがりが世の中にいるようで、ソースコードの差分が出てきたたびに、gulp の一連のタスクを実行するようにした人がいます。ここまでくれば、なんか gulp 使っててよかった、という感じがする(LaTeX にも同じようなものないのかな、と思うぐらい)。参考はこちら。 * gulp-watch * これからはじめるGulp(3):gulp.watchでファイルの変更を監視しタスクを実行する | Webデザイン、フロントエンド系の技術に関する備忘録 - whiskers

変更内容は至って簡単。

gulp.task('watch', function(){
  gulp.watch('./path/to/*.jsx', ['transform']);
});

以上。あとは、gulp watch というコマンドを打つだけ。チョー簡単。ただし、変更してもエラーが出た時しか、変更ファイルが出ない(ただ、エラーしても終了しないところは良い)。

$ gulp watch
[18:14:06] Using gulpfile ~/devel/python/react-tutorial/react-offcial-tutorial/gulpfile.js
[18:14:06] Starting 'watch'...
[18:14:06] Finished 'watch' after 14 ms
[18:14:09] Starting 'transform'...
[18:14:09] Finished 'transform' after 30 ms
[18:15:30] Starting 'transform'...
[18:15:30] Finished 'transform' after 20 ms
Error : /path/to/example.jsx: Unexpected token (51:2) while parsing file: /path/to/example.jsx

これもなんとかしたい場合は、watch の部分をもうちょっと追記して、最終的に次のようにする。

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require("vinyl-source-stream");
var uglify = require('gulp-uglify');
var buffer = require('vinyl-buffer');

gulp.task('transform', function () {
  browserify('./path/to/example.jsx', {transform: ['babelify']})
    .bundle()
    .on("error", function (err) { console.log("Error : " + err.message); })
    .pipe(source('example.js'))
    .pipe(buffer())
    .pipe(uglify({ preserveComments: 'license',
                   compress: true}))
    .pipe(gulp.dest('./path/to/output/'));
});

gulp.task('watch', ['transform'], function(){
  var watcher = gulp.watch('./path/to/*.jsx', ['transform']);
  watcher.on('change', function(event) {
    console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
  });
});

gulp.task('default', ['transform']);

ここまで準備できて、さー React 触るぞー!となりました((差分ビルドなるものが watchfy でできるらしいが、コンパイルがすぐ終わるし、そこまでしなくていいなかなーと、今回は無視しました。LaTeX のビルドで 1 分かかるとかありますし。))。CommonJS とか ES6 とかいろいろ javascript さんいろいろありすぎやん。

*1:2015/11/22 17:00 JST 時点

javascript 初心者が React に触ってみる。その 1

前回いろいろ調べて riot.js とか言ってましたが、結局 React に落ち着きました。もちろん React Native があったからですねはい。多分続きます。

とりあえずチュートリアル

facebook.github.io

これを触ってみて、あれーうごかねーと思っていたら、JSX (JavaScript Xml)を使っているからですね。 ようは javascript 内で XML でかけるようにすることで可読性をあげるっていうやつです。YAML でええやん javascript 内のコードに XML で放置されたままので、javascript に変換しないといけないのですね。

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>React Tutorial</title>
    <!-- <script src="https://fb.me/react-0.14.0.js"></script>
    <script src="https://fb.me/react-dom-0.14.0.js"></script> -->
    <script src="{{ url_for('static', filename='bower_components/react/react.js') }}"></script>
    <script src="{{ url_for('static', filename='bower_components/react/react-dom.js') }}"></script>
    <script src="{{ url_for('static', filename='bower_components/babel/browser.min.js') }}"></script>
    <script src="{{ url_for('static', filename='bower_components/jquery/dist/jquery.min.js') }}"></script>
    <script src="{{ url_for('static', filename='bower_components/marked/marked.min.js') }}"></script>
    <script src="https://fb.me/JSXTransformer-0.13.0.js"></script>

  </head>
  <body>
    <div id="content"></div>
    <script type="text/jsx"
      src="{{ url_for('static', filename='scripts/jsx/example.js') }}">
    </script>
  </body>
</html>

はい、何故か中途半端に flask 使っています。あと React は 0.14.2 を使っています。これで動きました。ただしこの場合、JSXTransformer から次のような警告がでます。

You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx

クライアント側の CPU に負荷をかける事になるので、商用ではやめましょうね、っていうことですね。JSXTransformer だけ外から引っ張ってきてるのが気持ち悪いけれども、まあ触るだけですし。いざとなればデバッグ時だけこれを読み込むようにして jsx の部分を変数にしたげれば(略)

無理やり python を使いたくて

チュートリアルのコード(reactjs/react-tutorial · GitHub)を読んでいたら、サーバサイド側に flask の例があるじゃないですか、っていうことで flask+python の例をいろいろ調べてました。

realpython.com

これを読んでいたら、bower? browserify? gulp? なんじゃそりゃってなりました。次のリンクを読んだらなんとなくわかりました。

qiita.com liginc.co.jp

  • bower はクライアントサイドの javascript パッケージマネージャ位置づけにしておいて *1
  • npm(node.js)は react の開発で諸々必要(Production 環境用に babel で JSX -> JS にプリコンパイルとか、圧縮とか)、
  • gulp はタスクランナー(例えば JSX -> JS -> 圧縮? など)として必要

予告編

javascript の中身よりも、周辺のものを覚える量多い気がします。react が 14 になってから?いろいろ変わっているそうなので、変更部分が何なのかを調べてみます。

参考になりそうなところ

*1:パッケージマネージャは npm にまかれていく予定らしい?

Python mini Hack-a-thon #58 にでて地図上の可視化を頑張ってました

なりゆき

参加 2 回目です。前回は EDINET から有価証券報告書XMLのなかにHTML)を頑張ってスクレイピングしようとしたけど挫折したので、今回はスクレイピングいらずのものを探して、地図の可視化を選びました。

参考にしたページ

qiita.com sinhrks.hatenablog.com

使ったオープンデータ

  1. 国土数値情報ダウンロードサービス
    • 国土数値情報ダウンロードサービスからダウンロードできます。selenium で自動化出来そう。
  2. 地価公示・地価調査・取引価格情報 | 土地総合情報システム | 国土交通省
    • 不動産取引価格をダウンロード。自動化はひじょーーーに簡単。

使ったライブラリ

github.com

Leaflet.js を使って、地図上に d3.js を使って可視化を行うライブラリです。デフォルトで Open Street Map を使うので google 嫌い病の人でも安心して使えます。

API Doc が無いとか、ipython notebook で描画する用の initialize_notebook という関数が動かないとかいろいろ突っ込みどころはありますが、それを差し置いても便利なライブラリでした。

コード

github に公開しました。 github.com

が、github だと iframe で読み込むはずの html までは表示されないのでわかりづらいですが、次のような感じで表示されます。

f:id:huacha:20151107232953p:plain

なかなか、使えそうです。

Web 開発しないといけなくてざっくり調べた

最近

運用対応からデータプラットフォーム系の開発(NW から既存アルゴリズムの応用まで)すべてワンマン運転でやっている気がしてならない私です。事件が起きて更につらみアップ。そんな中で Web 開発まで着手しないといけないので、とにかく軽量そうなライブラリ・フレームワークはないかと調べていました。

想定している用途

  • 社内で使うシステムなので Search Engine Optimization どうでもいい
  • 見てくれはごっそり作り変える可能性はあるので、とにかくミニマムにしたい。
  • かっこよさげなデザインがいいなー。
  • データを引っ張ってくる API はがっつり考えないといけない。

構成

ざっくり

  1. データを引っ張ってくる Rest な API をつくる
    • データの可視化さえ json で図を渡す
  2. javascriptAPI たたく
  3. なんかの CSS のライブラリで綺麗に表示

クライアントは将来どうなるかわからんので REST な API を叩きまくる、というふうにしております。 PyConJP にエア参加していて聞いた情報(おそらく次の講演のところ)。

www.slideshare.net

サーバサイドの API

  • pandas とかでいろいろデータを操作するので python がやっぱり良い。
  • Flask-RESTful が一番簡単そう。

github.com

Flask-RESTful は tomchristie/django-rest-framework · GitHub の規模と比べるとやや不安ではあるけれども、粛々と開発しているし、どうせ半年後には大規模になっても耐えられるものを〜っていうことで作り変えそうなので、まあ良いでしょうという。

また、データの可視化も図を json で渡すという謎なことができそう。実態は、matplotlib での図を mpld3 というライブラリ経由で d3.js のグラフにできる、かも。参考は次の2つ。

github.com stackoverflow.com

bokeh がもっと安定していればいいんだけどな〜。

javascriptフレームワーク

フロントエンドを触ったことが無いため、すっげぇ時間がかかった。とりあえず、今は戦国時代だということがわかった。

Polymer を採用することは当分なし。Angular は独特だということがよくわかっていてこれもなし。React は最後まで有力候補だったんだけれども、次の2つの記事を読んで、最終的に riot.js に落ち着きました。

CSS のはなし

イラレで制作したことは多少はあるけれども、既存のものを有効活用したい。Bootstrap, Foundation が主流で、Material Design が急上昇といったところでしょうか。

tech.eversense.co.jp

調べていて思ったこと(参考)

他にも入り口となる情報はいっぱいアルみたいですね。

blog.mmmcorp.co.jp

iphone 6s + ガラケー 2 台持ちってどうなの、を予約した後に比較した。

成り行き

iphone 5 を 2.5 年間使っていたもの…。なので iphone 6s (SIM Free) を予約した。でも電話カケホーダイにしたいし〜どうするよっていうことで。

本題

厳密な比較はこちら

【こんなに違った!】SIMフリーiPhone6sと格安SIMの運用について比較検討してみたぞ! | むねさだブログ iPhone 6s/6s Plus 価格まとめ SoftBank ドコモ au【更新中】 | iPhone6s/7の予約!発売日近くに在庫確保する方法【softbank ドコモ au】

このサイトが詳しいので、厳密な比較はこちらにお任せ。

比較の目的

問題はカケホーダイを追加してもペイするかどうか。 料金自体は雑に(有効数字 1〜2 桁あればいいでしょというノリで)やっているので、税込みなどかっちり行いたい方は自分でやってください。

前提

  • iPhone
    • 6s 64GB (99,800 円+ Apple Care 14,800 円)
    • SIM カードは OCN Mobile One (3GB/月のプラン 1744 円想定、OCN光モバイル割適用後:ここ重要)。
  • au ガラケー
    • カケホーダイプラン+Email(多少の通信料込 2600 円想定)
    • auガラケーは白 ROM 端末を買う(ここ重要、一応店員さんに確認した)
    • 事務手数料込みでイニシャル 11,000 円の想定

の二台持ち構成。比較対象は

  • auiPhone 6s 64GB に機種変更
  •  カケホデジラなんちゃら(データ 3GB)で端末代 24 回払いで月額 9,450 円。たけーー。

比較相手は au で機種変更した場合のお値段。諸事情で au にしないといけないのです。のです。

累積金額の比較

bokeh がいいぐらいに補助線を引いてくれないのでスタートを jul.2015 にしています。

f:id:huacha:20150912174307p:plain

二台持ちだと、2 年間使うと一緒のよう。まじか。これを 5GB プランに変更すると

f:id:huacha:20150912174301p:plain

微妙。ちなみに、ガラケーは白 ROM 端末購入ではなく au で契約して買うと、だいぶ高くなってしまいますね。

で、これでいいんだっけ

  • 白 ROM 端末を安く手に入れる
  • ガラケーのほうで通信料をかかんないようにする
  • ガラケーを電話専用にするっていう手間

という難点はあるけれども

  • 地下で電波が繋がりにくい時のための docomo/au の冗長構成
  • iPhone が SIM フリーになる

というメリットを考えると、やっぱり 2 台持ちがいいなーという結論になりました。

VPC で簡単に CI をしたくて drone いれた。

いきさつ

ansible の serverspec 書きたくなって、でも諸事情で Magnum CI ですらダメ というイケてない環境で秘伝のソース(Jenkins おじちゃん)を育てるのも面倒だったので drone(+Docker)始めました。秘伝のソースは Hidden Sources というそうな。

構成

  • Nginx
    • Nginx の Reverse Proxy 経由で gitlab と drone にアクセス。
    • Global IP を持ってる。Gitlab や drone への外界からのアクセスは基本的にはこの子経由。
  • Drone
    • OS は CentOS 7
      • 何もせずに yum install docker で docker 始められるという初期コストの低さは ss とか systemctl とかどうでも良くなるぐらい、良い。
      • yum install golang も同様。
    • drone の推奨は ubuntu ですが今のところ問題なし。
    • NetworkManager をとめている。/var/log/message がえらいことになるので。
    • Local IP は 192.168.0.110 だという想定
  • Gitlab
    • 社内のプログラムを外に出してはいけませんルールですので。
    • もちろん Community Edition.
    • omnibus-gitlab でらくらくインストール
    • Local IP は 192.168.0.111 だという想定

Installation

そのうち ansible で書く。

docker Installation

  • yum install dokcer
  • systemctl start docker
  • systemctl enable docker

以上。あとは初期設定のまま。

drone の installation

公式サイトによると

wget downloads.drone.io/master/drone.rpm
sudo yum localinstall drone.rpm

で OK らしいんだが、なぜか設定ファイルをうまく認識しなかったり、 よくわかんないエラーが出たので、次のリンク参考に goalng をインストールした後 github から直接インストールした。

blog.takus.me

CentOS7 の場合は何もせずyum install golang でインストール。GOPATH などなどの Golang の設定後は

  • cd /path/to/GOPATH/src
  • git clone https://github.com/drone/drone.git
  • make deps
  • make && make test && make install

でインストールできますた。Golang 覚えたい。

Gitlab と Drone の設定

ここ http://readme.drone.io/setup/config/gitlab/ を参考に gitlab の設定を行う。 * Admin Panel > Applications > New Application * Name: Drone * URI: https://path.to.your.drone/api/auth/gitlab.com で、accesss key と secret key が出てくるので、 /etc/drone/drone.toml もしくは好きな場所に drone.toml を配置して次の設定を書く。 元ネタは https://github.com/drone/drone/blob/master/packaging/root/etc/drone/drone.toml にある。

[server]
port=":8000"

[gitlab]
url = "https://gitlab.your.domain"
client = "c0aaff74c060ff4a950d"
secret = "1ac1eae5ff1b490892f5546f837f306265032412"
skip_verify=false
open=false

# Above keys are imitation ones written at http://readme.drone.io/setup/config/gitlab/

[database]
driver="sqlite3"
datasource="/var/lib/drone.sqlite"

[worker]
nodes=[
  "unix:///var/run/docker.sock",
  "unix:///var/run/docker.sock"
]
  • データベースの設定は MySQL, PostgreSQL でもいけるらしい。
  • Node を単純に羅列すればその分ガーッと増やせるみたい。 ちなみに docker の設定を変えれば
[worker]
nodes=[
  "tcp://127.0.0.1:2375",
]

でも可能。試してないけど dokcer ノードをわーっと増やしてつなげることもできるかも (cf. http://readme.drone.io/setup/config/workers/)。 で、droned とか nohup droned & などで droned を実行すると 8000 番でアクセスできるようになる。

Nginx の設定

こちらは公式サイト(http://readme.drone.io/setup/misc/nginx/)をそのままコピー。drone の Local IP は 192.168.0.110 だとする。

location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_set_header Origin "";

    proxy_pass http://192.168.0.110:8000;
    proxy_redirect off;
}

location /api/stream {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_set_header Origin "";

    proxy_pass http://192.168.0.110:8000;
    proxy_redirect off;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

docker Image をやっつけで作る

drone の作者側でいっぱい用意されているみたい。

github.com

ただ、CentOS もないし、ansible も動かせるようにする必要があった。 とりあえず dokcer になれるという意味で手作業でやりました、が、じきに Dockerfile 作る。

とりあえずやっつけで作る想定で、 docker run -i -t centos:centos6 /bin/bash で CentOS6 を動かす。

Gitlab から clone 出来ない問題

docker.toml

[gitlab]
url = "https://gitlab.your.domain"

と設定すると、drone が docker コンテナ内で SSH で gitlab.your.domain にアクセス してしまう。結果、DNS で名前解決して受け取る IP アドレスは Nginx のサーバになってしまう。DNS で名前解決させずにローカルに指定してあげればいいので、/etc/ssh/ssh_config に 次のような感じでVPC 内の Local IP を指定したげる。/etc/hosts だと、OAuth の関係でダメかもしんない。

Host gitlab.your.domain
  HostName 192.168.0.111
  Port 10022

tty 問題

ansible をローカルで動かしたら sudo: sorry, you must have a tty to run sudo と 怒られた。まあ CI のワーカー内だし、なぜか ssh でのリモート操作だとこれに引っかからないから docker イメージは設定ゆるゆるにしておきました。最低限はこちら

# diff /etc/sudoers /etc/sudoers.bak_20150712
56c56
< #Defaults    requiretty
---
> Defaults    requiretty

image に登録

作業したあとは Ctrl-p Ctrl-q で脱出して、イメージを作成

  • docker commit -m "docker image message" -a "your_name" happy_your_container your_repos/image_name

動いているコンテナをすべてとめるなら、

  • dokcer ps -a -q | xargs -I {} docker stop {}

あと削除するのであれば、dokcer ps -a で出てくる ID ひっぱってきて docker rm CONTAINERID とすれば OK。

リポジトリ.drone.yml を入れる

レポジトリのトップディレクトリに次のような .drone.yml を入れることで、 drone がこれを読み取って実行してくれる。

image: your_repos/image_name

script:
  - echo "start!"
  - ansible-playbook path/to/playbook.yml -i path/to/inventory -c local
  - echo "end!"

で、結果

f:id:huacha:20150712135710p:plain

これで「ここダメなんだなー」っていうのがよくわかるようになった(しろめ)。

かんたんに可視化をしたくて三千里(一里目)

やりたいこと

なんか ElasticSearch + Kibana で「わたしたちが考えたもっともかんたんなかしか」みたいなことができるらしいが、Hadoop User Experience (HUE)でもできるたい。

gethue.com

これ見た時には、すげーー!!!! もしかしたら IBM の Many Eyes も目じゃねーよ!って思って、とりあえずやってみようと決意しました。

installation(途中)

環境

  • cloudn の FLAT タイプ
  • CentOS 6.5
  • ansible は少々おまちください。

途中経過

これをやるためには cloudera(少なくともHUE の主要開発者トップ 2 が cloudera の人)に体と魂を売らなければならない、もとい、cloudera のパッケージを使わなければいけないっぽい。それですっげー苦労した。

gethue.com

とっかかりとなる Documents となるのはこのぐらい。とっかかりがあるだけましか。あとは solr と hue を動かせるようにしよう、ってところなんだけれども、これも辛い。とりあえず、 cloudera search という名の solr-serverhue さえ入れられれば(一番最初の URL が書いているように)動く、という希望をもとにとりあえず solr-server を動かすところまでできた。

HUE のインストール

Github の hue のページを見ると、cloudera のレポジトリを用意しなくともインストールできる感が満載。だが、できなかった←

仕方ないので cloudera のレポジトリを使います。http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_cdh5_install.html を参考にとりあえず最新のレポジトリを使う。

sudo yum clean all
curl -O http://archive.cloudera.com/cdh5/one-click-install/redhat/6/x86_64/cloudera-cdh-5-0.x86_64.rpm
sudo yum --nogpgcheck localinstall cloudera-cdh-5-0.x86_64.rpm

で、HUE のインストール・立ち上げ

sudo yum install hue hue-server
sudo service hue start

なんか余計なものまでけっこー入っている気がする、けどまあいいやっていうことで。これで port 8888 番でアクセスすれば HUE の画面が出るはず。あと画面のなかでの初期設定で Google Analytics に匿名データ渡しますよ、っていうチェックがあるのでそれは外す。

cloudera search という名の solr-server のインストール

sudo yum install solr-server

でインストールは可能。だがしかし sudo service solr-server と solr を動かそうとすると /var/log/solr/solr.out

log4j:ERROR Could not read configuration file from URL [file:/etc/solr/conf/log4j.properties].
java.io.FileNotFoundException: /etc/solr/conf/log4j.properties (No such file or directory)

というエラーを吐きつつ動かない。レポジトリでインストールするのにそこら辺の初期設定はおいてくれないのか・・・ということで、solr のデフォルト(https://github.com/apache/lucene-solr/blob/lucene_solr_4_10/solr/example/resources/log4j.properties)から取ってくる。

これでいけるだろーとおもいきや、同じく /var/log/solr/solr.out

31330 [main] ERROR org.apache.curator.ConnectionState  ? Connection timed out for connection string (localhost:2181) and timeout (15000) / elapsed (31150)
org.apache.curator.CuratorConnectionLossException: KeeperErrorCode = ConnectionLoss
        at org.apache.curator.ConnectionState.checkTimeouts(ConnectionState.java:197)
        at org.apache.curator.ConnectionState.getZooKeeper(ConnectionState.java:87)
        at org.apache.curator.CuratorZookeeperClient.getZooKeeper(CuratorZookeeperClient.java:115)
        at org.apache.curator.utils.EnsurePath$InitialHelper$1.call(EnsurePath.java:148)

(後略)

というエラーが。デフォルトで ZooKeeper 上で動かすようになっているらしい。Solr ってそーだっけー(実は使ったことがない)。とりあえず Stand-alone 構成で ZooKeeper で動かせるように ZooKeeper をインストール。

sudo yum install zookeeper-server
sudo service zookeeper-server start

これだけでも動かないようでなんでだーと思ったんだが、zookeeper が入っただけで solr の初期設定をしないといけないらしい。というわけで

solrctl init --force

を実行。恐らくは zookeeper を入れたあとに solr いれたげればオプション --force はいらないかもしれない。

で、service solr-server start で実行すると、例の solr の画面が見れました。 疲れたー。