如何使用Chef懒惰地评估任意变量

 angel青彤雪 发布于 2023-02-10 08:44

我正在编写一个Chef配方来安装我们的应用程序代码并执行它.配方需要特别关注此代码最终的目录(用于运行模板,设置日志转发等).因此,目录本身会在不同的食谱中出现在很多地方.

我试图获取/定义一个变量,所以我可以在我的资源块中使用字符串插值重新使用它.这非常简单:

home = node['etc']['passwd'][node['nodejs']['user']]['dir']

使用示例用法,npm install同时告诉它在主目录中插入repo下载,如下所示:

execute "npm install" do
  command "npm install #{prefix}#{app} --prefix #{home}"
end

除了定义home变量的第一个块将在编译时运行.在一个新的服务器上,我的nodejs用户帐户可能还不存在,这是一个问题,给出了一个

NoMethodError undefined method '[]' for nil:NilClass

我有一些解决方法,但我想要一个特定的解决方案,使home变量只在配方执行时获取,而不是编译时.


解决方法1

动态评估ruby块内的home变量,如下所示:

ruby_block "fetch home dir" do
  block do
    home = node['etc']['passwd'][node['nodejs']['user']]['dir']
  end
end

这似乎没有实际工作,当你尝试做类似这样的事情时,为Chef :: Resource :: Directory提供一个NoMethodError未定义方法的主页:

directory ".npm" do
  path "#{home}/.npm"
end

我觉得我必须在这里做错事.

解决方法2

懒惰地评估每个需要它的资源的参数.所以改为:

directory ".npm" do
  path lazy "#{node['etc']['passwd'][node['nodejs']['user']]['dir']}/.npm"
end

但是,只需要维护一行代码,将其存储在变量中并完成它就会非常棒.

解决方法3

在编译时创建用户.这当然有效,使用此处链接的通知技巧,如下所示:

u = user node['nodejs']['user'] do
  comment "The #{node['nodejs']['user']} is the user we want all our nodejs apps will run under."
  username node['nodejs']['user']
  home "/home/#{node['nodejs']['user']}"
end

u.run_action(:create)

这完全解决了我的问题,但是在其他情况下我可以想象想要延迟评估变量的能力,所以我让我的问题成立.

我想要什么

我真的希望能够做到

home lazy = node['etc']['passwd'][node['nodejs']['user']]['dir']

但这不是合法的语法,因为NameError无法在ubuntu版本13.10上找到home的资源(这是一个奇怪的语法错误,但无论如何).有没有合法的方法来实现这一目标?

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有