ruby - 如果源文件存在,如何编写 Chef 配方来复制文件? only_if 守卫不工作

标签 ruby tomcat deployment chef-infra

我目前正在编写一个简单的脚本来在 Chef 部署期间处理属性文件。我正在使用 chef-apply script.rb

执行以下代码
class_path = '/var/lib/tomcat/webapps/ROOT/WEB-INF/classes'
file '/home/corp/working/corp.properties' do
  owner 'root'
  group 'root'
  mode 0644
  p File.exist?("#{class_path}")
  content File.open("#{class_path}/corp.properties").read
  action :create_if_missing
  only_if { File.exist?("#{class_path}/corp.properties") }
end

但运行时出现错误

false
[2017-12-20T11:37:40-05:00] FATAL: Stacktrace dumped to /home/corp/.chef/cache/chef-stacktrace.out
[2017-12-20T11:37:40-05:00] FATAL: Stacktrace dumped to /home/corp/.chef/cache/chef-stacktrace.out
[2017-12-20T11:37:40-05:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2017-12-20T11:37:40-05:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2017-12-20T11:37:40-05:00] FATAL: Errno::ENOENT: No such file or directory @ rb_sysopen - /var/lib/tomcat/webapps/ROOT/WEB-INF/classes/corp.properties
[2017-12-20T11:37:40-05:00] FATAL: Errno::ENOENT: No such file or directory @ rb_sysopen - /var/lib/tomcat/webapps/ROOT/WEB-INF/classes/corp.properties

如您所见,即使 File.exist? 调用返回 false,File.open 仍会执行,而不管防护措施如何。

最佳答案

资源 block 中的任何代码默认在编译时运行。守卫在集合时间运行。您可以通过使其 content lazy { File.open("#{class_path}/corp.properties").read } 来强制文件读取在收敛时发生来解决此问题。请参阅https://coderanger.net/two-pass/了解更多信息。

关于ruby - 如果源文件存在,如何编写 Chef 配方来复制文件? only_if 守卫不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47910685/

相关文章:

ruby - 在 ruby​​ 中运行手动 GC 是好习惯吗

ruby - 如何使用 dockerfile 安装 ruby​​ 和 bundler?

java - Apache Tomcat 无法在 Mac 上启动

java - 将动态应用程序部署到 Eclipse 上的 Tomcat 服务器后,Spring Web REST API 的 HTTP 状态 404

ruby - 使用 Ruby 解析文本文件时如何跳过某些列?

ruby-on-rails - 采摘返回重复的结果

java - 将 Java 应用程序部署到 Heroku

ruby-on-rails - 代码推送到 heroku 不起作用

java - HTML 表单提交后 Tomcat 8 重定向

asp.net - 分步 ASP.NET 自动构建/部署