厨师在ruby块中使用cookbook_文件
我有以下代码来确定Java在盒子上的位置。我们的应用程序附带Java,应用程序附带的Java版本与之不同厨师在ruby块中使用cookbook_文件,ruby,chef-infra,cookbook,Ruby,Chef Infra,Cookbook,我有以下代码来确定Java在盒子上的位置。我们的应用程序附带Java,应用程序附带的Java版本与之不同 def app_java_home if Dir.exist?("#{app_home}/jre-server/linux") Dir.chdir("#{app_home}/jre-server/linux") do Dir.glob('jdk*').select { |f| File.directory? f }[0]
def app_java_home
if Dir.exist?("#{app_home}/jre-server/linux")
Dir.chdir("#{app_home}/jre-server/linux") do
Dir.glob('jdk*').select { |f| File.directory? f }[0]
end
end
end
然后,在我的食谱里我有
aws_s3_file "#{app_download_path}/#{app_s3['archive_file']}" do
bucket app_s3['bucket']
remote_path app_s3['remote_path']
region aws_region
not_if { ::Dir.exists?(app_bin_dir) }
not_if { ::File.exists?("#{app_download_path}/#{app_s3['archive_file']}") }
end
execute 'extract' do
user 'root'
command "unzip #{app_download_path}/#{app_s3['archive_file']} > /dev/null"
not_if { ::Dir.exists?("#{app_home}/ourapp") }
only_if { ::File.exists?("#{app_download_path}/#{app_s3['archive_file']}") }
end
execute 'move' do
user 'root'
command "mv #{app_download_path}/ourapp/ #{app_install_path}"
not_if { ::Dir.exists?(app_home) }
end
cookbook_file "#{app_java_home}/jre/lib/security/local_policy.jar" do
source %W[#{app_release}/local_policy.jar default/local_policy.jar]
owner app_user_name
group app_group_name
mode 0755
end
cookbook_file "#{app_java_home}/jre/lib/security/US_export_policy.jar" do
source %W[#{app_release}/US_export_policy.jar default/US_export_policy.jar]
owner app_user_name
group app_group_name
mode 0755
end
但是,两个cookbook\u文件资源失败,因为它找不到目录:
No such file or directory @ dir_chdir - /ourapp/jre-server/linux/
经过大量的谷歌搜索,我得出结论,这是一个。。配方的编译时和运行时之间的“错配”(?)。基本上,如果我理解正确,它会首先尝试运行cookbook\u文件
resource,但失败了。因此,永远不要下载、解压和安装应用程序人工制品
当目录存在时,我试着运行app\u java\u home
,它似乎按照我想要的方式工作
我尝试将cookbook\u文件
资源放入ruby\u块
,但结果是:
undefined method `cookbook_file' for Chef::Resource::RubyBlock
app\u java\u主页
。。函数(?)通常如下所示:
def app_java_home
"#{app_home}/jre-server/linux/#{jdk_version}"
end
其中,jdk_版本
来自数据包。这很好,但我们的系统中有一个长期存在的bug/特性请求,有时“他们”将其放入数据库的版本弄错,从而导致各种各样的问题。。因此,他们希望找到一种方法来消除这种依赖性,而不是动态地“解决这个问题”
Ruby和Chef不是我的强项,所以我不确定下一步该怎么做。我找到了对Chef::Resources::CookbookFile
的引用(如果我理解的话,可以/应该在ruby_block
s中使用),但找不到任何关于它的示例或文档。RubyDocs上的链接已断开。请在此处添加答案以获得更好的解释
- 任何不在Chef资源中的(Ruby)代码都将在编译阶段运行
- 所有资源声明将按照定义的顺序在聚合阶段运行
谢天谢地,如果需要的话,有一种方法可以使资源在编译阶段运行。尽管我认为在特殊情况下,这项工作应该谨慎进行
根据您的评论,aws_s3_文件
和execute
资源是解包应用程序(并创建目录)的资源。在本例中,您似乎希望它们在编译阶段运行
厨师长客户端16.0之前的版本
将run_action
选项与应在编译时执行的操作一起使用。例如execute
资源执行操作:run
:
#注意动作:无”和“运行动作”
执行'extract'do
用户“根”
命令“解压#{app_download_path}/#{app_s3['archive_file']}>/dev/null”
如果{::Dir.存在,则不存在(“{app_home}/ourapp”)}
只有{::File.exists?(“{app_download_path}/{app_s3['archive_File']}”)}
行动:没什么
结束。运行\u操作(:运行)
厨师长客户端16.0版以后的版本
我们可以在资源中添加一个。使用execute
资源的示例:
#注意额外的属性“compile_time”
执行'extract'do
用户“根”
命令“解压#{app_download_path}/#{app_s3['archive_file']}>/dev/null”
如果{::Dir.存在,则不存在(“{app_home}/ourapp”)}
只有{::File.exists?(“{app_download_path}/{app_s3['archive_File']}”)}
编译时间为true
结束
最后回答问题的主题:
厨师在ruby块中使用cookbook_文件
这是不可能的。参考顶部的第一点。如果我们希望Ruby代码在converge期间运行(而不是编译),我们将其放在Ruby_块
资源中。因此,它可以包含如下代码(例如):
ruby_块'get directory'do
布洛克道
def app_java_主页
“#{app_home}/jre server/linux/#{jdk_version}”
结束
结束
结束
在@seshadri_c的帮助下,我终于解决了这个问题!这需要一些努力,因为我一直误解这些建议等等
这就是我(为后代)想到的:
事实证明,我只需要单独获取版本,所以我重新安排了一些函数。我相信它可以写得更干净,但这里的技巧是使用返回
,而不是放置/打印
!嗯,我是个程序员,但不是Ruby程序员,所以我不知道这是一个选择
然后,在食谱中,我在需要的地方添加了.run\u action()
。我不需要它们作为烹饪书\u文件
,这简化了一些事情:
aws_s3_file "#{app_download_path}/#{app_s3['archive_file']}" do
bucket app_s3['bucket']
remote_path app_s3['remote_path']
region aws_region
not_if { ::Dir.exists?(app_bin_dir) }
not_if { ::File.exists?("#{app_download_path}/#{app_s3['archive_file']}") }
end.run_action(:create)
execute 'extract' do
user 'root'
command "unzip #{app_download_path}/#{app_s3['archive_file']} > /dev/null"
not_if { ::Dir.exists?("#{app_home}/app") }
only_if { ::File.exists?("#{app_download_path}/#{app_s3['archive_file']}") }
end.run_action(:run)
execute 'move' do
user 'root'
command "mv #{app_download_path}/app/ #{app_install_path}"
not_if { ::Dir.exists?(app_home) }
end.run_action(:run)
# JCE Unlimited Strength Jurisdiction Policy Files
cookbook_file "#{app_java_home}/jre/lib/security/local_policy.jar" do
source %W[#{app_release}/local_policy.jar default/local_policy.jar]
owner app_user_name
group app_group_name
mode 0755
end
cookbook_file "#{app_java_home}/jre/lib/security/US_export_policy.jar" do
source %W[#{app_release}/US_export_policy.jar default/US_export_policy.jar]
owner app_user_name
group app_group_name
mode 0755
end
有了这些,所有的东西都在它们应该运行的时候运行,而且一切似乎都在工作。这本食谱是app\u java\u home
的一部分吗?如何运行它?我将代码放入Ruby shell并运行它。在创建目录之前和之后,它都可以工作。当它出现在烹饪书(libraries/attributes.rb)中时,问题在于它似乎是在“错误的时间”运行的。从所发布的简明错误中无法判断,但是@dir\u chdir
似乎表明app\u java\u home
方法中的dir.chdir
存在问题。cookbook\u文件
资源不需要更改目录。{app_home}
是由配方中的代码创建的吗?没错。问题是cookbook\u文件
在aws\u s3\u文件
和两个execute
之前运行,这两个execute将解包并安装应用程序。因此,当cookbook\u文件运行时,该目录还不存在。Ok。因此,当您在编译时运行recipe-app\u java\u home
home运行以获取返回值时,就会发生这种情况。配方中声明的所有资源都将在converge阶段按照定义的顺序运行。只有在aws\u s3\u文件
上面有cookbook\u文件
资源时,它才会在它前面运行,否则就不会运行。如果我在两个execute
和aws\u s3\u文件
中放入compile\u time true
,我会得到未定义的方法
aws_s3_file "#{app_download_path}/#{app_s3['archive_file']}" do
bucket app_s3['bucket']
remote_path app_s3['remote_path']
region aws_region
not_if { ::Dir.exists?(app_bin_dir) }
not_if { ::File.exists?("#{app_download_path}/#{app_s3['archive_file']}") }
end.run_action(:create)
execute 'extract' do
user 'root'
command "unzip #{app_download_path}/#{app_s3['archive_file']} > /dev/null"
not_if { ::Dir.exists?("#{app_home}/app") }
only_if { ::File.exists?("#{app_download_path}/#{app_s3['archive_file']}") }
end.run_action(:run)
execute 'move' do
user 'root'
command "mv #{app_download_path}/app/ #{app_install_path}"
not_if { ::Dir.exists?(app_home) }
end.run_action(:run)
# JCE Unlimited Strength Jurisdiction Policy Files
cookbook_file "#{app_java_home}/jre/lib/security/local_policy.jar" do
source %W[#{app_release}/local_policy.jar default/local_policy.jar]
owner app_user_name
group app_group_name
mode 0755
end
cookbook_file "#{app_java_home}/jre/lib/security/US_export_policy.jar" do
source %W[#{app_release}/US_export_policy.jar default/US_export_policy.jar]
owner app_user_name
group app_group_name
mode 0755
end