【发布时间】:2026-02-02 13:30:02
【问题描述】:
我有以下代码来确定 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]
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_file这两个资源因为找不到目录而失败:
No such file or directory @ dir_chdir - /ourapp/jre-server/linux/
经过大量谷歌搜索,我得出的结论是,配方的编译时间和运行时间之间存在 ..“不匹配”(?)。基本上,如果我理解正确,它会首先尝试运行 cookbook_file 资源但失败。所以永远不要下载、解压和安装应用程序。
我尝试在目录存在时运行app_java_home,它似乎确实按我想要的方式工作..
我尝试将cookbook_file 资源放在ruby_block 中,但后来却得到:
undefined method `cookbook_file' for Chef::Resource::RubyBlock
app_java_home .. 函数 (?) 过去看起来像这样:
def app_java_home
"#{app_home}/jre-server/linux/#{jdk_version}"
end
jdk_version 来自数据包。这工作得很好,但是我们的系统中有一个长期存在的错误/功能请求,有时会发生“他们”得到他们放入数据包中的版本错误,导致各种问题.. 所以他们想要一种方法来删除这个依赖,而是动态地“解决这个问题”。
Ruby 和 Chef 不是我的强项,所以我不确定接下来要尝试什么。我找到了对Chef::Resources::CookbookFile 的引用(如果我理解的话,可以/应该在ruby_blocks 中使用它),但找不到任何关于它的示例或文档。 RubyDocs 上的链接已损坏。
【问题讨论】:
-
app_java_home是食谱的一部分吗?你是如何运行它的? -
我将该代码放入 Ruby shell 并运行它。在创建目录之前和之后,它都可以工作。当它出现在说明书(libraries/attributes.rb)中时,问题是它似乎“在错误的时间”运行。
-
无法从问题中发布的简洁错误中看出,但
@ dir_chdir似乎在app_java_home方法中表明Dir.chdir存在问题。cookbook_file资源不需要更改目录。#{app_home}是由配方中的代码创建的吗? -
没错。问题是
cookbook_file在aws_s3_file和两个execute之前运行之前 解压并安装应用程序。所以当cookbook_file运行时,那个目录还不存在。 -
好的。这就是当您运行配方时会发生的情况 -
app_java_homehome 在 compile 时间内运行以获得返回值。配方中声明的所有资源都将在 converge 阶段并按照它们定义的顺序运行。只有在aws_s3_file之上有cookbook_file资源,它才会在它之前运行,否则不会。
标签: ruby chef-infra cookbook