ソケットでサービスを停止する

ソケットでサービスを停止する

リモートでサービスを停止するのに問題があります。

シンプルなソケット/サービスペアがあります。

# /etc/systemd/system/foo.socket
[Unit]
Description=The socket

[Socket]
ListenStream=11111
# /etc/systemd/system/foo.service
[Unit]
Description=The service

[Service]
Type=simple
ExecStart=sleep infinity

その後はsystemctl start foo.socket次のようになります。

foo.socket:  active (listening)
foo.service: inactive (dead)

その後、他のシステムへの接続を確立すると、次のような結果がnetcat 10.10.1.16 11111得られます。

foo.socket:  active (running)
foo.service: active (running)

完璧!

SIGTERMこれで接続(to)を終了すると、netcat次のようになります。

foo.socket:  active (running)
foo.service: active (running)

しかし、私は次のように予想しました。

foo.socket:  active (listening)
foo.service: inactive (dead)

TCP接続を使用してリモートでサービスを停止する方法は?

私は試した:

  • Accept=yesそして[email protected]
  • サービスを提供PartOf=foo.socketするRequires=foo.socket
  • StandardInput=socketそして標準出力と標準エラー。

ベストアンサー1

代わりに/bin/sleep infinity別のものを実行したいと思います。

[Service]
Type=simple
ExecStart=foo
StandardInput=socket

次はどこですかfoo

#include <stdio.h>
int main(int, char**) {
  char buf[256];
  while(scanf("%255s",buf) > 0) {}
  return 0;
}
#!/bin/sh
while read line; do
  echo "$line"
done < "${1:-/dev/stdin}"
#!/usr/bin/python3
import sys
for line in sys.stdin:
    pass
#!/usr/bin/perl
while (<>) {
  if (eof()) { exit }
}

説明する:

サービスを使用すると、プロセスが終了Type=simpleするとすぐにサービスが停止しますExecStart。したがって、接続を閉じてもアプリケーションを終了する必要があることがわからないため、サービスは停止されません。 SystemdはSIGTERMを送信せず、それも必要ありません。

ExecStart代わりに、同じことを行う4つのプロセス(C、sh、python、perl)の実装を提供します。つまり、stdin が使用できなくなるまで stdin から読み込みます。接続が閉じられると、ストリームは終了します。これはstdinが終了することを意味します。したがって、EOFが得られるまでstdinを読み続け、終了します。プロセスが終了すると、サービスは停止します。


組み込み機能

上記のスクリプトのいずれかをデプロイしたくない場合は、stdinを受け取り、EOFで終了する組み込みツールの1つを使用してください。副作用は彼らが実際に何かをするかもしれないということです。最初に考えられるのはですgrep -EXIT_FAILURE一致するものがない場合は返されるので、-接続が閉じられるたびにサービスが失敗しないようにプレフィックスを付けます。

[Service]
Type=simple
ExecStart=-/bin/grep -
StandardInput=socket

このプロセスを活用するのが楽しいと思う場合は、接続を介して役に立つことができます。私が考えることができる2番目のプログラムはpython3。これで、通訳者全体がアイドル状態で座って、あなたのために何かをすることができます。サンドボックスを追加していませんが、systemdが機能していると危険ですDynamicUser=

[Service]
Type=simple
ExecStart=/usr/bin/python3
StandardInput=socket
DynamicUser=yes

クライアント側で接続が確立されていることを確認するには、catまず次の定型句テキストを作成することをお勧めします。

echo "established" > /usr/local/etc/simple/start_text

次に、systemdにそのテキストをキャットし、stdinを指定するように指示します。

[Service]
Type=simple
ExecStart=-cat /usr/local/etc/simple/start_text -
StandardInput=socket

netcat接続が確立されると、クライアントは印刷物を受け取ります。

Accept=yesandを使用する必要があることにも注目する価値があります[email protected]。それ以外の場合、systemdはアプリケーションが着信接続を受け入れることを期待しますが、ここではそうではありません。

おすすめ記事