如何使用 Chef 更改文件?

Posted

技术标签:

【中文标题】如何使用 Chef 更改文件?【英文标题】:How can I change a file with Chef? 【发布时间】:2013-01-28 16:16:09 【问题描述】:

我有 7 个文件和 1 个战争。我需要在部署它们时更改值。我有这个:

##usuario
#alfresco.user=*****
alfresco.user=********
##pass 
#alfresco.password= sfsfs
alfresco.password=sfgsf

alfresco.rutaAnexos=/gthtfdh/dfgdf/cm:

#atributo.type.anexo=ANEXO_INFO_OBJETO
atributo.type.anexo=AN
atributo.type.observaciones=OBSERVACIONES

我需要注释一些行并取消注释其他一些行。然后我需要制作七个模板并根据环境放置变量并在配方中创建一个文件。

我该怎么做?

【问题讨论】:

参见docs.opscode.com/essentials_cookbook_templates.html 和docs.opscode.com/resource_template.html,了解模板的工作原理。 【参考方案1】:

Chef 实际上允许并使用它。你可以在操作码的

中找到一个例子

cookbooks/chef-server/recipes/default.rb:

ruby_block "ensure node can resolve API FQDN" do
  block do
    fe = Chef::Util::FileEdit.new("/etc/hosts")
    fe.insert_line_if_no_match(/#node['chef-server']['api_fqdn']/,
                               "127.0.0.1 #node['chef-server']['api_fqdn']")
    fe.write_file
  end
  not_if  Resolv.getaddress(node['chef-server']['api_fqdn']) rescue false 
end

这是用例。从源代码安装后,我不得不取消注释某些创建的配置文件中的行,这些行在所有版本的软件中都不相同,因此模板的使用不合适。我使用的方法是:

(对象)search_file_replace(正则表达式,替换) (对象)search_file_replace_line(正则表达式,换行符)

您可以在这里找到完整的文档:

http://rubydoc.info/gems/chef/Chef/Util/FileEdit

TO STRESS:此方法仅在使用模板和部分不合适时使用。正如@StephenKing 已经说过的,模板是这样做的常用方法。

【讨论】:

@StephenKing,如果您有什么我没有想到的方法,请在此处提供。我认为这种争论会给整个话题带来好处。此外,我同意,我提供的方法应该谨慎使用,并且仅在不可避免的需要的情况下使用。 我不是在争论,我试图争论。一个想法:将模板中发生变化的部分作为变量传递给模板,并决定配方中特定于版本的内容。其他想法:尝试部分模板:docs.opscode.com/… 是的,如果 Chef 正在生成整个安装,模板(或将原始内容推送到文件资源中)非常有用。但是 mediawiki(例如)会生成自己的 LocalSettings.php 文件。您的选择是 1) 运行 mediawiki 初始化脚本,然后向生成的 LocalSettings.php 文件添加一些编辑,或者 2) 重新发明***,从模板创建整个 LocalSettings.ini 文件并弄清楚如何创建数据库结构等。 编辑文件的一个主要缺点是确保进程是幂等的。这可能不是微不足道的!使用模板并且“正常工作”。 在许多情况下,模板是正确的答案,但如果您正在管理要定期升级的软件配置,并且您不想在之后重新创建“金牌大师”每次升级,使用部分 FileEdits 比手动或部分自动安装和配置软件只是为了获得新的设置字段/等要好得多。【参考方案2】:

这是一个示例,说明如何使用 Chef 取消对配置文件中的行的注释。 ruby_block::File::grep 保护。 Debian 的测试只是为了好玩。

pam_config = "/etc/pam.d/su"
commented_limits = /^#\s+(session\s+\w+\s+pam_limits\.so)\b/m

ruby_block "add pam_limits to su" do
  block do
    sed = Chef::Util::FileEdit.new(pam_config)
    sed.search_file_replace(commented_limits, '\1')
    sed.write_file
  end
  only_if  ::File.readlines(pam_config).grep(commented_limits).any? 
end if platform_family?('debian')

【讨论】:

【参考方案3】:

自 2020 年起,不鼓励提供所提供的解决方案 - 请参阅 here 和 here。

执行文件手动编辑的现代方式是使用由社区维护的官方食谱line。

例子:

replace_or_add "why hello" do
  path "/some/file"
  pattern "Why hello there.*"
  line "Why hello there, you beautiful person, you."
end

在使用这种策略之前,100% 确保确实需要手动编辑是至关重要的,但这完全取决于用例。

【讨论】:

【参考方案4】:

按照设计,您不能使用 Chef 修改文件。相反,您将占位符 (<%= ..%>) 放入文件模板中,然后将其替换为动态值(所谓的属性)。

【讨论】:

如果文件也被其他软件编辑了怎么办?模板很棒,但也需要编辑文件(甚至 ansible 也有 lineinfile 模块)。 那么请看下面的答案。

以上是关于如何使用 Chef 更改文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Chef 在本地移动/复制文件

如何控制 Vagrant 用于配置 VM 的 Chef 版本?

开始使用chef,并在部署时运行composer install

如何以幂等方式使用 Chef 添加 NFS 共享?

如何在 Chef 食谱中使用自定义 JSON 属性

如何从 Chef 获取 rundeck 的节点清单