1 つの systemd ユニット ファイルで 2 つの異なる ExecStart コマンドを条件付きで実行するにはどうすればよいですか?

1 つの systemd ユニット ファイルで 2 つの異なる ExecStart コマンドを条件付きで実行するにはどうすればよいですか?

したい条件付きでどちらか一方を実行するこれらのコマンド(または両方)をシングルsystemd ユニットファイル:

ExecStart=/usr/bin/ssh-keygen -t rsa -b 4096
ExecStart=/usr/bin/ssh-keygen -t ed25519 -a 32

最初のものは、次の条件で実行されます。

ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key.pub

2 番目は、次の条件で実行されます。

ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key.pub

両方のキーが欠落しているか、片方だけが欠落しているか、どちらも欠落していない可能性があります。明らかに、キーが存在する場合は、それを再生成したくありません。私の質問は ssh キーに関するものですが、概念はどの systemd ユニット ファイルにも適用できるはずです。ユニット ファイルでこれを行う一般的な方法があれば、ここでも機能するはずです (私はそう思います)。

背景は次のとおりです。

/usr/lib/systemd/system/sshd.service含まれるもの:

Wants=sshdgenkeys.service

の標準的な内容は/usr/lib/systemd/system/sshdgenkeys.service次のとおりです。

[Unit]
Description=SSH Key Generation
ConditionPathExists=|!/etc/ssh/ssh_host_dsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_dsa_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_ecdsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_ecdsa_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key.pub
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key.pub

[Service]
ExecStart=/usr/bin/ssh-keygen -A
Type=oneshot
RemainAfterExit=yes

そのユニットファイルに関する問題はいずれかのキータイプが欠落している場合は、すべてが再生成されます。dsa キーと ecdsa キーを削除する予定です。したがって、2 つのキー タイプのみをチェックし、不足している特定のキーのみを再生成する必要があります (ある場合)。

これを実現する方法を教えてください。関連しているが異なる質問があります:systemd ユニット ファイルからオプションを削除する (上書きしない、新規作成しない) 方法は?これら 2 つの質問は独立しており、ユニット ファイルの操作の異なる側面に関係しています。この質問は、さまざまなコマンドを条件付きで実行することに関するもので、もう 1 つの質問は、ユニット ファイルから標準オプションを削除することに関するものです。

答え1

条件はユニット全体にのみ適用され、ユニット内の個々のジョブ仕様には適用されません。

したがって、一部のジョブを条件付きで実行するには、それらのジョブ仕様は、最終的なアクションを実行する前に、それ自体でチェックを行う必要があります。

fe. このように:(テストはしていません。オンラインで書いているだけです)

ExecStart=bash -c \
'\
  if test ! -f /etc/ssh/ssh_host_rsa_key -o ! -f /etc/ssh/ssh_host_rsa_key.pub; then\
    /usr/bin/ssh-keygen -t rsa -b 4096;\
  fi\
' 'my-rsa-key-gen'
ExecStart=bash -c \
'\
  if test ! -f /etc/ssh/ssh_host_ed25519_key -o ! -f /etc/ssh/ssh_host_ed25519_key.pub; then\
    /usr/bin/ssh-keygen -t ed25519 -a 32;\
  fi\
' 'my-ed25519-key-gen'
1. `$$` は、systemd が `$` 自体を解釈するのを防ぐためのものです。\ `man systemd.service` セクションの「コマンドライン」から:
リテラルドル記号を渡すには、「$$」を使用します。
2. 暗黙的な `exit` コマンドは、それぞれ `ssh-keygen` のステータスを返し、ユニットが失敗するのを防ぎます。

最良の結果と容易さを得るために、すべての条件付き実行を 1 か所で実行する外部スクリプトを作成することをお勧めします。

関連情報