【问题标题】:Removing boilerplate attributes from resources从资源中删除样板属性
【发布时间】:2014-02-01 02:32:09
【问题描述】:

在 chef 中,每个资源都是这样定义的:

directory "/home/akihiro/folder" do
  owner "akihiro"
  group "akihiro"
  mode 0755
end

如果这是akihiro主目录下的唯一任务,那很好。

不幸的是,我必须在所有者所在的主目录下创建目录、复制文件和应用模板。因此owner "akihiro"; group "akihiro"必须在每个资源上都设置,这是非常多余的。

如果资源可以这样写,

directory "/home/akihiro/folder" do
  as_akihiro
  mode 0755
end

as_akihiro 定义在资源之外的某个地方,配方会变得更加清晰。

是否可以通过定义新方法来移除样板属性?

【问题讨论】:

  • 我想如果你只是尝试一下,你会得到比在这里问更快的答案。

标签: ruby chef-infra


【解决方案1】:

这里有几个选项。

红宝石

您可以创建一个定义此方法的 Ruby 模块:

module Impersonator
  def as(person, perms = '0755')
    send(:owner, person)
    send(:group, person)
    send(:mode,  perms)
  end
end

然后在资源中包含这个模块:

Chef::Resource.send(:include, Impersonator)

然后使用它:

directory '/foo/bar' do
  as 'akihiro' # or as 'akihiro', '0644'
end

大鱼

如果我对您的用例的理解正确,则处理此问题的首选方法是使用 LWRP(或 HWRP)。您指出此过程多次发生并包装核心 Chef 资源。这是 LWRP 的一个很好的用例。本质上,您将所有这些资源包装和参数化到一个“包装器”中。

# providers/default.rb
action :run do
  user new_resource.username do
    # ...
  end

  directory "/home/#{new_resource.username}" do
    owner new_resource.username
    group new_resource.group
    mode  new_resource.mode
  end

  # Other resources, using the `new_resource` object
end

然后在 Chef 食谱中,您将使用此资源(假设它被命名为“company_user”):

company_user 'akihiro'

【讨论】:

    【解决方案2】:

    这是可能的。对我有用的是打开实现“目录”资源的类 Chef::Resource::Directory 并添加一个方法 as_akihiro。为此,请将库添加到 *your_cookbook*/libraries/as_user_helper.rb

    class Chef::Resource::Directory
    def as_akihiro()
        owner "akihiro"
        group "akihiro"
    end
    

    你就完成了。

    【讨论】:

      猜你喜欢
      • 2011-02-13
      • 1970-01-01
      • 2017-04-21
      • 2011-07-27
      • 2014-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多