ラズパイでhubotを自動起動 - systemdとforever

# はじめに
slackをadaptorにhubotの自動起動をしよう、と決めて

- raspberryPiにhubotを入れて起動している間に落ちてしまう　→　foreverで防ぐ
- serviceから起動する　→ slackにhubotが現れない → serviceの書き方を変える

raspberryPi起動後に書いたshを叩いて起動は確認しつつ、わかったところをまとめます。

# 前提

foreverはhubotではなく、piユーザの環境にいれています。
> $ npm install forever -g

# hubot
## hubotファイル本体の編集
npmのPATHを追加しないと動かなかったので環境変数に追加

```:.bin/hubot
#!/bin/sh

who=$(whoami)
if [ "${who}" != "pi" ]; then
        echo "Usage: bin/hubot (start|stop|restart|status). Please again.\n"
        exit 1;
fi

ARG1=$1

if [ "${ARG1}" = "" ]; then
        echo "missing param. bin/hubot (start|stop|restart|status). Please again."
        exit 1;
fi

set -e

NVM_BIN=/usr/local/nvm/versions/node/v6.10.1/bin
export PATH="$NVM_BIN:$PATH"

start() {
　　　　　　　　　　　　　　　　# 一度起動した後は外しました。サービス起動時にあると起動時間が長すぎてうまくいかなかった
        #npm install
        export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"
        export HUBOT_SLACK_TOKEN=[slackから取得したtoken]

        exec forever start  --spinSleepTime 200000 -c coffee node_modules/.bin/hubot -a slack
}
stop () {
        forever stop -c coffee node_modules/.bin/hubot
}
restart() {
        forever restartall
}
status() {
        forever list
}

case "$ARG1" in
        "stop" )
                stop
                ;;
        "restart" )
                restart
                ;;
        "start" )
                start
                ;;
        "status" )
                status
                ;;
esac
```
### 参考

http://kenzo0107.hatenablog.com/entry/2016/01/13/154431
の`daemonize hubot`がよいです。

> $ forever -h

## テスト
`/home/pi/work/hubot`でhubotを作っています。

### 起動

```
$ cd /home/pi/work/hubot
$ ./bin/hubot start
```
### 停止

```
$ cd /home/pi/work/hubot
$ ./bin/hubot stop
```

### 起動時のリロード

```
$ cd /home/pi/work/hubot
$ ./bin/hubot restart
```

# プロセス起動・停止

それぞれのスクリプトには実行権限をつけておきます
> $ sudo chmod 755 xxxxx.sh

## 起動スクリプト

```shell-session:/home/pi/work/hubot_start.sh 
#!/bin/sh

DIR="/home/pi/work/hubot"
cd $DIR
./bin/hubot start

```

## 停止スクリプト

```shell-session:/home/pi/work/hubot_stop.sh 

#!/bin/sh

DIR="/home/pi/work/hubot"
cd $DIR
./bin/hubot stop

```

## 再起動スクリプト

```shell-session:/home/pi/work/hubot_restart.sh 

#!/bin/sh

DIR="/home/pi/work/hubot"
cd $DIR
./bin/hubot restart

```

## テスト

起動、停止、再起動スクリプトを実行して動くか確認

# serviceへの登録で自動起動

## serviceファイルの作成

```:/lib/systemd/system/hogehoge.service
[Unit]
Description = slack bot daemon

[Service]
ExecStart = /home/pi/work/hubot_start.sh
ExecStop = /home/pi/work/hubot_stop.sh
ExecReload = /home/pi/work/hubot_restart.sh
Restart = always
Type = forking
User=pi
Group=pi

[Install]
WantedBy = multi-user.target
```

### 参考
http://enakai00.hatenablog.com/entry/20130917/1379374797

## テスト
serviceファイルを編集したらdaemonを読み込みなおし
> $ sudo systemctl daemon-reload

起動
> $ sudo systemctl start hogehoge

停止
> $ sudo systemctl stop hogehoge

ステータスを確認
> $ sudo systemctl status hogehoge

### 参考
http://enakai00.hatenablog.com/entry/20130915/1379212787

# 起動時の確認

サービスの起動・停止がうまくいったらサービスに登録します。

> $ sudo systemctl enable hogehoge

下記実行後

再起動
> $ sudo reboot now

もしくは

停止
> $ sudo shutdown now 

起動したraspberry Piで

> $ ps -ef | grep pi

```
pi        1319     1  0 11:47 ?        00:00:05 /usr/local/nvm/versions/node/v6.10.1/bin/node /home/pi/work/hubot/node_modules/forever/bin/monitor node_modules/.bin/hubot
pi        1328  1319  1 11:47 ?        00:00:45 node node_modules/.bin/coffee /home/pi/work/hubot/node_modules/.bin/hubot -a slack
```

こんな感じに見えている時はhubotは動作していました。
下記のような場合は失敗。

```
pi        2232     1  0 09:50 ?        00:00:00 /bin/sh /home/pi/work/hubot_start.sh
pi        2233  2232  0 09:50 ?        00:00:00 /bin/sh ./bin/hubot -a slack
pi        2234  2233 99 09:50 ?        00:00:30 npm  
```


# さいごに

いろいろ正直めんどくさいが、テスト好きなのが幸いして進められている感じです。
こうした方がいい、こっちのやり方の方が正しいなどありましたらコメントくださいませ。

## ハマリどころ1　ー serviceファイルの書き方。
ググってみるだけででは

今回forkで書いた部分は
>Type = simple

ユーザはだいたいrootで動かしているようなものが多く下記を追加してpiユーザで動くようになったものの
>User=pi
Group=pi

piユーザで設定しているNVM_BINの環境変数が取れないなど。

## ハマリどころ2　ー hubotの起動時間が長い
他、hubotのデフォルトで記載がある`npm install`を毎回実行すると時間がかかり起動がうまくいかないことがよくありました。
hubotのpackage.jsonからforeverを外したり、結局毎度installをやめたりで対応しています。