provisioners/ansible: Replace inventory file instead of modify

When updating the inventory, write to a temp file and replace the
original once writing is complete, to allow for an atomic replacement
of the contents.

Ensures that ansible reading an inventory file will get either the old
or new contents, but never the truncated version of the file that
appears should you open it with 'w' mode set to replace the contents.

Solves the 'provided hosts list is empty' error, which is emitted by
ansible should it manage to be reading the inventory file just as it
was truncated, but before the new contents were flushed to disk.

Partially-Fixes: #6526
This commit is contained in:
Darragh Bailey 2016-03-31 14:44:17 +01:00
parent 36ad4d53cf
commit cae0bfdf9d
1 changed files with 9 additions and 2 deletions

View File

@ -132,8 +132,15 @@ module VagrantPlugins
inventory_file = Pathname.new(File.join(inventory_path, 'vagrant_ansible_inventory')) inventory_file = Pathname.new(File.join(inventory_path, 'vagrant_ansible_inventory'))
@@lock.synchronize do @@lock.synchronize do
if !File.exists?(inventory_file) or inventory_content != File.read(inventory_file) if !File.exists?(inventory_file) or inventory_content != File.read(inventory_file)
inventory_file.open('w') do |file| begin
file.write(inventory_content) # ansible dir inventory will ignore files starting with '.'
inventory_tmpfile = Tempfile.new('.vagrant_ansible_inventory', inventory_path)
inventory_tmpfile.write(inventory_content)
inventory_tmpfile.close
File.rename(inventory_tmpfile.path, inventory_file)
ensure
inventory_tmpfile.close
inventory_tmpfile.unlink
end end
end end
end end