8

Because I'm running into this MIXLIB-11 error that I've reported to Mixlib team, I need to find a walkaround, an alternative to Mixlib::Shellout.

Briefly about the problem:

Here is a statement which says "*No surprise -- the read is happening at compile time, but the remote_file resource is actually created at execution time.**"

Because of this feature, Mixlib::Shellout.new("ls", :cwd => '/opt/cubrid/share/webmanager') raises "No such file or directory" error even though that directory is created at execution time by a previous recipe included in this current recipe.

Is there a way to read a file/directory at execution time?

esengineer
  • 9,514
  • 7
  • 45
  • 69

4 Answers4

14

Found an answer: wrap the code in ruby_block, and it will be executed at run time.

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

Now the version is correctly populated from the file created in the previous recipe.

esengineer
  • 9,514
  • 7
  • 45
  • 69
0

If using custom resources, you can use the load_current_value method.

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

spuder
  • 17,437
  • 19
  • 87
  • 153
0

Personally, I prefer to use the type command to read the file into a variable during execution.

To simply read the file into a variable, you can try

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") will run the type command in command prompt and return the output to the v_ip variable specified.

draysams
  • 1,199
  • 1
  • 11
  • 18
  • 1
    The `type` command is a windows-specific command, with a completely different behavior on unix. For that reason you should use ruby file i/o commands rather than executing system utilities. – lamont Aug 20 '20 at 22:35
-4

Consider a remote_file. It is executed at execution (run) time, and it can also works with local files for example:

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

So using remote_file is good work around. While writing a custom code require a time and can be error prone. See also this answer.

Community
  • 1
  • 1
Cherry
  • 31,309
  • 66
  • 224
  • 364