问题描述
我的 Puppet 安装有以下问题:
我有这样的事情:
package { 'my-rpm':
ensure => $version,source => $rpm_file,notify => File[$my_file],}
file { $my_file:
ensure => present,source => $my_file_template,replace => true,# Overwrite (default behavIoUr). Needed in case new RPM was installed.
}
问题是,如果没有安装新版本的 RPM,“文件”也会被执行。发生这种情况,因为我之后使用“file_line”更改了 $my_file 文件
file_line { 'disable_my_service':
ensure => present,path => $my_file,line => ' <deployment name="My.jar" runtime-name="My.jar" enabled="false">',match => ' <deployment name="My.jar" runtime-name="My.jar">',}
$my_file 内容的这种更改会在每次 Puppet 运行时触发从模板复制新版本。
我可以在我的文件副本定义中添加“repace => false”,但这会破坏任何进一步的更新......
长话短说:我有以下循环
我怎样才能打破这个循环?
更新: 澄清:
- “file_line”定义可选执行,由 Puppet hiera-property 控制,因此“启用”部分不能包含在 RPM 中。
- 无法将整个文件转换为模板 (恕我直言)。问题:Puppet 模块必须能够安装文件的不同(未来)版本。
- 问题暂时没有解决。
解决方法
我认为您在这里遇到的问题是您正在尝试使用 file 和 file_line 资源类型来管理 $my_file
,这是将导致文件在目录应用程序期间更改。
选择其中一个,将其作为模板或按文件行进行管理。
我怀疑在 Puppet 运行期间发生的事情是 file
资源更改 $my_file
看起来像这样;
<deployment name="My.jar" runtime-name="My.jar">
因为那是模板中的内容,file_line 资源将其更改为;
<deployment name="My.jar" runtime-name="My.jar" enabled="false">
然后在下一次运行时发生完全相同的事情,file 更改 $my_file
以匹配模板,然后 file_line 更改它以修改该行。
我会删除 notify => File[$my_file],
它实际上并没有做任何事情,您正在代码中定义所需的状态,因此如果该文件因任何原因,手动更改或 RPM 更新而更改,Puppet 会将该文件带回来在运行过程中进入所需的状态。你可能要考虑;
file { $my_file:
ensure => present,source => $my_file_template,require => Package['my-rpm'],}
这可确保在 package 资源之后强制执行文件所需的状态,因此如果包更改了文件,该文件将在同一次运行中得到纠正。 https://puppet.com/docs/puppet/7.4/lang_relationships.html
您可能还想考虑;
file { $my_file:
ensure => present,notify => Service['my-service'],}
所以当配置文件改变时,rpm提供的服务会重新启动。
,仅在 RPM 更新时复制覆盖文件
问题是,如果没有安装新版本的 RPM,“文件”也会被执行。发生这种情况,因为我之后使用“file_line”更改了 $my_file 文件
是的,每次运行都会应用节点目录中的 File
资源。事实上,最好的观点是每个 将其放入节点目录中的资源在每次运行时都会应用。资源的属性会影响应用它们的意义和/或它们同步的意义,而不是它们是否被应用。例如,在 File
的情况下,设置 replace => false
表示只要文件最初存在,其内容就是同步的(因此不应修改),而 replace => true
表示仅当文件内容与指定的 source
或 content
完全匹配时才同步。
一般来说,通过多个 Puppet 资源管理相同或重叠的物理资源效果不佳,这就是您在这里遇到的问题。当您遇到问题时,最惯用的方法通常是编写自定义资源类型来详细管理目标对象。但在本例中,您似乎可以通过使用 Exec
执行一次性更新后复制来解决此问题:
package { 'my-rpm':
ensure => $version,source => $rpm_file,}
~> exec { "Start with default ${my_file}":
command => "cp '${my_file_template}' '${my_file}'",# this is important:
refreshonly => true,}
-> file { $my_file:
ensure => 'file',replace => false,# no source or content
owner => 'root',# or whatever
group => 'root',# or whatever
mode => '0644',# ...
}
-> file_line { 'disable_my_service':
ensure => present,path => $my_file,# ...
}
当然,如果您愿意或有需要,您可以使用关系元参数而不是链接箭头。
这种方法为您提供:
- 通过包管理器管理包;
- 仅在更新包触发时才将打包的默认文件复制到目标文件(通过 Puppet - 如果手动更新包,您将无法获得此信息);
- 通过
File
资源管理文件内容以外的属性;和 - 通过
File_line
资源管理文件内容的特定行。