Symbol Dual をサービス化(デーモン化)する


## サービスファイルの作成

### MongoDB

Server から Broker へ渡った情報を保存するためのサービスです。Rest の情報の取得元のひとつでもあります。

```bash
sudo vi /etc/systemd/system/symbol-db.service
```

```/etc/systemd/system/symbol-db.service
[Unit]
Description=Symbol MongoDB
Wants=network.target
After=network.target

[Service]
Type=forking
PIDFile=/run/mongo/symbol-db.pid
ExecStart=/usr/bin/mongod --dbpath=dbdata --wiredTigerCacheSizeGB 2 --pidfilepath /run/mongo/symbol-db.pid --fork --syslog
KillSignal=SIGINT
User=harvestasya
Group=harvestasya
WorkingDirectory=/opt/symbol-node
LimitNOFILE=65536
UMask=077

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

pid ファイルの保存先を作成します。

```bash
sudo mkdir /run/mongo
sudo chown harvestasya: /run/mongo
```

再起動するとディレクトリが消えてしまうので、再起動時に作成するようにします。

```bash
sudo vi /etc/tmpfiles.d/mongo.conf
```

```/etc/tmpfiles.d/mongo.conf
#Type   Path                    Mode    UID            GID          Age  Argument
d       /run/mongo              0755    harvestasya    harvestasya  -
```

### Rest Gateway

Symbol ブロックチェーンのノードとクライアント間の通信を管理するための RESTful API を提供するサービスです。基本的に MongoDB からデータを取得するので、MongoDB に依存します。
一部のデータは、Server や Broker から直接取得しますが、必要になった際に接続するので依存関係からは外しています。

```bash
sudo vi /etc/systemd/system/symbol-rest.service
```

```/etc/systemd/system/symbol.service
[Unit]
Description=Symbol Rest Gateway
Requires=network.target symbol-db.service

[Service]
Type=idle
ExecStart=/home/harvestasya/.volta/bin/npm start ../rest/rest.json
Restart=on-failure
RestartSec=2
User=harvestasya
Group=harvestasya
WorkingDirectory=/opt/symbol-node/app
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
UMask=077

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

### Symbol Recovery

異常終了などで lock ファイルが残った際に起動します。

```bash
sudo vi /etc/systemd/system/symbol-recovery.service
```

```/etc/systemd/system/symbol-recovery.service
[Unit]
Description=Symbol Recovery

[Service]
Type=oneshot
ExecCondition=/bin/sh -c '/usr/bin/test -f /opt/symbol-node/data/server.lock || /usr/bin/test -f /opt/symbol-node/data/broker.lock'
ExecStart=/usr/local/catapult/bin/catapult.recovery .
KillSignal=SIGINT
Restart=on-failure
RestartSec=2
TimeoutStopSec=60
User=harvestasya
Group=harvestasya
WorkingDirectory=/opt/symbol-node
Environment="LD_LIBRARY_PATH=/usr/local/catapult/deps"
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
UMask=077

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

### Symbol Broker

Server からファイルスプールを通してデータを取得するサービスです。MongoDB への接続や Rest からの ZeroMQ 接続があるので、これらを依存関係に含めています。

```bash
sudo vi /etc/systemd/system/symbol-broker.service
```

```/etc/systemd/system/symbol-broker.service
[Unit]
Description=Symbol Broker
Wants=symbol-recovery.service
Requires=network.target symbol-db.service symbol-rest.service

[Service]
Type=idle
ExecStart=/usr/local/catapult/bin/catapult.broker .
ExecStopPost=/bin/bash -c 'while systemctl is-active --quiet symbol-broker.service; do sleep 1; done; sudo systemctl stop symbol-rest.service'
ExecStopPost=/bin/bash -c 'while systemctl is-active --quiet symbol-broker.service; do sleep 1; done; sudo systemctl stop symbol-db.service'
KillSignal=SIGINT
Restart=on-failure
RestartSec=2
TimeoutStopSec=20
User=harvestasya
Group=harvestasya
WorkingDirectory=/opt/symbol-node
Environment="LD_LIBRARY_PATH=/usr/local/catapult/deps"
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
UMask=077

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

### Symbol Server

前々回に作成した`symbol.service`を編集します。broker の起動後に起動することになります。

```bash
sudo vi /etc/systemd/system/symbol.service
```

```/etc/systemd/system/symbol.service
[Unit]
Description=Symbol Node
Wants=symbol-recovery.service
Requires=network.target symbol-broker.service

[Service]
Type=idle
ExecStart=/usr/local/catapult/bin/catapult.server .
ExecStopPost=/bin/bash -c 'while systemctl is-active --quiet symbol.service; do sleep 1; done; sudo systemctl stop symbol-broker.service'
KillSignal=SIGINT
Restart=on-failure
RestartSec=2
TimeoutStopSec=300
User=harvestasya
Group=harvestasya
WorkingDirectory=/opt/symbol-node
Environment="LD_LIBRARY_PATH=/usr/local/catapult/deps"
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
UMask=077

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

## `systemctl stop`のパスワード不要化

`ExecStopPost`で`sudo systemctl stop`しているので、パスワードなしで実行できるようにします。

nano で編集する場合は、`EDITOR=vi`不要です。

```bash
sudo EDITOR=vi visudo
```

`@includedir /etc/sudoers.d`の前に追記する。

```visudo
harvestasya ALL=(ALL:ALL) NOPASSWD: /bin/systemctl stop symbol-db.service
harvestasya ALL=(ALL:ALL) NOPASSWD: /bin/systemctl stop symbol-rest.service
harvestasya ALL=(ALL:ALL) NOPASSWD: /bin/systemctl stop symbol-broker.service
```

## サービスをリロード

```bash
sudo systemctl daemon-reload
```

## サービスを有効化

```bash
sudo systemctl enable symbol
```

## サービスを開始

```bash
sudo systemctl start symbol
```

## サービスを停止

```bash
sudo systemctl stop symbol
```

## ログの確認

```bash
sudo journalctl -u symbol -r
```

リアルタイムで確認したい場合は`-f`オプションを付けます。

```bash
sudo journalctl -u symbol -f
```

さらに色を付けたい場合は、`-o cat`オプションを付けます。

```bash
sudo journalctl -u symbol -f -o cat
```