RockyLinuxにMosquittoをインストール

# RockyLinuxにMosquittoをインストール

最近はWeb言語から遠ざかり、2畳程度のビニールハウスでパッションフルーツやフィンガーライムを愛でる生活を満喫中。
そんな最中、Blynkが有料化してローカルサーバを廃止、開発主要メンバーの母国ウクライナが戦争に巻き込まれ、CentOSがお亡くなりになる怒涛の１年でした、、、

今回はそんなこんなで、今はRockyLinuxでウホウホしているので、RockyLinuxにMQTTのMosquittoをインストールしたときの記録を残します。

## 環境

```
$ cat /etc/system-release
Rocky Linux release 9.1 (Blue Onyx)

$ mosquitto -v
1673374996: mosquitto version 2.0.15 starting
1673374996: Using default config.
1673374996: Starting in local only mode. Connections will only be possible from clients running on this machine.
1673374996: Create a configuration file which defines a listener to allow remote access.
1673374996: For more details see https://mosquitto.org/documentation/authentication-methods/
1673374996: Opening ipv4 listen socket on port 1883.
1673374996: Error: Address already in use
1673374996: Opening ipv6 listen socket on port 1883.
1673374996: Error: Address already in use

$ systemctl status mosquitto
● mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/etc/systemd/system/mosquitto.service; alias)
     Active: active (running) since Wed 2023-01-11 03:12:16 JST; 14min ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
    Process: 1062 ExecStartPre=/bin/mkdir -m 740 -p /var/log/mosquitto (code=exited, status=0/SUCCESS)
    Process: 1064 ExecStartPre=/bin/chown mosquitto:mosquitto /var/log/mosquitto (code=exited, status=0/SUCCESS)
    Process: 1068 ExecStartPre=/bin/mkdir -m 740 -p /run/mosquitto (code=exited, status=0/SUCCESS)
    Process: 1072 ExecStartPre=/bin/chown mosquitto:mosquitto /run/mosquitto (code=exited, status=0/SUCCESS)
   Main PID: 1079 (mosquitto)
      Tasks: 1 (limit: 48045)
     Memory: 1.5M
        CPU: 378ms
     CGroup: /system.slice/mosquitto.service
             └─1079 /usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jan 11 03:12:16 localhost systemd[1]: Starting Mosquitto MQTT Broker...
Jan 11 03:12:16 localhost systemd[1]: Started Mosquitto MQTT Broker.

```

## インストール手順

Mosquittoはオフィシャルの[Mosquitto github](https://github.com/eclipse/mosquitto)からクローンを作ってコンパイルしてインストールします。リポジトリとかなかったので地道にコンパイルして入れる作業になります。

### githubからクローン作成

`cJSON`は`Mosquitto`のJSONパーサーとして使われています。

```
$ cd /usr/local/src/

$ git clone https://github.com/eclipse/mosquitto.git

$ git clone https://github.com/DaveGamble/cJSON.git
```

### コンパイル準備

`Development Tools`はgccあたりのビルドのために、
`systemd-devel`はMosquittoインストールでsystemctl配下にするために、
`CUnit`関係は`make test`のために、、、

```
$ dnf groupinstall "Development Tools" -y

$ dnf install systemd-devel -y

$ dnf install CUnit -y

$ dnf --enablerepo=devel install CUnit-devel -y
```

### cJSONインストール

```
$ cd /usr/local/src/cJSON/

$ make
gcc -std=c89 -c -fPIC -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion -fstack-protector cJSON.c
gcc -std=c89 -shared -o libcjson.so.1.7.15 cJSON.o -Wl,-soname=libcjson.so.1 
ln -s libcjson.so.1.7.15 libcjson.so.1
ln -s libcjson.so.1 libcjson.so
gcc -std=c89 -c -fPIC -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion -fstack-protector cJSON_Utils.c
gcc -std=c89 -shared -o libcjson_utils.so.1.7.15 cJSON_Utils.o cJSON.o -Wl,-soname=libcjson_utils.so.1 
ln -s libcjson_utils.so.1.7.15 libcjson_utils.so.1
ln -s libcjson_utils.so.1 libcjson_utils.so
ar rcs libcjson.a cJSON.o
ar rcs libcjson_utils.a cJSON_Utils.o

$ make install
mkdir -p /usr/local/lib /usr/local/include/cjson
cp -a cJSON.h /usr/local/include/cjson
cp -a libcjson.so libcjson.so.1 libcjson.so.1.7.15 /usr/local/lib
cp -a cJSON_Utils.h /usr/local/include/cjson
cp -a libcjson_utils.so libcjson_utils.so.1 libcjson_utils.so.1.7.15 /usr/local/lib
```

### Mosquittoインストール

今回はsystemctl配下にして、サービスとして利用したいので`Makefile`のコンフィグファイルをイジります。
`WITH_SYSTEMD`を`no`から`yes`に変更します。これでインストール時に`systemd`を使用したサービス登録が行われます。

```text:/usr/local/src/mosquitto/config.mk
# Build with systemd support. If enabled, mosquitto will notify systemd after
# initialization. See README in service/systemd/ for more information.
# Setting to yes means the libsystemd-dev or similar package will need to be
# installed.
WITH_SYSTEMD:=yes
```

ビルドします。

```
$ cd /usr/local/src/mosquitto/

$ make
```

テストします。（でも何個か失敗しちゃうから、逃げの`-i`をつけて実効します
dbを作成したり、confファイルを作成する感じのスクリプトで、ファイルの作成・削除に失敗してるっぽい。
原因はよくわからない、、、

```
$ cd /usr/local/src/mosquitto/

$ make test -i
```

インストール

```
$ cd /usr/local/src/mosquitto/

$ make install
```

コンフィグファイル作成

```text:/etc/mosquitto/mosquitto.conf
allow_anonymous true
# password_file /etc/mosquitto/pwfile
listener 1883
persistence false
pid_file /var/run/mosquitto/mosquitto.pid
protocol mqtt
log_dest stderr
log_type warning
user mosquitto
```

試しに`Mosqitto`を実効してみる。
この時、オプション`-v`をつけておくと、コンフィグファイルにミスがあると教えてくれる。
抜けるには`Ctrl + c`

```
$ mosquitto -v -c /etc/mosquitto/mosquitto.conf
1673384836: mosquitto version 2.0.15 starting
1673384836: Config loaded from /etc/mosquitto/mosquitto.conf.
1673384836: Opening ipv4 listen socket on port 1883.
1673384836: Opening ipv6 listen socket on port 1883.
1673384836: mosquitto version 2.0.15 running

```

### Mosquittoをサービスに登録

サービス書き換え
`[Service]`の`ExecStart`に記述されているパスが通ってないため書き換え

> ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
> ↓
> ExecStart=/usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

```text:/usr/local/src/mosquitto/service/systemd/mosquitto.service.notify
[Unit]
Description=Mosquitto MQTT Broker
Documentation=man:mosquitto.conf(5) man:mosquitto(8)
After=network.target
Wants=network.target

[Service]
Type=notify
NotifyAccess=main
ExecStart=/usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
ExecStartPre=/bin/mkdir -m 740 -p /var/log/mosquitto
ExecStartPre=/bin/chown mosquitto:mosquitto /var/log/mosquitto
ExecStartPre=/bin/mkdir -m 740 -p /run/mosquitto
ExecStartPre=/bin/chown mosquitto:mosquitto /run/mosquitto

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

サービスへ登録

```
$ ln -s /etc/systemd/system/mosquitto.service /usr/local/src/mosquitto/service/systemd/mosquitto.service.notify

$ systemctl daemon-reload
```

サービスとして起動

```
$ systemctl start mosquitto.service

$ systemctl status mosquitto.service 
● mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/etc/systemd/system/mosquitto.service; alias)
     Active: active (running) since Wed 2023-01-11 06:12:32 JST; 8s ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
    Process: 21956 ExecStartPre=/bin/mkdir -m 740 -p /var/log/mosquitto (code=exited, status=0/SUCCESS)
    Process: 21957 ExecStartPre=/bin/chown mosquitto:mosquitto /var/log/mosquitto (code=exited, status=0/SUCCESS)
    Process: 21958 ExecStartPre=/bin/mkdir -m 740 -p /run/mosquitto (code=exited, status=0/SUCCESS)
    Process: 21959 ExecStartPre=/bin/chown mosquitto:mosquitto /run/mosquitto (code=exited, status=0/SUCCESS)
   Main PID: 21960 (mosquitto)
      Tasks: 1 (limit: 48045)
     Memory: 1.0M
        CPU: 21ms
     CGroup: /system.slice/mosquitto.service
             └─21960 /usr/local/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jan 11 06:12:32 localhost.localdomain systemd[1]: Starting Mosquitto MQTT Broker...
Jan 11 06:12:32 localhost.localdomain systemd[1]: Started Mosquitto MQTT Broker.
```


## 動作テスト

コンソールを２つ開いてそれぞれで実効してみる。
`sub`が受信側、`pub`が送信側、ちゃんと`うんこ`が出るはず。

```
$ mosquitto_sub -t 'test/topic' -v
```

```
& mosquitto_pub -t test/topic -m "うんこ"
```