仕事を開始するときに出勤記録をつける必要がある。 便利なことにCLIがあるので*1これを叩けば出勤記録をつけることができる。
$ syukkin
しかしながら、これを忘れることがあるので自動化したい!というのが目的。
NetworkManager Dispatcher
結論からいうとNetworkManagerのDispatcherを使うことにした。
これを使うとネットワークに関連するイベントが発生したときに任意のスクリプトを実行することができる。
実行したいスクリプトは実行権限をつけて /etc/NetworkManager/dispatcher.d
配下に配置すると実行される。
ちゃんと確認していないけど、ファイル名順に実行されるっぽい。
今回は 99-dakoku
というファイル名にした。
➜ ls -lah /etc/NetworkManager/dispatcher.d/99-dakoku .rwxr-xr-x root root 378 B Wed Jul 31 20:20:08 2019 99-dakoku
スクリプトには各種環境変数が渡されるので、これを見て動作を変える。 様々な環境変数があるが、今回利用したのは以下の2つである。
$NM_DISPATCHER_ACTION
: どういうアクションによってスクリプトが実行されたかが格納される$CONNECTION_UUID
: コネクションプロファイルのUUID(後述)
$NM_DISPATCHER_ACTION
はわかりやすく、 up
とか down
とかが入る。
$CONNECTION_UUID
はNetworkManagerで管理されているプロファイルのUUIDになる。
これは、 nmcli connection
で確認できる。
➜ nmcli connection NAME UUID TYPE DEVICE **** 5f5bba80-6de6-476d-8cce-424bfe256558 vpn wlp2s0 **** 29b52b22-1937-4bb7-b05b-f6eb2af0bbbb wifi wlp2s0 **** c1d3d458-8029-495b-9350-39424ab2eb06 tun tun0
$NM_DISPATCHER_ACTION
だけではどのネットワークに接続されたのかがわからないため、$CONNECTION_UUID
も確認することで特定することができる。
今回は、オフィスのWiFiに接続した時に実行したいのでオフィスWiFiのUUIDを指定した。
完成したスクリプト
雑に多重実行の防止をいれて*2完成
#!/bin/bash PROFILE_UUID="***" STATE="/var/lib/NetworkManager/dakoku" if [ "$NM_DISPATCHER_ACTION" != "up" -o "$CONNECTION_UUID" != "$PROFILE_UUID" ]; then exit 0; fi PREV="`cat $STATE 2> /dev/null || echo 0`" NOW="`date +%Y%m%d`" if [ $PREV -ge $NOW ]; then exit 0 fi /usr/local/bin/syukkin result="$?" echo $NOW > $STATE exit 0
デバッグする場合は /var/log/syslog
をnm-dispatcher でgrepすると何かがわかるはず。
おわりに
NetworkManagerのDispatcherを使って、オフィスでPCを起動すると自動で出勤記録をつけられるようになった! これが実際便利で、オフィスに来てから何も考えずにPCを起動して仕事を開始することができるようになった。 また、このスクリプトには含まれていないけど出勤記録をつける時に会社Slackに出勤したことを通知することで、リモートワークしている人にも出勤したことが伝わってとても便利。
ちなみに、退勤記録は自動化していない。 というのも同じような仕組みで実装しようとすると、WiFiが切断されたときに実行されることになるのでスタンドアローン状態になり記録することができない。。 まぁ、私は区切りをつける意味で退勤するときはtaikinコマンドを実行することにしているので困ってはいない。
おまけ: /etc/network/{if-down.d,if-post-down.d,if-pre-up.d,if-up.d} との使い分け
Ubuntuには /etc/network
配下に if-up.dなどのディレクトリがあり、この配下にスクリプトを置くと今回やったことと同じことができる。
ではどちらを使えばいいのだろうか? 🤔
実は、 /etc/network
配下のスクリプトは NetworkManager Dispatcher を使って実装されている。
/etc/NetworkManager/dispatcher.d/01-ifupdown
というスクリプトがあり、このスクリプトから /etc/network
配下のスクリプト群を呼び出す仕組みになっているようだ。