
毎日午前 9 時に開始し、午後 23 時に終了する 2 つのサービス (ビデオ プレーヤーと画像認識デーモン) があります (システムは継続的に実行されますが、起動時にも実行されます)。各サービスに対して、 と を作成しました-startup.service
。-shutdown.service
これらのサービスは と に結合され、daemon-on.target
それぞれとdaemon-off.target
によってトリガーされます。daemon-on.timer
daemon-off.timer
数回の試行とテストの後、タイマーは最初は期待どおりにターゲットをトリガーしますが、NEXT 時間が n/a に設定された状態になることがわかりました。
タイマーを使用して 2 つのアプリケーションを実行するだけでも、かなりの作業が必要です。明らかに何かが欠けていると思いますので、ヒントがあれば教えてください。
mpv-startup.service はビデオ プレーヤー サービスを開始します。
[Unit]
Description=MPV Video Player Startup
After=xorg.target
Requires=xorg.target
[Service]
Environment=DISPLAY=:0
ExecStart=/usr/bin/python3 /opt/videoplayer/app.py
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10
[Install]
Also=daemon-on.timer
recog-startup.service は画像認識サービスを開始します。
[Unit]
Description=Recog Startup Service
[Service]
Type=simple
WorkingDirectory=/opt/recog
ExecStart=/opt/recog/recog run
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=30
[Install]
Also=daemon-on.timer
mpv-shutdown.service はワンショットコマンドとしてビデオプレーヤーサービスを停止します。
[Unit]
Description=MPV Video Player Shutdown
[Service]
Type=oneshot
ExecStart=/bin/systemctl --user stop mpv-startup.service
[Install]
Also=daemon-off.timer
recog-shutdown.service は、ワンショットコマンドとして画像認識サービスを停止します。
[Unit]
Description=Recog Shutdown Service
[Service]
Type=oneshot
ExecStart=/bin/systemctl --user stop recog-startup.service
[Install]
Also=daemon-off.timer
daemon-on.target は上記の 2 つの起動サービスを組み合わせ、default.target とともに起動時に有効になります。
[Unit]
Description=Daemon Startup Target
Wants=recog-startup.service mpv-startup.service
After=recog-startup.service mpv-startup.service
[Service]
Type=oneshot
[Install]
WantedBy=default.target
Also=daemon-on.timer
daemon-off.target は上記の 2 つのシャットダウン サービスを組み合わせます。
[Unit]
Description=Daemon Shutdown Target
Wants=recog-shutdown.service mpv-shutdown.service
After=recog-shutdown.service mpv-shutdown.service
[Service]
Type=oneshot
[Install]
Also=daemon-off.timer
daemon-on.timer は、午前 9 時に daemon-on.target をトリガーするように設定されています。
[Unit]
Description=Daemon Startup Schedule
[Timer]
OnCalendar=9:00
Unit=recog-on.target
Persistent=true
[Install]
WantedBy=timers.target
daemon-off.timer は、23pm に daemon-off.target をトリガーするように設定されています。
[Unit]
Description=Daemon Shutdown Schedule
[Timer]
OnCalendar=23:00
Unit=daemon-off.target
Persistent=true
[Install]
WantedBy=timers.target
これらすべてを配置した後、~/.config/systemd/user/
次の方法で有効にします。
systemctl --user enable --now daemon-on.target
systemctl --user enable --now daemon-on.timer
systemctl --user enable --now daemon-off.timer
これにより、起動のたびにデーモンが自動的に起動し、タイマーがオプションに従ってデーモンを開始/停止することを期待しますOnCalendar=
。この時点で、systemctl --user list-timers
2 つのタイマーが適切な時間にトリガーされることがわかります (長時間待機する必要がないように、タイマーを 3 分間隔で設定したことに注意してください)。
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2019-06-26 12:12:00 JST 1min 4s left Wed 2019-06-26 11:35:02 JST 35min ago daemon-off.timer daemon-off.target
Wed 2019-06-26 12:15:00 JST 4min 4s left Wed 2019-06-26 11:40:48 JST 30min ago daemon-on.timer daemon-on.target
その後、オフ タイマーがトリガーされ、デーモンが停止します。数分後にオン タイマーがトリガーされ、デーモンが予測どおりに起動します。ただし、タイマーをもう一度確認すると、タイマーがリセットされ、NEXT/LEFT フィールドが n/a に設定されており、デーモンが再びトリガーされることはありません。ここでの問題は何でしょうか。
NEXT LEFT LAST PASSED UNIT ACTIVATES
n/a n/a Wed 2019-06-26 12:12:06 JST 4min 18s ago daemon-off.timer daemon-off.target
n/a n/a Wed 2019-06-26 12:15:33 JST 50s ago daemon-on.timer daemon-on.target
答え1
さらに少し検索して systemd のマニュアルページを読んだ後、少し簡素化して、サービスの望ましい動作を実現することができました。
まず、ファイルに [Service] セクションを入れる際にミスをしました.target
。これは意味をなさないものでした。次に、PartOf=
ビデオ プレーヤーと認識サービスをコンポーネントとして持つトップ レベル アプリケーションを作成できるステートメントを発見しました。最後に、Conflicts=
オプションを使用することで、互いに競合する 2 つのターゲットを使用してアプリケーションを開始/停止できます。.timer
これらのターゲットにアタッチされた は、互いに切り替わり、アプリケーション チェーンとそれぞれの競合する を無効または有効にします.targets
。結果は、依然として 7 つのファイルに含まれており、維持したい量を超えていますが、要求どおりに動作します。
app.service はトップレベルのアプリケーションです。ダミーではありますが、他の何かを実行することもできます。
[Unit]
Description=App Service
[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
[Install]
WantedBy=default.target
Also=app-on.timer app-off.timer
app-mpv.service はアプリのビデオ プレーヤー コンポーネントであるため、xorg にも依存します。
[Unit]
Description=App Video Player Service
PartOf=app.service
After=app.service
Requires=xorg.target
After=xorg.target
[Service]
Environment=DISPLAY=:0
ExecStart=/usr/bin/python3 /opt/videoplayer/app.py
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10
[Install]
WantedBy=app.service
app-recog.service はアプリの画像認識コンポーネントであり、ビデオ プレーヤーに依存しません。
[Unit]
Description=App Recognition Service
PartOf=app.service
After=app.service
[Service]
WorkingDirectory=/opt/recog
ExecStart=/opt/recog/recog run
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=30
[Install]
WantedBy=app.service
app-on.target は仮想ターゲットであり、app-on.timer がトリガーされるとすぐにアクティブになり、app.service が有効になります。
[Unit]
Description=App Startup Target
Conflicts=app-off.target
Wants=app.service
After=app.service
RefuseManualStart=yes
[Install]
Also=app-on.timer
app-off.target は仮想ターゲットであり、app-off.timer がトリガーされるとすぐにアクティブになり、app.service を無効にします。
[Unit]
Description=App Shutdown Target
Conflicts=app.service app-on.target
RefuseManualStart=yes
[Install]
Also=app-off.timer
app-on.timer は単に app-on.target をトリガーします。
[Unit]
Description=App Startup Schedule
[Timer]
OnCalendar=9:00
Unit=app-on.target
Persistent=true
[Install]
WantedBy=timers.target
app-off.timer は単に app-off.target をトリガーします。
[Unit]
Description=App Shutdown Schedule
[Timer]
OnCalendar=23:00
Unit=app-off.target
Persistent=true
[Install]
WantedBy=timers.target
この混乱をすべて可能にするのは(この記事):
systemctl --user enable app app-mpv app-recog
systemctl --user enable --now app-on.timer app-off.timer
systemctl --user start app
アプリケーションの実行が開始され、タイマーを確認すると、両方ともアクティブであり、先に発生したタイマーが最初に実行されます。
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2019-06-26 14:00:00 JST 1min 25s left n/a n/a app-off.timer app-off.target
Wed 2019-06-26 14:01:00 JST 2min 25s left n/a n/a app-on.timer app-on.target
オフ タイマーがトリガーされると、アプリケーションは停止しますが、app-off.target
オン ターゲットはスケジュールされたままになります。
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2019-06-26 14:01:00 JST 55s left n/a n/a app-on.timer app-on.target
n/a n/a Wed 2019-06-26 14:00:04 JST 3ms ago app-off.timer app-off.target
オン タイマーがトリガーされると、アプリケーションが起動し、が無効になりますapp-on.target
が、オフ タイマーが再び有効になります。
NEXT LEFT LAST PASSED UNIT ACTIVATES
Thu 2019-06-27 14:00:00 JST 23h left Wed 2019-06-26 14:00:04 JST 57s ago app-off.timer app-off.target
n/a n/a Wed 2019-06-26 14:01:01 JST 5ms ago app-on.timer app-on.target
そして、このサイクルは続きます。これが設定の最善の方法であるかどうかはまだ疑問なので、他の提案もぜひ聞きたいです。