Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check for existing directory fails in Ruby + Chef

This is my piece of Ruby in a Chef recipe:

# if datadir doesn't exist, move over the default one
if !File.exist?("/vol/postgres/data")
    execute "mv /var/lib/postgresql/9.1/main /vol/postgres/data"
end

The result is:

Executing mv /var/lib/postgresql/9.1/main /vol/postgres/data
mv: inter-device move failed: `/var/lib/postgresql/9.1/main' to `/vol/postgres/data/main'; unable to remove target: Is a directory

I know that /vol/postgres/data exists and is a directory, yet it still attempts to execute the mv. Why?

Just to be sure, running the following standalone Ruby script on the same machine outputs "nomv":

if !File.exist?("/vol/postgres/data")
print "mv"
else
print "nomv"
end
like image 732
Bart van Heukelom Avatar asked Jul 11 '13 14:07

Bart van Heukelom


2 Answers

I was not so attentive earlier, I thought you are checking for file existence in not_if or only_if block. Your problem is similar to the one in this question: Chef LWRP - defs/resources execution order. See the detailed explanation there.

Your problem is that !File.exist?("/vol/postgres/data") code gets executed straight away - (because it's pure ruby), before any resource is executed and thus before the postgress is installed.

The solution should be to move the check to not_if block.

execute "mv /var/lib/postgresql/9.1/main /vol/postgres/data" do
  not_if { File.exist?("/vol/postgres/data") }
end
like image 96
Draco Ater Avatar answered Oct 04 '22 20:10

Draco Ater


Use this block of code :

execute "name" do
    command "mv /var/lib/postgresql/9.1/main /vol/postgres/data"
    not_if { ::File.exists?("/vol/postgres/data")}
end

OR

you can also use

execute "name" do
    command "mv /var/lib/postgresql/9.1/main /vol/postgres/data"
    creates "/vol/postgres/data"
end

Both will run the command only if /vol/postgres/data is not present in the file system. If you want to run block of commands then use something like this,

bash 'name' do
  not_if { ::File.exists?("/vol/postgres/data") }
  cwd "/"
  code <<-EOH
  mv /var/lib/postgresql/9.1/main /vol/postgres/data
  #any other bash commands 
  #any other bash commands
  EOH
end
like image 37
Rajesh Hegde Avatar answered Oct 04 '22 20:10

Rajesh Hegde