在Ruby + Chef中检查现有目录是否失败

Bar*_*lom 5 ruby chef-infra

这是我在Chef中的Ruby配方:

# 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
Run Code Online (Sandbox Code Playgroud)

结果是:

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
Run Code Online (Sandbox Code Playgroud)

我知道/vol/postgres/data存在并且是一个目录,但它仍然试图执行mv.为什么?

可以肯定的是,在同一台机器上运行以下独立的Ruby脚本会输出"nomv":

if !File.exist?("/vol/postgres/data")
print "mv"
else
print "nomv"
end
Run Code Online (Sandbox Code Playgroud)

Dra*_*ter 9

我之前并不那么专心,我以为你正在检查文件是否存在not_ifonly_if阻塞.您的问题类似于此问题中的问题:Chef LWRP - defs /资源执行顺序.请参阅那里的详细说明.

您的问题是!File.exist?("/vol/postgres/data")代码会立即执行 - (因为它是纯粹的ruby),在执行任何资源之前,因此在安装postgress之前.

解决方案应该是将检查移至not_if阻止.

execute "mv /var/lib/postgresql/9.1/main /vol/postgres/data" do
  not_if { File.exist?("/vol/postgres/data") }
end
Run Code Online (Sandbox Code Playgroud)


Raj*_*gde 5

使用这段代码:

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

要么

你也可以用

execute "name" do
    command "mv /var/lib/postgresql/9.1/main /vol/postgres/data"
    creates "/vol/postgres/data"
end
Run Code Online (Sandbox Code Playgroud)

只有/vol/postgres/data在文件系统中不存在时,两者才会运行该命令.如果你想运行命令块,那么使用这样的东西,

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
Run Code Online (Sandbox Code Playgroud)