2022年にCloudforecastを導入する

# はじめに
リソース監視ツールのCloudforecastは便利なのですが、導入手順のドキュメントがいまいち整備されていないので個人的にメモ。

# 諸要素
CentOS 9 Stream
System Perl
Gearman
Nginx

※ネタバレですが、Perlbrewで入れたPerlで導入しようとするとSNMPモジュールのインストールでコケます。
諦めてSystem Perlを使って導入しましょう。

# パッケージの導入

```shell
dnf update
dnf install perl perl-core
curl -L https://cpanmin.us | perl - App::cpanminus
dnf install rrdtool rrdtool-perl
dnf install net-snmp net-snmp-utils
dnf install net-snmp-perl
dnf install git
dnf install nginx
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
dnf config-manager --set-enabled crb
dnf install gearmand
```

# 実行ユーザーの作成〜各種ファイル作成

```shell
useradd cloudforecast
su - cloudforecast
snmpwalk -v 2c -c ExAmplEcOmmUnIty 192.168.x.x system
chmod 755 /home/cloudforecast
mkdir git
cd git
git clone https://github.com/kazeburo/cloudforecast.git
mkdir ~/appli
cd ~/appli
mkdir data
ln -s /home/cloudforecast/git/cloudforecast/inc
ln -s /home/cloudforecast/git/cloudforecast/lib
ln -s /home/cloudforecast/git/cloudforecast/t
ln -s /home/cloudforecast/git/cloudforecast/Makefile.PL 
ln -s /home/cloudforecast/git/cloudforecast/cf_devstarter 
ln -s /home/cloudforecast/git/cloudforecast/cf_fetcher_worker 
ln -s /home/cloudforecast/git/cloudforecast/cf_updater_worker 
ln -s /home/cloudforecast/git/cloudforecast/cloudforecast_radar 
ln -s /home/cloudforecast/git/cloudforecast/cloudforecast_web 
mkdir host_config
cd host_config/
cp /home/cloudforecast/git/cloudforecast/host_config/* ./
cd ~/appli
```

```yaml:cloudforecast.yaml
---
config:
  gearman_enable: 1
  gearman_server:
    host: localhost
    port: 4730
  data_dir: data
  host_config_dir: host_config

component_config:
  SNMP:
    community: ExAmplEcOmmUnIty
    version: 2c
```

※Cloudforecastが作られた当時のものから、Gearmanのポートが変わっているので注意。

```yaml:server_list.yaml
--- #Dev
servers:
  - config: basic.yaml
    hosts:
      - 192.168.x.x sample sample system
```

```shell
cpanm -v -n -L extlib --installdeps .
mkdir service
cd service
```

```sh:radar.sh
#!/bin/sh
export HOME=/home/cloudforecast
export USER=cloudforecast
export LANG=C
export CF_DEBUG=1

cd ~/appli
./cloudforecast_radar -r -c cloudforecast.yaml -l server_list.yaml
```

```sh:web.sh
#!/bin/sh
export HOME=/home/cloudforecast
export USER=cloudforecast
export LANG=C
export CF_DEBUG=1

cd ~/appli
./cloudforecast_web -p 5000 -c cloudforecast.yaml -l server_list.yaml
```

```sh:fetcher.sh
#!/bin/sh
export HOME=/home/cloudforecast
export USER=cloudforecast
export LANG=C
export CF_DEBUG=1

cd ~/appli
./cf_fetcher_worker -c cloudforecast.yaml -max-workers 2 -max-request-per-child 100 -max-exection-time 60
```

```sh:updater.sh
#!/bin/sh
export HOME=/home/cloudforecast
export USER=cloudforecast
export LANG=C
export CF_DEBUG=1

cd ~/appli
./cf_updater_worker -c cloudforecast.yaml -max-workers 2 -max-request-per-child 100 -max-exection-time 60
```

※`LANG=C`がないと場合によってはフォントがなくてグラフが文字化けする（OS言語設定を日本語にしているなどの場合）
※`CF_DEBUG=1`はデバッグログ出力フラグなので、必要に応じて削除。

```cloudforecast_radar.service
[Unit]
Description=Cloudforecast Radar Service

[Service]
Type=simple
User=cloudforecast
ExecStart=/home/cloudforecast/appli/service/radar.sh
TimeoutStopSec=10
KillMode=mixed
PrivateTmp=true
Restart=always

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

```clouudforecast_web.service
[Unit]
Description=Cloudforecast Web Service

[Service]
Type=simple
User=cloudforecast
ExecStart=/home/cloudforecast/appli/service/web.sh
TimeoutStopSec=10
KillMode=mixed
PrivateTmp=true
Restart=always

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

```cloudforecast_fetcher.service
[Unit]
Description=Cloudforecast Fetcher Service

[Service]
Type=simple
User=cloudforecast
ExecStart=/home/cloudforecast/appli/service/fetcher.sh
TimeoutStopSec=10
KillMode=mixed
PrivateTmp=true
Restart=always

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

```cloudforecast_updater.service
[Unit]
Description=Cloudforecast Updater Service

[Service]
Type=simple
User=cloudforecast
ExecStart=/home/cloudforecast/appli/service/updater.sh
TimeoutStopSec=10
KillMode=mixed
PrivateTmp=true
Restart=always

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

```shell
chmod 755 *.sh
cd ~/appli
mkdir nginx
```

```nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;

        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
        
        location ^~ /static/ {
            root   /home/cloudforecast/App/htdocs;
            expires -1;
        }

        location / {
            proxy_pass http://127.0.0.1:5000;
        }
    }
}
```

※proxy_set_headerの部分とlocation設定の部分以外は環境に合わせて自由に組み替えて良い(はず)

```shell
cd /usr/lib/systemd/system/
ln -s /home/cloudforecast/appli/service/cloudforecast_radar.service
ln -s /home/cloudforecast/appli/service/cloudforecast_web.service
ln -s /home/cloudforecast/appli/service/cloudforecast_fetcher.service
ln -s /home/cloudforecast/appli/service/cloudforecast_updater.service
cd /etc/nginx
mv nginx.conf nginx.conf_
ln -s /home/cloudforecast/appli/nginx/nginx.conf
setenforce permissive
```

```text:/etc/selinux/config
SELINUX=permissive
```

※本当はSELinux無効化ではなくて、Nginx設定ファイルのシンボリックリンクを辿れるようにするのが良い。

# サービス起動

```shell
nginx -t
systemctl enable nginx
systemctl start nginx
systemctl enable gearmand
systemctl start gearmand
systemctl enable cloudforecast_radar
systemctl enable cloudforecast_web
systemctl enable cloudforecast_fetcher
systemctl enable cloudforecast_updater
systemctl start cloudforecast_radar
systemctl start cloudforecast_web
systemctl start cloudforecast_fetcher
systemctl start cloudforecast_updater
```