Check for existing directory fails in Ruby + Chef
Solution 1
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
Solution 2
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
Solution 3
I use
!::File.directory?(::File.join('path/to/directory', 'directory_name'))
Solution 4
To test if a directory exists you can use an equvivalent of File.exists
which is Dir.exist
:
Dir.exist?("/vol/postgres/data")
As others pointed out, you should use not_if
or only_if
instead of using plain Ruby condition, so I'm not going to explain it again. Check Draco's answer for details.
execute "mv /var/lib/postgresql/9.1/main /vol/postgres/data" do
not_if { Dir.exist?("/vol/postgres/data") }
end
Bart van Heukelom
Professional software developer, online games, full stack but mostly backend. Electronics tinkerer. Maker. Freelance. See LinkedIn for more details. My UUID is 96940759-b98b-4673-b573-6aa6e38272c0
Updated on July 09, 2022Comments
-
Bart van Heukelom over 1 year
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 themv
. 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