我对 Puppet 还不太熟悉,想知道是否有办法仅在 Exec 发起的命令完成其工作后才应用资源。我的需求是,我应该仅在另一项工作完成后才安排备份工作。下面给出的代码不起作用。一旦启动主备份作业,cron 就会被安排。
编辑:在容器的生命周期内,我只需要运行一次主要作业(使用 docker)。主要备份作业可能需要长达 5 个小时,而次要备份作业则需要大约 1 个小时。Primary-backup-script.py 使用 subprocess.popen 模块来启动作业,该作业在后台分叉,但我认为这并不重要。如果我错了,请纠正我。
exec{ 'primary-backup-job':
command => '/path/primary-backup-script.py',
require => File['/path/primary-backup-script.py'],
refreshonly => true,
}
# Schedule cron job only after primary backup is completed.
cron{ schedule-secondary-backup:
command => "/path/secondary-backup-script.py",
require => Exec['primary-backup-job'],
user => root,
hour => 05,
minute => 00,
weekday => 1-5;
}
有什么想法或建议吗?
答案1
您使用工具的方式不正确。Puppet 是一种声明性语言 - 意思是 - 您应该使用 Puppet 声明状态,而不是协调事物。当然,您可以这样做,但这更难,看起来很笨拙,而且容易出错。
使用 puppet 时,应尽可能避免使用“exec”资源。为什么?因为 exec 位于“状态机”的外部 - 这意味着 exec 将以(对于 puppet 而言)不受控制且未知的方式修改系统。
将其他资源链接到 exec 甚至可能会使情况变得更糟。
下一个问题是 puppet 不是 cron 作业,因此您应该避免通过 Puppet 本身的“exec”运行作业。这就是我们有 cron 的原因。
在您的具体情况下,将 cron 作业创建一行添加到原始脚本末尾不是更简单吗?您将获得多种好处:
- 无需实施复杂且容易出错的黑客来向其他进程发送消息
- 无需实施看门狗
- 无需调试各种问题将要从该解决方案中得出。
如果可能的话,只需在原始第一个备份脚本的末尾添加 cron 创建即可。如果它是专有工具或脚本,并且您无法编辑它,只需创建简单的 bash 包装器,然后通过 exec 资源调用该包装器。
如果您想从 puppet 本身管理 cron,您仍然可以这样做,但尽量避免将 exec 和 cron 资源链接在一起。
在这种情况下我会做什么(你想要/必须从 Puppet 代码管理 cron):
cron { schedule-secondary-backup:
command => "pgrep primary-backup-script && echo 'still running' || /path/secondary-backup-script.py",
user => root,
hour => 05,
minute => 00,
weekday => 1-5;
}
另一个解决方案是修改主脚本,使其在执行完成时在文件系统上创建一个文件,并在以前的资源定义中使用以下 cron 命令:
command => "[ ! -e /path/to/first_script_finished_file ] && /path/secondary-backup-script.py",
希望这可以帮助。
答案2
嗯。。好吧,因为它在后台运行,所以很难在它完成后触发某些响应。你觉得将辅助任务切换到以下任务怎么样:
exec { 'secondary-backup':
command => "/path/secondary-backup-script.py",
unless => "/bin/ps -ef | /bin/grep primary-backup-script",
}
..将 grep 参数设置为可以找到主要备份过程的某个值?
在主备份完成后,这将使辅助备份在下次 Puppet 运行时启动。