クラウド仮想マシンで定期的なタスクが実行されています。このマシンタイプは非常に高価であるため、起動時に起動してスクリプトを実行し、マシンをシャットダウンしてコストを節約するsystemdデバイスサービスがあります。これは設計どおりに機能します。
ログインしてservice [] stop
コマンドを実行すると、当然システムが即座にシャットダウンされるため、システムを保守することが困難になります。
私はこれが利用可能でなければならないと思いますOnFailure
が、何らかの理由でスクリプトが失敗した場合(衝突時にVMが回転するのではなく)、システムがシャットダウンしたいと思います。またはいくつかの用途ExecStop
?
3つの状況が発生します。
- プロセスが正しく実行され、シャットダウンされます(例:終了コード0)、システムの電源が切れます。
- プロセスの競合 (例: 終了コード != 0)、システムの電源切断
- ユーザーによってサービスが終了/中断されましたか?システムの電源が入っている
簡単な解決策は、開始、ログイン、無効化、再起動(サービスがすでに開始されているため)、メンテナンスタスクの実行、および再起動する前に、サービスに1分の猶予期間を提供することです。ところでこれはちょっと混乱しているようです。参考までに、サービス定義は次のとおりです。
[Unit]
Description="Run job"
After=network.target
StartLimitInterval=200
StartLimitBurst=30
OnFailure=systemd-poweroff.service
[Service]
Type=simple
Restart=on-failure
RestartSec=30
ExecStartPre=/bin/sleep 60
ExecStart=/my/script.sh
ExecStopPost=sudo systemctl poweroff -i
User=foo
[Install]
WantedBy=multi-user.target
セキュリティ認識ではなく、環境設定によりスクリプトが通常のユーザーとして実行されるため、ここではsudoが使用されます(このアカウントには、電源を切るためのパスワードのないsudo権限が特別に付与されます)。
ベストアンサー1
poweroff
アクションで実行するのではなく、ExecStopPost
別のサービスに移動してください。つまり、「ジョブ実行」サービスを次のようにしてください。
[Unit]
Description="Run job"
After=network.target
Requires=my-poweroff.service
Before=my-poweroff.service
[Service]
Type=oneshot
Restart=on-failure
RestartSec=30
ExecStart=/my/script.sh
User=foo
[Install]
WantedBy=multi-user.target
スクリプトが完了するまでサービスが「起動」されないため、Type=oneshot
代わりに使用しています。を使用して/dependentを介して停電をトリガーすると、この操作と終了操作が開始されるType=simple
ため、これは重要です。Requires=
Before=
Type=simple
同時に。使用は、Type=oneshot
サービスが終了するまでシャットダウンジョブが実行されないことを意味します。
次に、my-poweroff.service
次のようになります。
[Unit]
ConditionPathExists=!/run/nopoweroff
[Service]
Type=simple
ExecStart=/usr/bin/systemctl poweroff -i
これで、「ジョブの実行」サービスが完了するまでpoweroff
ブロックします。touch /run/nopoweroff