如何清理Puppet中未管理内容的文件?解决Exec文件未被清理问题
Puppet管控Exec创建文件及清理未管控文件的问题
我尝试在Puppet中管理由Exec创建的文件,希望确保目录中不存在任何未管控的文件。示例代码如下:
file { '/tmp/puppet_example': ensure => directory, purge => true, } $files = [ '/tmp/puppet_example/file1.json', # '/tmp/puppet_example/file2.json', '/tmp/puppet_example/file3.json', ] $files.each |$file| { exec { "exec_${file}": creates => $file, command => "/usr/bin/touch ${file}", require => File['/tmp/puppet_example'], } file { $file: ensure => file, replace => false, require => File['/tmp/puppet_example'], } }
当$files数组中的条目被移除后(比如注释掉的file2.json),对应的文件并未被自动清理。请问管理这类由Exec创建的文件、清理未管控内容的正确方式是什么?另外,这是否是replace属性的特性导致的?该属性官方说明如下:
将此设置为false允许文件资源初始化文件而不覆盖未来的更改
问题原因分析
- 目录purge的逻辑:你当前设置的
purge => true只会清理没有被Puppet任何资源管控的文件。如果某个文件曾经被定义过file资源,哪怕后来从$files中移除,只要没显式标记为删除,Puppet不会把它判定为“未管控”文件,自然不会清理。 - replace属性的作用:
replace => false和文件是否被清理完全无关,它只控制Puppet会不会覆盖文件的内容——正如说明所说,允许文件初始化后,后续的内容变更不会被Puppet覆盖,但只要ensure => file,Puppet会一直保证这个文件存在。
正确解决方案
方案1:显式清理不再管控的文件
通过resources类型匹配目录下的文件,自动清理不在管控列表中的文件:
file { '/tmp/puppet_example': ensure => directory, purge => true, recurse => true, # 必须加上recurse,purge才会作用于子文件 } # 定义需要保留的管控文件列表 $managed_files = [ '/tmp/puppet_example/file1.json', '/tmp/puppet_example/file3.json', ] # 管理需要存在的文件:先通过exec创建,再用file管控内容不被覆盖 $managed_files.each |$file| { exec { "exec_${file}": creates => $file, command => "/usr/bin/touch ${file}", require => File['/tmp/puppet_example'], } file { $file: ensure => file, replace => false, require => Exec["exec_${file}"], # 确保exec创建文件后再执行file资源 } } # 清理不在管控列表中的文件 resources { 'file': purge => true, # 只匹配目标目录下的文件 onlyif => "/usr/bin/test -f \$title && echo \$title | grep -q '^/tmp/puppet_example/'", # 如果文件不在管控列表中,就删除 unless => "/usr/bin/echo '${managed_files.join("' '")}' | grep -q \"^\\\$title\$\"", }
方案2:简化逻辑,用file资源替代exec
如果你的exec只是创建空文件,完全可以直接用file资源的ensure => file来创建,这样管控更简洁,清理也更直接:
file { '/tmp/puppet_example': ensure => directory, purge => true, recurse => true, } $managed_files = [ '/tmp/puppet_example/file1.json', '/tmp/puppet_example/file3.json', ] $managed_files.each |$file| { file { $file: ensure => file, replace => false, require => File['/tmp/puppet_example'], } }
这种情况下,当你从$managed_files中移除某个文件,Puppet会把它判定为“未管控”文件,结合purge => true和recurse => true,自动清理掉目录中不在管控列表里的文件。
内容的提问来源于stack exchange,提问作者Elfranne
相关产品推荐
相关产品推荐

