systemdでユニットファイルを作ってサービス化してみる

## 勉強前イメージ

Unitファイル作って結構めんどくさいことしないといけない？
ちょっとsystemdの仕組み勉強したくらいでいけるのかな....

## 1. コマンドを作成

- スクリプトの作成

```
vi /usr/local/bin/qiita-test.sh
```

```sh:/usr/local/bin/qiita-test.sh
#!/bin/bash

while true
do
   echo "hello world" >> /var/tmp/qiita-test.log
   sleep 1
done
```

- 実行権限を付与

```
chmod 755 /usr/local/bin/qiita-test.sh
```

## 2. Unitファイルの作成

- Unitファイルの作成

```
vi /etc/systemd/system/qiita-test.service
```

```sh:/etc/systemd/system/qiita-test.service
[Unit]
Description=qiita-test
After=network.service

[Service]
Type=simple
ExecStart=/usr/local/bin/qiita-test.sh
ExecStop=/bin/kill -WINCH ${MAINPID}
Restart=always

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

- Unit
	- Description : このユニットの説明。systemctl status の時に表示される「● qiita-test.service - (qiita-test)」  () の中のやつ
	- After : 設定するユニットの前に起動するユニット
- Service
	- Type : プロセスの起動方法
		- simple :  デフォルトで、プロセスが起動した時点で起動完了とし、実行が可能になるする
		- forking : フォークして親プロセスが終了した時点で起動完了とする
		- oneshot : 次のユニットを実行する前に自身のプロセスを終了する
		- dbus : D-Bus を使うプロセスで、D-Bus の接続名を見つけると起動完了
		- notify : d_notify() 関数で起動完了のメッセージを受け取ったときに起動完了とする
		- idle : 他のジョブが終了するまで待機する
	- ExecStart : 起動時に実行するコマンドで、ここではスクリプトのパスを指定
	- ExecStop : 停止時に実行するコマンド
	- Restart : 再起動時のコマンドで、プロセスが停止し再起動の際の条件を指定
		- always :  常に再起動
		- no : 再起動しない
		- on-success : 終了コードが0の際に再起動する
		- on-failure : 終了コードが0以外の際に再起動する
- Install : インストール時の設定
	- WantedBy : enable時にこのユニットの.wantsディレクトリにリンクを作成する。↓で自動起動設定をいれましたが、/etc/systemd/system/multi-user.target.wants/qiita-test.service にシンボリックリンク貼られました

## 3. qiita-test.serviceがServiceとして認識されているか確認

`systemctl list-unit-files` を使用
このコマンドは、定義されているサービス一覧を見ることが出来ます。

```sh:定義ファイル一覧から確認
[root@localhost ~]# systemctl list-unit-files --type=service | grep qiita
qiita-test.service                            disabled
```

## 4. qiita-test.serviceを起動させる

- 起動前のstatusを確認

```
[root@localhost ~]# systemctl status qiita-test.service
● qiita-test.service - qiita-test
   Loaded: loaded (/etc/systemd/system/qiita-test.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
```

- 起動を行う

```
[root@localhost ~]# systemctl start qiita-test.service
[root@localhost ~]# 
```

- 起動後のstatusを確認

`active` になってます！動いてる！

```
[root@localhost ~]# systemctl status qiita-test.service
● qiita-test.service - qiita-test
   Loaded: loaded (/etc/systemd/system/qiita-test.service; disabled; vendor preset: disabled)
   Active: active (running) since 金 2020-12-04 22:27:41 JST; 7s ago
 Main PID: 2114 (qiita-test.sh)
   CGroup: /system.slice/qiita-test.service
           ├─2114 /bin/bash /usr/local/bin/qiita-test.sh
           └─2122 sleep 1

12月 04 22:27:41 localhost.localdomain systemd[1]: Started qiita-test.
```

- プロセスを確認

実行されてますね

```
[root@localhost ~]# ps aux | grep [q]iita-test
root      2114  0.0  0.0 115408  1480 ?        Ss   22:27   0:00 /bin/bash /usr/local/bin/qiita-test.sh
```

- スクリプトの中身が実行されていることを確認

`echo "hello world" >> /var/tmp/qiita-test.log` を記述しているので、 /var/tmp/qiita-test.log を確認
出力されてます

```sh:/var/tmp/qiita-test.log 
[root@localhost ~]# head /var/tmp/qiita-test.log 
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
```

- 停止させる

停止出来て、inactiveになりました

```
[root@localhost ~]# systemctl stop qiita-test.service
[root@localhost ~]# systemctl status qiita-test.service
● qiita-test.service - qiita-test
   Loaded: loaded (/etc/systemd/system/qiita-test.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

12月 04 22:27:41 localhost.localdomain systemd[1]: Started qiita-test.
12月 04 22:30:21 localhost.localdomain systemd[1]: Stopping qiita-test...
12月 04 22:30:21 localhost.localdomain systemd[1]: Stopped qiita-test.
```

- 自動起動設定を入れる

自動起動設定を入れました

```
[root@localhost ~]# systemctl enable qiita-test.service
Created symlink from /etc/systemd/system/multi-user.target.wants/qiita-test.service to /etc/systemd/system/qiita-test.service.
[root@localhost ~]# systemctl list-unit-files --type=service | grep qiita
qiita-test.service                            enabled 
```

シンボリックリンクもはられています

```
[root@localhost ~]# ll /etc/systemd/system/multi-user.target.wants/qiita-test.service
lrwxrwxrwx 1 root root 38 12月  4 22:33 /etc/systemd/system/multi-user.target.wants/qiita-test.service -> /etc/systemd/system/qiita-test.service
```

再起動を行います

```
[root@localhost ~]# reboot
```

自動で立ち上がっていることを確認

```
[root@localhost ~]# systemctl status qiita-test.service
● qiita-test.service - qiita-test
   Loaded: loaded (/etc/systemd/system/qiita-test.service; enabled; vendor preset: disabled)
   Active: active (running) since 月 2020-08-31 17:03:17 JST; 3 months 3 days ago
 Main PID: 1013 (qiita-test.sh)
   CGroup: /system.slice/qiita-test.service
           ├─1013 /bin/bash /usr/local/bin/qiita-test.sh
           └─1506 sleep 1

 8月 31 17:03:17 localhost.localdomain systemd[1]: Started qiita-test.
```

## 勉強後イメージ

案外すっと動いた！
実際にコピペでもUnitファイル作成したらどうやったらreloadさせれるとか、こういうときこうしたいとかわかるし、理解が進むから結構楽しかった。
もっと苦戦すると思ったw



## 参考

- [ユニット定義ファイルの使い方](https://qiita.com/hana_shin/items/b1a269dbee6d96cb3ace)
- [systemd のユニットファイルの作り方](https://tex2e.github.io/blog/linux/create-my-systemd-service)
- [Systemdを使ってさくっと自作コマンドをサービス化してみる](https://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff)
- [Systemd入門(4) - serviceタイプUnitの設定ファイル](https://enakai00.hatenablog.com/entry/20130917/1379374797)
- [Systemd Unit File チートシート](https://qiita.com/ukiuni@github/items/400e4fdaae14b9bc0fcf)
- [CentOS7で使われているsystemctlについて少しまとめた](https://qiita.com/tukiyo3/items/092fc32318bd3d1a0846)