![根据配置有条件地阻止 systemd 启动](https://linux22.com/image/733702/%E6%A0%B9%E6%8D%AE%E9%85%8D%E7%BD%AE%E6%9C%89%E6%9D%A1%E4%BB%B6%E5%9C%B0%E9%98%BB%E6%AD%A2%20systemd%20%E5%90%AF%E5%8A%A8.png)
过去几个小时我一直在努力解决这个问题,据我了解,几乎没有任何直接的解决方法。我有一个名为已配对,它存储在某个 .conf 文件中。如果此配置设置为 false,我想阻止该服务启动以及运行其初步步骤。
进一步的背景:主服务是一项长期运行的服务。它是更大的整体应用程序的一部分。此服务仅在主应用程序与其他应用程序配对后才需要运行。IS_PAIRED 配置由同一应用程序中的另一个服务控制。无法说出何时设置它 - 这是用户的选择。应用程序中的所有其他服务只能在设置 IS_PAIRED 后启动。否则,启动它们毫无意义。IS_PAIRED 参数是持久的。设置后,服务需要在启动时加载。
我已从此开始:
[Service]
Restart=on-failure
ExecStartPre=/bin/grep -q '^IS_PAIRED=true$' /etc/p.conf
ExecStartPre=/bin/sh -c "echo 'aaa' > /vagrant/b.sh"
ExecStart=/vagrant/a.sh
ExecStopPost=/vagrant/utils/bin/delay_service_restart.sh test
[Install]
WantedBy=multi-user.target
当发生什么时已配对不正确的是,systemd 失败,运行 PostStop,然后继续重新启动。我不希望发生这种情况。如果没有设置此配置,服务应该处于非活动状态。我不想切换重新开始值中止时,因为有时长时间运行的进程(称为灰这里)将捕获异常并以错误关闭,而不是被信号杀死。
接下来,我尝试了这个(该服务名为测试):
[Service]
Restart=on-failure
ExecStartPre=/bin/bash -c "grep -q '^IS_PAIRED=true$' /etc/p.conf || systemctl stop test"
ExecStartPre=/bin/sh -c "echo 'aaa' > /vagrant/b.sh"
ExecStart=/vagrant/a.sh
ExecStopPost=/vagrant/utils/bin/delay_service_restart.sh test
[Install]
WantedBy=multi-user.target
现在发生的是第二个执行开始前在服务停止之前执行。这对我来说不太好,因为在实际代码中有一些初始化,我不想在没有设置配置的情况下允许它们。
在我最后一次尝试的时候,事情变得非常奇怪:
[Service]
Restart=on-failure
ExecStartPre=/bin/bash -c "grep -q '^IS_PAIRED=true$' /etc/p.conf || { systemctl stop test; /bin/false; }"
ExecStartPre=/bin/sh -c "echo 'aaa' > /vagrant/b.sh"
ExecStart=/vagrant/a.sh
ExecStopPost=/vagrant/utils/bin/delay_service_restart.sh test
[Install]
WantedBy=multi-user.target
我以为我在这里耍花招,但不,第二个执行开始前仍然运行。我以为我疯了,所以我验证了第一个确实会产生错误:
vagrant@ubuntu-bionic:~$ sudo /bin/bash -c "grep -q '^IS_PAIRED=true$' /etc/p.conf || { systemctl stop test; /bin/false; }"
vagrant@ubuntu-bionic:~$ sudo echo $?
1
总的来说,我很迷茫,我有两个问题:
我该如何实现我想要的逻辑?我看到两种我不喜欢的可能解决方案:
- 将配置检查作为一项服务。这是错误的。它根本不像服务。
- 创建一个包装器运行器,其中检查是首先要做的事情。好吧,我目前正在将一个逻辑组织的 upstart 迁移到这个 systemd 中。在 upstart 中,这个检查是在预启动中,这是正确的。它在逻辑上属于这个。否则,我必须开始为每种类型的服务创建单独的包装器 - 其中一些是 Java,一些是 C++,一些有额外的预启动操作,并且都具有这个先决条件。
- 拥有设置已配对在配置文件创建一个文件,然后使用条件路径存在指令。这是我唯一愿意考虑的指令,但它确实很糟糕。
如果没有正确的方法 - 为什么我的最后一次破解不起作用?:(
答案1
或许ExecCondition=
可以帮助?
[Service]
ExecCondition=/usr/bin/myapp-exec-condition
myapp-exec-condition
仅当以状态 0 退出时,应用程序才会启动。