Ensure tripleo ansible inventory file update is atomic

Multiple python-tripleoclient commands can run concurrently
and all attempt to update the same inventory file in
~/tripleo-ansible-inventory.yaml. Make the update atomic to
ensure the inventory file is always complete/valid.

Change-Id: I28628100e1300e789114af420bf3ea0dfe9c0d70
(cherry picked from commit 8e082f45dd)
This commit is contained in:
Oliver Walsh 2020-08-07 16:15:43 +01:00 committed by Alex Schultz
parent 473d9cbc32
commit 67f9cb1cee
2 changed files with 10 additions and 4 deletions

View File

@ -16,7 +16,8 @@
# under the License. # under the License.
from collections import OrderedDict from collections import OrderedDict
import os.path import os
import tempfile
import yaml import yaml
@ -137,8 +138,10 @@ class TripleoInventories(object):
if var in inventory: if var in inventory:
inventory[var]['vars'].update(value) inventory[var]['vars'].update(value)
with open(inventory_file_path, 'w') as inventory_file: # Atomic update as concurrent tripleoclient commands can call this
with tempfile.NamedTemporaryFile('w', delete=False) as inventory_file:
yaml.dump(inventory, inventory_file, TemplateDumper) yaml.dump(inventory, inventory_file, TemplateDumper)
os.rename(inventory_file.name, inventory_file_path)
def host(self): def host(self):
# Dynamic inventory scripts must return empty json if they don't # Dynamic inventory scripts must return empty json if they don't

View File

@ -17,8 +17,9 @@
from collections import OrderedDict from collections import OrderedDict
import logging import logging
import os.path import os
import sys import sys
import tempfile
import yaml import yaml
from heatclient.exc import HTTPNotFound from heatclient.exc import HTTPNotFound
@ -383,5 +384,7 @@ class TripleoInventory(object):
if var in inventory: if var in inventory:
inventory[var]['vars'].update(value) inventory[var]['vars'].update(value)
with open(inventory_file_path, 'w') as inventory_file: # Atomic update as concurrent tripleoclient commands can call this
with tempfile.NamedTemporaryFile('w', delete=False) as inventory_file:
yaml.dump(inventory, inventory_file, TemplateDumper) yaml.dump(inventory, inventory_file, TemplateDumper)
os.rename(inventory_file.name, inventory_file_path)