isaaxをRaspberryPiで試す


[TechCrunshでisaaxというサービスのローンチが紹介されていた](http://jp.techcrunch.com/2016/09/20/xshell-launches-iot-platform-isaax/)ので、試しにRaspberryPiで動かしてみました。
言うまでもありませんがこの記事の内容は所属組織の見解とは一切関係ありません。

# 環境

- MacOSX
  - LANにはWiFiで接続
- RaspberryPi 2 ModelB+
  - スイッチサイエンスのACアダプタを使用

# プロジェクトを追加する

isaaxの`プロジェクト > 新規追加`ページからプロジェクトを先に追加しておく必要があります。
プロジェクト追加時にgithub上にレポジトリを用意しておく必要があります。
今回は https://github.com/miminashi/isaax-test を使用しました。

# Raspbianのイメージを焼く

手元にRaspbianのイメージあったのでそのまま使ってみることにしました。

```bash
sudo dd if=2016-05-27-raspbian-jessie-lite.img of=/dev/disk2
```

焼きあがったらmicroSDをRaspberryPiに挿して、ついでにEthernetケーブルも挿して電源をいれます。

# RaspberryPiを探す

EthernetポートにLANケーブルを繋いだら、同じLANにつながっているMacから
地道にpingを打ってもいいがnmapを使うと一発で済む。

```bash
$ nmap -p22 192.168.0.0/24

Starting Nmap 7.12 ( https://nmap.org ) at 2016-09-26 00:07 JST
Nmap scan report for 192.168.0.1
Host is up (0.0020s latency).
PORT   STATE  SERVICE
22/tcp closed ssh

Nmap scan report for 192.168.0.3
Host is up (0.0029s latency).
PORT   STATE SERVICE
22/tcp open  ssh

Nmap done: 256 IP addresses (2 hosts up) scanned in 3.66 seconds
```

`192.168.0.3`が割り当てられている模様。


# isaax device register を実行する

`isaax device register`を実行すると、エージェント（isaaxd）とアプリケーションがアップロードされるようです。
さきほど発見したRaspberryPiのIPアドレスと、プロジェクト追加時に指定したGithubレポジトリがcloneしてあるローカルレポジトリのパスが必要です。（これがややこしい）

```bash
$ isaax device register
[+] Device registration.
[+] Loggining in
[+] You're already logged in
[+] Please enter IP address of your device: 192.168.0.3
[+] Default login credentials are (pi/raspberry), would you like to provide new credentials? (y/n):n
[+] Available isaax cloud projects:
	[0] Name: isaax-test
		[+] Description: aaaa
[+] Select a project (enter corresponding project number): 0
[+] Project with [ID: 67528d38-b651-4bab-856b-5fea040b4149] selected
[+] Available clusters: 
	[0] ID:d65c554d-f6ba-412b-b46f-c1f82796da41 
		[+] Description: default cluster
[+] Select cluster (enter corresponding cluster number): 0
[+] Selected: 0
[+] Cluster with [ID: d65c554d-f6ba-412b-b46f-c1f82796da41] selected
[+] Registering device to cluster:d65c554d-f6ba-412b-b46f-c1f82796da41
[+] Please enter label: rpi2
[+] Successfully registered device. Device ID:379533dd-3dcf-45db-a09b-ecd60ea7aa1e
[+] Would you like to upload app from your local workstation?(y/n):y
[+] Please enter a dir of your application (q for exit):/Users/miminashi/projects/isaax/isaax-test
[+] Creating application dir on device
[+] Executing sudo mkdir -p /var/isaax/project/ pi@192.168.0.3
[+] Creating a tarball:  /tmp/isaax-test.tar  from dir: /Users/miminashi/projects/isaax/isaax-test

[+] Successfully uploaded file :  isaax-test.tar
[+] Executing sudo tar xvf /var/isaax/project//isaax-test.tar -C /var/isaax/project/ pi@192.168.0.3
[+] Untarred app
[+] Executing sudo rm /var/isaax/project//isaax-test.tar pi@192.168.0.3
[+] Cleaning up
[+] Attempting to download. Trying 1 out of 3 
[+] Downloading isaaxd_linux_arm.tar.gz from https://s3-us-west-2.amazonaws.com/isaax-daemon/latest/linux/isaaxd_linux_arm.tar.gz to /tmp/isaaxd/
 2680457 / 2702105 [=====================================================================]  99.20% 0
[+] Done
 2702105 / 2702105 [=====================================================================] 100.00% 0
[+] Successfully uploaded file :  isaaxd_linux_arm.tar.gz

[+] Successfully uploaded file :  isaaxd.json
[+] Executing sudo  tar xvf /opt/isaaxd_linux_arm.tar.gz -C /opt/ pi@192.168.0.3
[+] Untarred daemon
[+] Executing sudo /opt/isaaxd_linux_arm/isaaxd status  pi@192.168.0.3
[+] Executing sudo /opt/isaaxd_linux_arm/isaaxd install  pi@192.168.0.3
Install Isaax Daemon:					[  OK  ]

[+] Executing sudo /opt/isaaxd_linux_arm/isaaxd start  pi@192.168.0.3
Error while starting daemon: Service is alredy running

[+] Executing sudo /opt/isaaxd_linux_arm/isaaxd status  pi@192.168.0.3
Service (pid  969) is running...

[+] Executing sudo cat /var/log/isaaxd.log pi@192.168.0.3
{"level":"debug","msg":"init() called with args:[/opt/isaaxd_linux_arm/isaaxd status]","time":"2016-09-25T17:38:29Z"}
{"level":"error","msg":"Error while getting status of daemonerror msg:Service is not installed","time":"2016-09-25T17:38:29Z"}
{"level":"fatal","msg":"Status could not defined error msg:Service is not installed","time":"2016-09-25T17:38:29Z"}
{"level":"debug","msg":"init() called with args:[/opt/isaaxd_linux_arm/isaaxd install]","time":"2016-09-25T17:38:29Z"}
{"level":"debug","msg":"init() called with args:[/opt/isaaxd_linux_arm/isaaxd]","time":"2016-09-25T17:38:32Z"}
{"level":"debug","msg":"Loading daemon configuration file from:/etc/isaaxd.json","time":"2016-09-25T17:38:32Z"}
{"level":"warning","msg":"Error extracting URL:api.isaax.io error msg:missing port in address","time":"2016-09-25T17:38:32Z"}
{"level":"warning","msg":"no protocol specified, applying default protocol:tcp","time":"2016-09-25T17:38:32Z"}
{"level":"warning","msg":"no port specified, applying default port:1883","time":"2016-09-25T17:38:32Z"}
{"level":"debug","msg":"init() called with args:[/opt/isaaxd_linux_arm/isaaxd start]","time":"2016-09-25T17:38:33Z"}
{"level":"error","msg":"Error while starting daemonerror msg:Service is alredy running","time":"2016-09-25T17:38:33Z"}
{"level":"fatal","msg":"Starting Isaax Daemon:\t\t\t\t\t[\u001b[31mFAILED\u001b[0m] error msg:Service is alredy running","time":"2016-09-25T17:38:33Z"}
{"level":"debug","msg":"Preparing mqtt logging hook","time":"2016-09-25T17:38:33Z"}
{"level":"debug","msg":"adding logrus hook for mqtt","time":"2016-09-25T17:38:33Z"}
{"level":"debug","msg":"Subscribing to:cloud/d65c554d-f6ba-412b-b46f-c1f82796da41/update","time":"2016-09-25T17:38:33Z"}
{"level":"debug","msg":"init() called with args:[/opt/isaaxd_linux_arm/isaaxd status]","time":"2016-09-25T17:38:34Z"}
{"level":"info","msg":"Starting up","time":"2016-09-25T17:38:34Z"}
{"level":"debug","msg":"Registering handlers","time":"2016-09-25T17:38:34Z"}
{"level":"info","msg":"Starting up web server","time":"2016-09-25T17:38:34Z"}
{"level":"debug","msg":"Loading application isaax.json file from:/var/isaax/project/isaax-test/isaax.json","time":"2016-09-25T17:38:34Z"}
{"level":"debug","msg":"Application details are loaded","time":"2016-09-25T17:38:34Z"}
```

isaaxの`プロジェクト > デバイス`を見ると、デバイスが追加されて、ステータスが`オンライン`になっているのが確認できます。

![スクリーンショット 2016-09-26 2.41.55.png](https://qiita-image-store.s3.amazonaws.com/0/26038/ade3d436-63e4-b07d-6da5-f78ed194bc02.png "スクリーンショット 2016-09-26 2.41.55.png")

デバイスの個別ページを開いて、`EVENTS`を見ると、ログがガンガン飛んできているようです。

![スクリーンショット 2016-09-26 2.44.42.png](https://qiita-image-store.s3.amazonaws.com/0/26038/d1d0653c-d913-70e5-bf8b-604ad595a501.png "スクリーンショット 2016-09-26 2.44.42.png")

sshではいってpsしてみると、pythonのプロセスが確認できました。

```bash
pi@raspberrypi:~ $ ps axu |grep python
root       561  0.8  2.0  12860  9152 ?        S    17:54   0:00 python app.py
```

# アップデートしてみる

```bash
vim app.py  # ファイル変更
git add app.py
git commit
git push origin master
```

printで出力するメッセージを変更したのですが、`EVENTS`に表示されるログには変化がないですね。うーん・・・
RaspberryPiにsshではいってpsしてみると、PIDが変わっているので、プロセスの再起動は行われているっぽいです。
Push hook の設定も行われているようなので、差分の取得に失敗しているのかな・・・？

# アプリケーションプロセスを殺してみる

```ssh
pi@raspberrypi:~ $ sudo kill 561
pi@raspberrypi:~ $ ps axu |grep python
root       561  0.4  0.0      0     0 ?        Z    17:54   0:00 [python] <defunct>
```

アイエエエ？ゾンビ化してしまったようです。
`EVENTS`を見るとログが止まってないので、アプリケーションプロセスはまだ動いてはいるみたいです。

# 気になった点

方向性としては非常にありだと思うんだけど、にわか組み込みLinux受託屋さんが楽するためのツールとしては、まだ自分のほしい感じのものじゃないかな・・・という感じです。

## 初期化処理が煩雑

CLIがsshでいろいろ設定してるみたいだけど、どうせイメージ焼き直すんなら諸々セットアップ済みのイメージを焼いて/bootパーティションに認証情報置くだけ、って感じにしといてくれたらなーと思います。
客先でLAN繋げない、みたいな環境の場合再セットアップできないじゃん・・・
あとこれ複数台セットアップしてて、IPアドレス打ち間違えたらハチャメチャなことになりそう・・・
ていうかEthernetかWiFiにつながってさえいれば大抵DHCPがIPアドレス割り振ってインターネットまで導いてくれるはずなので、ネットワークの設定はケーブル挿す or WiFiの認証情報打ち込む、より難しいことは意識しないで済むようにしてほしいですね。
[TechCrunchの記事](http://jp.techcrunch.com/2016/09/20/xshell-launches-iot-platform-isaax/)ではプログラミング言語の知識さえあれば使える、と謳っていますが、SOHOのLAN管理者程度のネットワークの知識が要求されてる気がします。
クラウドが革命的だったのって、サービスを運用するにあたってネットワークの知識がほとんどなくて良くなったことだったので、IoTプラットフォームをやっていってる皆様におかれましてはネットワークを意識しなくてもよくなるようなサービス設計をお願いしたいところです。

## エージェントを手動でインストールする方法がわからない

エージェントのダウンロード自体はできるようですが、エージェントを手動でインストールする方法がどこにも書かれてないようです。
NanoPiで使いたかったので、同じARMなので設定方法さえわかれば動かせると思うんですが・・・
yoctoとかから使いたいときもCLIによらない設定方法がわからないとできないです。


## isaax, Github, CLI をいったりきたり

isaaxでプロジェクトを新規作成する前に、githubでレポジトリを追加しておかないといけません。
CLIからデバイスを登録する前に、Web上でプロジェクトを新規作成しておかないといけません。
ローカルにレポジトリが存在しない場合、CLIからデバイスを登録する前にcloneしておかないといけません。
これらの前後関係が頭に入ってないとアプリケーションのデプロイまで辿り着けません。
herokuだと割とどっから始めても困らなかったんだけどな・・・（そもそもgithub必須ではないし）


## Github連携しないとgitレポジトリが使えない

Githubだと課金しないとprivateなレポジトリが使えないので、そもそもコードを公開できない受託案件でかなり使いづらいです。（これ使うためにGithub課金するか？と言われるとNoなので）
herokuみたいにサービス側がprivateなレポジトリを用意しててくれると何も考えなくて済んで良いのですが・・・
プロトタイプだと認証情報とコードの分離とか気にせずとにかく一直線で動くもの作りたかったりしますしね。そんなわけでHerokuの無料で使えるprivateなレポジトリの存在というのはかなり重要なんだなと思いました。


## Github上で手動でレポジトリを用意しておかないといけない

プロジェクトを新規作成する前に、
たとえこれがisaax上でプロジェクトを追加するときにGithub上に自動でレポジトリが追加されたとしても、Github上からisaaxから参照されてるレポジトリなのかぱっと見でわからないので、管理が煩雑になりそうだなぁ、と思いました。
これもherokuのようにサービス側でGitレポジトリを持っていてくれると気にしなくて済むことなのですが・・・


## isaax gl でユーザに確認もなしに問答無用でインストールする

isaax CLIに自分自身をインストールするサブコマンドがあるのですが、ユーザに確認もなしに /usr/local/bin に問答無用にインストールしてきます。

```bash
$ ./isaax gl
[+] Installing: ./isaax  to: /usr/local/bin
```

これはちょっとお行儀が悪いなと思いました。

## CLIとエージェントのソースコードが公開されていない

ユーザの手元のデバイスにインストールするソフトウェアがなにやってるのかがわからない（検証手段がパケットキャプチャくらいしかない）のがちょっと不安です。
お客さんに「スパイウェアの可能性ないの？」って聞かれたときにどう答えるのか・・・
[resinは全部公開されてる](https://github.com/resin-io/resin-supervisor)みたいですね。


# 理想のワークフローは？

まず、開発段階で頻繁にコードの変更が発生するときにいちいちgit commitしてgit pushするのはやってられないです。Webアプリケーションの場合だと`rails s`とかで一発でローカルで起動してデバッグができますが、これをリモートデバイスに対してやってくれる仕組みがほしいところです。
いまのところデバッグはコードをscpで送ってsshでログインして実行してますが、これが毎度毎度すごいめんどくさいので全自動でできるようになってほしい。（できればMacとRaspberryPiが別々のネットワークにいたとしても同じ手順でできてほしい）
デバイスのセットアップは自動でやってくれても、こっちができないのは片手落ちでしょ、と思ってしまいます。

デプロイについてはherokuのように、CLIはなくてもなんとかなるというのがPaaSとして理想的なかたちだと思います。

```
アプリケーションを書く → Webからプロジェクトを追加 → git remote add → git commit → git push → デプロイ完了
```

という感じでできたらよいかな。