如何在执行时读取文件内容?厨师在编译时读取

时间:2013-03-29 01:20:02

标签: ruby io chef

因为我遇到了我向Mixlib团队报告过的MIXLIB-11错误,所以我需要找一个散步,替代Mixlib :: Shellout。

简要说明问题:

Here是一个声明,“*毫不奇怪 - 读取是在编译时发生的,但是remote_file资源实际上是在执行时创建的。**”

由于此功能,Mixlib::Shellout.new("ls", :cwd => '/opt/cubrid/share/webmanager')会引发“没有此类文件或目录”错误,即使该目录是在执行时由当前配方中包含的上一个配方创建的。

有没有办法在执行时读取文件/目录?

4 个答案:

答案 0 :(得分:14)

找到答案:将代码包装在ruby_block中,并在运行时执行。

ruby_block "Check if CURBID Web Manager needs installation" do
  block do
    version = ""

    if File.exists?("#{CWM_HOME_DIR}/appLoader.js")
      # Read the CWM version from file.
      f = File.open("#{CWM_HOME_DIR}/appLoader.js")

      pattern = /Ext\.cwm\.prodVersion = '(\d+\.\d+\.\d+\.\d+)'/

      f.each {|line|
        if match = pattern.match(line)
          version = match[1]
          break
        end
      }

      f.close
    end
  end
end

现在,从上一个配方中创建的文件中正确填充了该版本。

答案 1 :(得分:0)

如果使用自定义资源,则可以使用load_current_value方法。

action :some_action do

  load_current_value do
    if File.exist?('/var/www/html/index.html')
      homepage IO.read('/var/www/html/index.html')
    end
    if File.exist?('/var/www/html/404.html')
      page_not_found IO.read('/var/www/html/404.html')
    end
  end

end

https://docs.chef.io/dsl_custom_resource.html

答案 2 :(得分:0)

我个人更喜欢在执行期间使用type命令将文件读入变量。

要将文件简单地读入变量,可以尝试

ruby_block 'Read IP file into v_ip variable' do
   block do
       if File.exists?("#{v_ip_folder}\\ip.txt")
          v_ip = %x(type "#{v_ip_folder}\\ip.txt")
          Chef::Log.info("#{v_ip}")
       end
   end
end 

%x(type "#{v_ip_folder}\\ip.txt")将在命令提示符下运行type命令,并将输出返回到指定的v_ip变量。

答案 3 :(得分:-3)

考虑remote_file。它在执行(运行)时执行,也可以与本地文件一起使用,例如:

remote_file "Copy file" do
  path "file:///opt/destination.txt"
  source "file:///opt/source.txt"
  owner 'root'
  group 'root'
  mode 0755
end

因此使用remote_file是一个很好的解决方法。编写自定义代码需要一些时间并且可能容易出错。 另请参阅this answer