Wercker からマイグレーションせよというメールが来たので対応してみた
CI サービスの Wercker からマイグレーションせよという以下のメールが来た。
Attention: Manual Migration required on your Wercker Account
Hi Mallowlabs,
We informed you a couple of months ago that we're going to start deprecating our non-Docker (or classic) stack in the future.
Since you have projects on our classic stack, we are pleased to announce that the time has come.
Non Docker-based applications will require a manual effort to migrate please follow this link to our stack migration wizard to start the process.
...
今回、このマイグレーションに対応した記録を共有する。
まずは https://app.wercker.com/applications/migrate にアクセスする。
Heroku deploy targets を使っているのがまずいらしい。
該当アプリの Deploys から edit をクリックする。
Delete Target をクリックして、Deploy Target を削除する。
もう一度 https://app.wercker.com/applications/migrate にアクセスすると、以下のような表示になるのでチェックを入れて、Migrate をクリックする。
アプリの Workflows タブから Add new pipeline をクリックする。
Name に heroku-deploy、YML Pipeline name に deploy を入力して Create をクリックする。
環境変数を設定する画面に遷移するので、以下の3つを入力する。
- HEROKU_APP_NAME
- HEROKU_USER
- HEROKU_KEY
Workflows タブに戻って build の後ろに heroku-deploy Pipeline を追加する。
ここでやっとソースを変更する。
diff --git a/config/mongoid.yml b/config/mongoid.yml index ccd80db..b658599 100644 --- a/config/mongoid.yml +++ b/config/mongoid.yml @@ -3,7 +3,7 @@ development: database: asakusa_satellite_development test: - host: <%= ENV['WERCKER_MONGODB_HOST'] || 'localhost' %> + host: <%= ENV['MONGO_PORT_27017_TCP_ADDR'] || 'localhost' %> database: asakusa_satellite_test production: diff --git a/wercker.yml b/wercker.yml index 0ce7ab5..80c1a0b 100644 --- a/wercker.yml +++ b/wercker.yml @@ -1,6 +1,6 @@ -box: wercker/rvm +box: ruby:2.3 services: - - wercker/mongodb + - id: mongo build: steps: - bundle-install @@ -19,3 +19,10 @@ build: after-steps: - mzp/http-notify: url: $DASHBOZU_URL +deploy: + steps: + - heroku-deploy: + key: $HEROKU_KEY + user: $HEROKU_USER + app-name: $HEROKU_APP_NAME
ポイントとしては以下の通り。
- box を指定したところは Docker コンテナを指定するようにする
- MongoDB などの services も Docker になるのでホスト名等を工夫する
- Heroku deploy は heroku-deploy を使うようにする
このあと、 変更を master に push すれば Wercker でビルド後、Heroku に deploy される。
所感
Wercker のドキュメントが Wercker Workflows に対応していないものが多くて苦労した。
この記事が誰かの役にたてば嬉しい。
ホビー用途の mLab でリモートバックアップする
環境
- MongoDB 3.2.11
- dbxcli 1.4.0
- heroku-toolbelt 3.43.15
- heroku-buildpack-mongodb Rev. 59b9e8d
- heroku-buildpack-dbxcli Rev. d67845a
モチベーション
ホビー用途の Heroku アプリで mLab アドオンを Sandbox プランで利用している。
mLab の DB のバックアップは Sandbox プランでは提供されないので、リモートバックアップを設定したい。
ホビー用途なので、できればお金をかけない範囲で行いたい。
heroku-buildpack-mongodb
Heroku の buildpack に MongoDB のバイナリを使えるようにする heroku-buildpack-mongodb があるので、これを使って Heroku Scheduler で mongodump を呼び出せば、バックアップは取れそうである。
ストレージ
問題はストレージをどうするかである。
普通に考えたら S3 だが、ホビー用途で AWS はあまり使いたくない。IAM や MFA など、考えることが多いためだ。
そこで Dropbox を利用することを考えた。
dbxcli というワンバイナリで Dropbox を操作できるツールを Heroku Scheduler から使えれば良さそうだ。
heroku-buildpack-dbxcli
ということで heroku-buildpack-dbxcli という Buildpack を作った。
この Buildpack を使えば、dbxcli を Heroku 上から簡単に使うことができる。
Heroku 設定
まずは以下のような backup.sh を作って git commit しておく。
#!/bin/sh # backup xxx $ mongodump -h xxx.mongolab.com --port xxx -d heroku_appxxx -u heroku_appxxx -p xxx -o xxx_dump --excludeCollection=system.users # archive $ tar cvzf xxx_dump.tgz xxx_dump # upload to Dropbox $ dbxcli put xxx_dump.tgz Backups/xxx_dump.tgz
次にその Git リポジトリを Heroku に push する。
$ heroku create --buildpack http://github.com/goodeggs/heroku-buildpack-mongodb.git $ heroku buildpacks:add --index 2 http://github.com/mallowlabs/heroku-buildpack-dbxcli.git $ heroku config:add DROPBOX_AUTH_TOKEN=<your token> $ git push heroku master
Dropbox のトークンは、手元で dbxcli で一度ログインして ~/.config/dbxcli/auth.json の内容を見て取得する(ちょっとかっこ悪い)。
あとは backup.sh を Heroku Scheduler から呼び出せば、Dropbox に mongodump の結果が保存されるようになる。
まとめ
- dbxcli は便利!
- Heroku Buildpacks も便利!
GitBook で書いた文書の Redpen の警告を Jenkins Warnings Plugin で可視化する
環境
- Jenkins 2.8
- Jenkins Warnings Plug-in 4.56
- Redpen 1.5.5
モチベーション
最近、技術ドキュメントを GitBook を使って Markdown で書いている。
GitBook は当然 Git リポジトリが使えて、WebHook まで使える。
こうなってくると Jenkins で CI をして、校正結果をグラフにしたくなってくるので、
Jenkins と同じ Java で書かれた Redpen を使ってみている。
Jenkins Warnings Plugin の設定
まずは Jenkins Warnings Plugin にパーサーを追加する。
設定は以下のようにする。
- 名前 … Redpen
- リンク名 … Redpen 警告
- 推移レポート名 … Redpen 警告
- 正規表現
(.+):(\d+?): ValidationError\[(.+)\], (.+) at line: (.+)
import hudson.plugins.warnings.parser.Warning import hudson.plugins.analysis.util.model.Priority String fileName = matcher.group(1) String lineNumber = matcher.group(2) String message = matcher.group(4) return new Warning(fileName, Integer.parseInt(lineNumber), "Dynamic Parser", "Warning", message, Priority.NORMAL);
ジョブの設定
GitBook 側の設定
- WebHook で Jenkins のジョブを実行する
まとめ
GitBook + Redpen + Jenkins Warnings Pluginin がお手軽で最高!
Maven 3 + cobertura-maven-plugin 2.7 で mvn site すると jar/war が壊れる件
現象
Maven 3 と cobertura-maven-plugin 2.7 の組み合わせで mvn site をすると、生成される jar/war に Cobertura の instrument が混入したままパッケージが作られてしまう。
mvn package だけすると問題がないが、一つのコマンドラインで mvn package site のように同時にやってしまうと jar/war が壊れる。
Maven 2 を使っている場合には問題が無い。
原因
cobertura-maven-plugin 2.7 から integration-test フェーズでも実行されるように変更された。
この結果、mvn site でも package フェーズが実行されてしまうようになった。
Maven2 は integration-test フェーズが無いため問題がない。
対策
Mojo's Maven plugin for Cobertura – Usage に書いてある通り。
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>cobertura-maven-plugin</artifactId> <version>2.7</version> <reportSets> <reportSet> <reports> <report>cobertura</report> </reports> </reportSet> </reportSets> <configuration> <inputEncoding>UTF-8</inputEncoding> <outputEncoding>UTF-8</outputEncoding> <formats> <format>xml</format> <format>html</format> </formats> </configuration> </plugin>
のように reportSets を書くこと。これで site ゴールで Cobertura が走らなくなって、jar/war に instrument が混入することはなくなる。
まとめ
cobertura-maven-plugin 2.7 最高!
Ruboty でカレンダーの予定をアラートするプラグイン「ruboty-calendar_alert」作った
ruboty-cron を使って、チャットに予定をアラートしてたんだけど、予定の登録がダルくなったので作った。
iCal (.ics) の URL を Ruboty に教えてあげると、定期的にフェッチして、予定の10分前になったら教えてくれるようになった。
使い方
Gemfile に以下のように記述する
# Gemfile gem 'ruboty-calendar_alert', github: 'mallowlabs/ruboty-calendar_alert'
あとは Ruboty に iCal の URL を教えてあげる。
@ruboty add calendar <ics_url>
そうすると予定の10分前にチャットに通知される。
フェッチは
- 02:23
- 08:23
- 14:23
- 20:23
に実行されるので、あんまり最近に登録された予定についてはアラートされないかもしれない。
こんな感じで仕事中でもアニメの一挙放送の開始に気づけて本当に便利です。
まとめ
キルラキル最高!
h2o + supervisord で Munin を HTTP/2 でサーブさせてみた
YAPC::Asia Tokyo 2015 で HTTP/2 の話を聞いて意識が高まったので Munin を h2o でサーブするようにしてみた記録。
リバースプロキシではなく、h2o 自身にサーブさせている。
環境
- CentOS release 6.5 (Final)
- h2o Rev.af7413a0ec
- Supervisord 2.1
h2o
インストール
yum install cmake yum downgrade libyaml yum install libyaml-devel cd /usr/local/src git clone https://github.com/kazuho/h2o.git cd h2o git submodule update --init --recursive cmake . make h2o make install
設定
# cat /usr/local/share/h2o/h2o.conf hosts: "munin.example.com": listen: port: 443 ssl: certificate-file: /etc/httpd/certs/your.crt key-file: /etc/httpd/certs/your.pem host: 0.0.0.0 paths: "/": file.dir: /var/www/html/munin access-log: /var/log/h2o-access.log error-log: /var/log/h2o-error.log
Supervisord
インストール
yum --enablerepo=epel install -y supervisor
設定
# cat /etc/supervisord.conf [supervisord] [program:h2o] command=/usr/local/bin/h2o -c /usr/local/share/h2o/h2o.conf autorestart=true
所感
めっちゃ表示速くなった。
画像が一気に表示されるので非常に気持ちいい。
Chrome のネットワークタブを見るとこんな感じ。
ただ、IE11 でページが表示されないことがあったので、今すぐ本番導入という感じではないかも?
まとめ
HTTP/2 と h2o 最高!
Kibana4 + Elasticsearch で not_analyzed 指定を忘れた時にやったこと
Elasticsearch をそのまま使うと string フィールドがトークナイズされてしまうので、ユーザーエージェント等スペースを含むフィールドのグラフが意図通り出ない問題に対処した。
真面目にやるなら elasticsearchでダウンタイムなしでインデックスのマッピングを切り替える の方法がいいんだけど、Ruby が必要だったり、エイリアスを作ったりしなければならないので、もっと不真面目にやった時の記録。
環境
- Kibana 4.1.0
- Elasticsearch 1.6.0
- Elasticsearch Reindexing 1.4.2
やったこと
まずは、今後作成される全ての string のフィールドを not_analyzed にする。
curl -XPOST localhost:9200/_template/strig_not_analyzed_template -d '{ "template": "*", "mappings": { "_default_": { "dynamic_templates": [ { "string_template": { "mapping": { "index": "not_analyzed", "type": "string" }, "match_mapping_type": "string", "match": "*" } } ] } } }'
この後、9:00 JST まで待って次の日のインデックスが作成されるのを待つ。
Elasticsearch Reindexing をインストールする。
$ES_HOME/bin/plugin --install org.codelibs/elasticsearch-reindexing/1.4.2 service elasticsearch restart
Elasticsearch Reindexing 1.4.2 は Elasticsearch 1.6.0 でも動いた。
あとは、古いインデックスを一旦新しいインデックスに reindex して、また元に戻すというのを繰り返す。
最新のインデックスは、ログの流し込みが行われているはずなので、除外しておく。
雑なスクリプトでも動けばいいじゃない。
for index_name in access-2015.06.27 access-2015.06.28 access-2015.06.29 access-2015.06.30 access-2015.07.01; do curl -XPOST localhost:9200/${index_name}/_reindex/${index_name}_new/?wait_for_completion=true curl -XDELETE localhost:9200/${index_name} curl -XPOST localhost:9200/${index_name}_new/_reindex/${index_name}/?wait_for_completion=true curl -XDELETE localhost:9200/${index_name}_new done
これで、全てのインデックスの string フィールドは not_analyzed になる。