问题描述
这是一个普遍的Upstart问题,但让我使用一个特定的案例:
Centrify是ActiveDirectory网关的NIS。它需要在依赖于它提供的身份验证服务的任何服务之前加载,例如, autofs,cron,nis,et al。
事实证明这很难实现,即使在尝试更改其他服务的依赖关系时(我认为我们不应该这样做,我也不想触及其他Upstart工作,如果可能的话) 。
建议?
最佳解决方案
解决方案是从另一个方向解决问题:为了满足Centrify的启动标准,不必使现有服务依赖于新的Centrify服务,而是使新的Centrify服务依赖于现有服务。
例如,Upstart配置文件/etc/init/centrify.conf
可以说:
start on (starting cron or starting autofs or starting nis)
将其转换为英语,这将转换为:
start the Centrify service just before either cron, autofs or nis start (whichever starts first).
cron,autofs或nis启动的顺序无关紧要:Upstart将确保Centrify将在任何服务首先启动之前启动,从而确保Centrify在任何一个服务启动之前运行。
另请注意,Upstart将阻止第一个要启动的服务的启动,直到Centrify开始运行。
一旦你习惯于以这种方式思考,就会非常优雅和简单。
次佳解决方案
詹姆斯的答案适用于1对1的依赖。对于1到多,即为了确保服务A在服务B,C和D之前开始,您需要采取另一种方法。您可以查看当前的portmap脚本以供参考,但这是一般方法:创建一个等待脚本。
场景:您希望服务A始终在service-b,service-c和service-d之前运行。
解决方案:为服务A创建等待脚本。将其命名为”/etc/init/service-a-wait.conf”
# service-a-wait
start on (starting service-b
or starting service-c
or starting service-d)
stop on (started service-a or stopped service-a)
# We know that we have more than one job that needs to wait for service-a and
# will make use of this service, so we need to instantiate.
instance $JOB
# Needed to make starting the job successful despite being killed
normal exit 2
task
script
status service-a | grep -q "start/running" && exit 0
start service-a || true
# Waiting forever is ok.. upstart will kill this job when
# the service-a we tried to start above either starts or stops
while sleep 3600 ; do :; done
end script
这意味着简单的英语是:当服务b,c或d表示他们想要启动时,他们必须等待开始直到service-a正在运行。 service-a-wait作业设计为在service-a启动之前运行。一旦service-a-wait退出,现在服务b,c和d可以自由进行和运行。
这将确保service-a在其任何反向依赖项尝试启动之前启动并运行。
注意:“实例$ JOB”行在“start on …或..或..”场景中很重要。否则你只会先阻止B,C或D中的任何一个发射。
(实例化应该诚实地得到更好的解释。现在,就这样做。;)