Systemd - パスワードなしのsudoを使用してユーザースペースでノードプロセスを再起動する方法

Systemd - パスワードなしのsudoを使用してユーザースペースでノードプロセスを再起動する方法

root以外のユーザーとして実行されるnodejsプロセスがあります(これを行う必要がある理由があります)、ラズベリーパイgpio割り込みへのルートアクセスを必要とする依存関係があります。したがって、解決策は、gpioノードを実行するためのsudoersエントリを持つrpiグループを持つことでした。その後、サービス単位ファイルでこのスクリプトを起動すると正常に動作します。

[Unit]
Description=switches16-mcp230xx-dSxJM-interrupt Device Starter Service
After=network-online.target

[Service]
Environment=UCI_ENV=pro
ExecStart=/usr/bin/sudo /usr/bin/node -r esm /opt/light/switches16-mcp230xx-dSxJM-interrupt/index.js
Restart=on-failure
WorkingDirectory=/opt/light/switches16-mcp230xx-dSxJM-interrupt

[Install]
WantedBy=default.target

再起動(または再起動の失敗)時に問題が発生します。プロセスを終了する必要がありますが、sudoで始まったので、当然sudoでも終了する必要があります。

Mar 12 19:43:12 switches systemd[1289]: switches16-mcp230xx-dSxJM-interrupt.service: Failed to kill main process 11222 (sudo), ignoring: Operation not permitted
Mar 12 19:43:12 switches systemd[1289]: switches16-mcp230xx-dSxJM-interrupt.service: Killing process 11223 (node) with signal SIGKILL.
Mar 12 19:43:12 switches systemd[1289]: switches16-mcp230xx-dSxJM-interrupt.service: Failed to kill control group /user.slice/user-1000.slice/[email protected]/switches16-mcp230xx-dSxJM-

したがって、ユニットファイルはrootではなくユーザーとして開始されたため、ユーザーとして終了するため、開始時に意図的にsudoを使用してプロセスを終了する必要があるとします。だからこれを追加しました。

ExecReload=/usr/bin/sudo /bin/kill -HUP $MAINPID

しかし、同じエラーが発生しました。私のsudoers.dファイル

%gpio ALL=NOPASSWD: /usr/bin/node
%gpio ALL=NOPASSWD: /bin/kill

ここに何か落ちたに違いありませんが、指摘することはできません。

これはユニットファイルによって生成されたプロセスであるため、再起動する前に終了する必要があります。

root     11093  0.0  0.3   8468  2920 ?        Ss   18:01   0:00  \_ /usr/bin/sudo /usr/bin/node -r esm /opt/light/switches16-mcp230xx-dSxJM-interrupt/index.js
root     11094  6.7  4.8 142820 45788 ?        SLl  18:01   6:52      \_ /usr/bin/node -r esm /opt/light/switches16-mcp230xx-dSxJM-interrupt/index.js

どんな提案がありますか?

このサービスをrootとして実行できないことをもう一度強調します。したがって、これは明らかに簡単な答えなので、提案する必要はありません。このコードを配布してrootアクセスキーなしでSSH経由で実行するので、パスワードのないsudoを使用してユーザーとして実行することが唯一のオプションです。私のコードに特定のハードウェア(ルート)依存関係がなかった場合、この問題はまったく発生しませんでした。

関連情報