我正在编写一个Puppet模块来执行配置并在需要时重新启动服务。我想做这样的事情:
class app_cfg {
$app_files = ['file1', 'file2', 'file3']
$app_files.each |String $file| {
exec {"sed -i 's/bar/foo/g' $file":
path => ['/bin'],
onlyif => 'grep "bar" $file 2>/dev/null',
cwd => '/opt/app/config/',
}
} ~>
service { 'app':
ensure => running,
enable => true,
}
}
我可以在exec内添加“ notify”,但是我不想为每个文件重新启动服务,并且每次循环后,通知链接箭头似乎都无法使用。你们有什么想法如何使它起作用吗?
非常感谢:)
我发现了一种解决方法,方法是在exec资源中插入for循环,而不是使用每个循环:
class app_cfg {
service { 'app':
ensure => running,
enable => true,
}
exec {"for file in file1 file2 file3; do sed -i 's/bar/foo/g' \$file; done":
path => ['/bin'],
onlyif => 'grep "bar" $file 2>/dev/null',
cwd => '/opt/app/config/',
provider => shell,
notify => Service['app']
}
}
我仍然对第一个解决方案感到好奇!您曾经做过类似的事情吗?
谢谢!
答案 0 :(得分:2)
我可以在exec内添加“ notify”,但我不想重新启动我的 服务,每个文件看起来像是通知链接箭头 每次循环后都不起作用。
重要的是要理解,Puppet清单中的代码仅描述如何构建目录,而该目录随后又描述了服务器的所需配置。目录列出了声明的类和资源,它们的参数和属性以及它们之间的关系。清单中的逻辑未映射到应用结果目录时执行的操作;它仅反映在分类了哪些类和资源以及它们的参数,属性和关系是什么。
因此,当您在清单中使用链接箭头之一时,就是在指示目录构建器记录目录中两个资源之间的关系,而不是显式的指示来应用或刷新资源。没有声明的资源会被应用一次以上或刷新一次。因此,将合适的链表达式放入循环中会很好,但是您不能做的就是将Service
声明本身放入循环中,因为这样会产生多个声明。因此,您可以执行以下任何操作:
声明一次服务,并在循环内的链表达式中使用对该资源的引用:
class app_cfg {
service { 'app':
ensure => running,
enable => true,
}
['file1', 'file2', 'file3'].each |String $file| {
exec {"sed -i 's/bar/foo/g' $file":
path => ['/bin'],
onlyif => 'grep "bar" $file 2>/dev/null',
cwd => '/opt/app/config/',
} ~> Service['App']
}
}
如上所述,但是使用适当的资源元参数代替链表达式:
class app_cfg {
service { 'app':
ensure => running,
enable => true,
}
['file1', 'file2', 'file3'].each |String $file| {
exec {"sed -i 's/bar/foo/g' $file":
path => ['/bin'],
onlyif => 'grep "bar" $file 2>/dev/null',
cwd => '/opt/app/config/',
notify => Service['app'],
}
}
}
或在收集器的帮助下声明关系:
class app_cfg {
['file1', 'file2', 'file3'].each |String $file| {
exec {"sed -i 's/bar/foo/g' $file":
path => ['/bin'],
onlyif => 'grep "bar" $file 2>/dev/null',
cwd => '/opt/app/config/',
tag => 'app_notifier',
}
}
Exec<|tag == 'app_notifier|>
~> service { 'app':
ensure => running,
enable => true,
}
}