带有“&&”的主厨守卫 only_if 不遵守这两个声明

chef guard only_if with '&&' not adhering to both statements

我在厨师食谱中有以下哈希,它创建了 directory/s

node['fnb_base_directory']['directory_name'].map do |directory_name, dir|
  next if directory_name.empty?
  directory directory_name do
    owner     dir['owner']
    group     dir['group']
    mode      dir['mode']
    recursive dir['recursive']
    action    dir['action']
    only_if "getent passwd #{dir['owner']}" && "getent group #{dir['group']}"
  end
end

我只想让 chef 尝试基于这个守卫创建目录:

only_if "getent passwd #{dir['owner']}" && "getent group #{dir['group']}"

所以这基本上意味着 usergroup 都必须存在才能尝试创建目录。

问题似乎是当 chef 解释这个时,我看到它只遵守 ONE 的陈述,即只检查 group 存在然后继续尝试创建目录,但会失败,因为用户尚不存在。 见下文解读:

directory("/opt/test_dir_creation") do
  action [:create]
  default_guard_interpreter :default
  declared_type :directory
  cookbook_name "fnb_base_wrapper"
  recipe_name "fnb_base_directory"
  recursive false
  owner "nonexistent_user"
  group "opc"
  mode "0755"
  only_if "getent group opc"
end

失败:

directory[/opt/test_dir_creation] action create
* cannot determine user id for 'nonexistent_user', does the user exist on this system?
================================================================================
Error executing action `create` on resource 'directory[/opt/test_dir_creation]'
================================================================================

Chef::Exceptions::UserIDNotFound
--------------------------------
cannot determine user id for 'nonexistent_user', does the user exist on this system?

用户尚不存在的原因是因为该用户是在另一本食谱中创建的,其优先级不如我们的基本厨师(创建目录)高,因此目录创建在用户之前完成已创建。

然后将在第 2 个会聚时创建目录,用户将存在于此,然后仅在那时继续创建目录。

仅供参考。 我正在使用 getent 因为我们在我们的服务器上使用 AD,所以它可能并不总是静态的 user/group,而是驻留在 AD 中的一个。

这个问题我也查过了: Using multiple conditions in Chef only_if guard

对我没有帮助。

非常感谢您的帮助、指导和建议。

尝试删除中间的引号,以便整个表达式(包括 && 条件)在 shell.

中运行

only_if "getent passwd #{dir['owner']} && getent group #{dir['group']}"

Chef 接受字符串 shell 命令或 ruby 块

only_if "some shell commands which are possibly in a pipeline return 0"

only_if {
  return true if <condition1> && <condition2>
  return true if <condition3> || <condition4>
  return false
}