[enebular][heroku] node.js+Heroku Platform APIでHerokuアプリを作成する

By |12月 12, 2014|enebular, heroku, Javascript, Node.js, |


2014年11月22日にenebularをベータリリースしました。

こちらのサービスはユーザ登録すると自動的にHerokuアプリが作成され各ユーザに1つづつ割り当てられる動きになっています。

なぜHeroku buttonでやらないのかというとHerokuユーザ以外にも使ってもらいたいのと作成したHerokuアプリをサービス側で管理したいという理由です。

enebularはnode.jsで作っていてユーザ個別に作成するHerokuアプリもnode.jsで作られています。

つまり今回のエントリはnode.jsでnode.jsのHerokuアプリをHeroku Platform APIで自動作成するという内容になります。

まずはHeroku Platform APIのドキュメントを見ながらcurlでApp Setupをやってみます。

[html]
$ curl -n -X POST https://api.heroku.com/app-setups \
-H "Accept: application/vnd.heroku+json; version=3" \
-H "Content-Type: application/json" \
-d ‘{
"app": {
"locked": false,
"personal": true,
"region": "us",
"stack": "cedar"
},
"source_blob": {
"url": "https://github.com/railsjedi/heroku-rails/tarball/master/"
}
}’
{"id":"59ac2624-3254-4077-a161-2fdb3f432fd5","failure_message":null,"status":"pending","app":{"id":"f4371da2-6d31-4035-a344-551c4ebb6b46","name":"peaceful-coast-4013"},"build":{"id":null,"status":null},"manifest_errors":[],"postdeploy":{"output":null,"exit_code":null},"resolved_success_url":null,"created_at":"2014-12-11T18:34:39+00:00","updated_at":"2014-12-11T18:34:39+00:00"}
[/html]

一見、成功したように見えますがstatusがpendingです。少し待ってみましたがアプリは作成されません…

結局よくわからないのでApp Setupで一気に作成するのは諦めました(personalだとダメとか?organizationアプリってのがよく解りません)

この後、割愛しますがApp, Dyno, Buildなどのリソースをcurlで利用したら思い通りの動きになりましたのでnode.jsで実装します。

node.jsのHeroku clientであるnode-heroku-clientを利用します(メソッド数珠つなぎでコールバック地獄に陥るのでPromiseで書きました)

var appName,
Heroku = require('heroku-client'),
heroku = new Heroku({ token: process.env.HEROKU_API_TOKEN });
heroku.apps().create().then(function (app) {
appName = app.name;
return heroku.apps(appName).addons().create({
"plan": "mongolab"
});
}).then(function (addon) {
return heroku.apps(appName).dynos().create({
"attach": true,
"command": "bash"
});
}).then(function (dyno) {
return heroku.apps(appName).builds().create({
"source_blob": {
"url": "https://github.com/node-red/node-red/tarball/master/"
}
});
}).then(function (build) {
var intervalId = setInterval(function() {
heroku.apps(appName).builds(build.id).result().info().then(function (result) {
console.log(result.build.status);
if (result.build.status == 'succeeded') {
clearInterval(intervalId);
}
});
}, 3000);
}).catch(function (e) {
console.error(e.stack);
});
view raw heroku.js hosted with ❤ by GitHub

このエントリはHeroku Advent Calendar 2014に参加しています。