如何从 LWRP Provider 中调用资源

How to invoke resources from within an LWRP Provider

首先让我承认我很难理解整个资源创作技术堆栈。有 LWRP、图书馆资源、重量级资源,我似乎找不到绳子的尽头,可以说开始解开这个毛线球。因此,这是一个有点广泛的多部分问题。

它的症结在于我有一个工作配方,它调用一系列资源来分区、格式化和挂载 linux 设备。现在我想把它变成一个 LWRP(或者如果 LWRP 不合适,任何合适的 R/P 方法)这样我就可以以参数化的方式多次调用它。

这是我的初步尝试,关于它的问题如下:

# Resource:: mount_drive_as
#
# Will idempotently find a physical drive (/dev/sdb, /dev/sdc, etc), 
# create a primary partition using the entire drive and formated to ext4 
# and mount it at the specified mount point.
# An fstab entry is also created to auto mount the partition.

actions :create
default_action :create

#Path to the location where the drive will be mounted, e.g. /data
attribute :mount_point,
          :name_attribute => true,
          :kind_of => String,
          :required => true

attribute :device,
          :regex => [ /^sd[a-z]$/ ]
          :default => 'sdb'

还有我的提供者(此时大部分只是原始食谱的删减):

#ensures parted is installed.
run_context.include_recipe 'parted'

def whyrun_supported?
  true
end

action :create do
  parted_disk "/dev/#{@new_resource.device}" do
    label_type "gpt"
    action :mklabel
  end

  parted_disk "/dev/#{@new_resource.device}" do
    part_type   "primary"
    file_system "ext4"
    action :mkpart
  end

  parted_disk "/dev/#{@new_resource.device}1" do
    file_system "ext4"
    action :mkfs
  end

  replace_or_add "add /dev/#{@new_resource.device}1 to /etc/fstab" do
    path "/etc/fstab"
    pattern "^/dev/#{@new_resource.device}1"
    line "/dev/#{@new_resource.device}1   #{@new_resource.mount_point}   ext4   defaults   0 0"
  end

  directory @new_resource.mount_point

  execute 'mount /dev/#{@new_resource.device}1'

end

所以我有两个基本问题:

  1. 如何从 :create 操作中正确调用这些其他资源。
  2. 如何汇总所有 updated_by_last_action() 调用的结果,以便我可以在我的代码中正确调用 updated_by_last_action()
  3. 换句话说,在这种情况下如何正确支持 whyrun?

我意识到我在上面使用的一些食谱(特别是 line 食谱中的 replace_or_add,可能还有 execute)可能最好通过其他方式使用资源但我可以稍后再说。我最感兴趣的是在这里利用的 parted 资源。

解决您的问题: 1. 如果你添加 use_inline_resources 你可以保持你的代码不变 2. 如果您添加 use_inline_resources 那么这会为您处理(在本例中) 3.与其他两个相同。

现在,关于大毛线的问题,希望这会有所帮助。

好的,我知道有四种方法可以创建 resource/providers。按出场顺序: 1.重量级 2. LWRP 3. 中等重量?? 4. 风度翩翩

重量级

本来,这是唯一的方法。您将新的 classes 添加到您的库目录中,它们就可用了。传统上,任何时候你在这些资源中使用资源,你都会将这些资源的动作设置为:nothing,然后立即run_action来获得效果。

file 'somefile' do
  action :nothing
end.run_action(:create)

但是,这导致虚拟资源被添加到堆栈中。您还必须让他们查询资源的 updated 状态,并进行相应设置。

f = file 'somefile' do
  action :nothing
end.run_action(:create)
@new_resource.updated_by_last_action f.updated_by_last_action

再加上文件比实际需要大得多的事实,我们得到了 LWRP 概念。

LWRP

LWRP 是一组新的库,允许您将文件放入 resourcesproviders。这些文件使用 LWRP 库进行评估,并允许您以更 DSL 的方式定义资源和提供程序。因此,您可以定义属性,例如,通过调用方法。最初他们有许多 HWRP 的缺点,但文件更干净、更小。主要缺点是您不能进行任何形式的继承。

最终,引入了use_inline_resources的想法。通过将此方法放入您的 LWRP 提供程序中,您可以不再担心 updated_by_last_action。它还具有您可以在文档中阅读的其他好处。简而言之,所有在 provider 中声明的资源都在 'mini' chef 运行 中执行。如果其中任何一个被更新,那么 LWRP 资源将被标记为自动更新。此外,由于这个 inner chef 运行,这些资源中的 none 被添加到外部 chef 运行 的资源堆栈中。 (这有好有坏,我们将在 Poise 中看到更多)

MWRP

有些人想要两全其美,并意识到如果他们扩展 LWRPBase class,他们可以定义一个 "base" 资源和提供者,然后继承它们,同时仍然获得来自 LWRP 的清洁方法。对此无需多说。它很酷,但基本上只是 HWRP 和 LWRP 的混合体。这些进入库目录

平衡

Noah K. 认为其中 none 是正确的。如果我没记错的话,他曾深入参与编写 LWRP,但也感受到了它的一些缺点。所以大约一年前(我想)他发布了 Poise 食谱。这确实是一个用于编写新型 resource/provider 的库。使用 poise,您可以很好地平衡 LWRP 和 MWRP。您在库文件中简单 require poise,在 metadata.rb 中简单 depends poise。 Poise 实现了 LWRP 库中您最喜欢的所有方法,以及一些其他非常有用的东西。

平衡使用 notifying_block 而不是 use_inline_resources。两者之间的主要区别在于 notifying_block 资源 ARE 添加到主厨 运行 堆栈。这是一个大问题,因为它允许其他资源通知它们。 (例如重新启动服务)。它还允许其他资源订阅它们。

您可以在 github 项目中查看 Poise 的完整文档。

就我个人而言,我正在泰然自若地进行所有新的 LWRP,因为我认为这是迄今为止最好的选择。