Dynamic inventory backup corruption fix

When multiple users and process are accessing the dynamic inventory
the inventory backup and json can get corrupted. This change checks
for inventory modifictions and only saves if needed. The backup
is also moved to right before the actual save.

Change-Id: Ifd348ddd9c21526f5b523963dd1fd247edd6b109
Closes-Bug: #1750233
This commit is contained in:
Shannon Mitchell 2019-02-17 16:59:29 -06:00
parent 442d53a4d5
commit 71a067abf2
2 changed files with 12 additions and 3 deletions

View File

@ -245,7 +245,6 @@ def load_inventory(preferred_path=None, default_inv=None, filename=None):
if inventory is not False:
logger.debug("Loaded existing inventory from {}".format(file_loaded))
_make_backup(load_path, file_loaded)
else:
logger.debug("No existing inventory, created fresh skeleton.")
inventory = copy.deepcopy(default_inv)
@ -264,6 +263,10 @@ def save_inventory(inventory_json, save_path):
inventory_file = file_find(save_path)
else:
inventory_file = os.path.join(save_path, INVENTORY_FILENAME)
if os.path.isfile(inventory_file):
_make_backup(save_path, inventory_file)
with open(inventory_file, 'wb') as f:
f.write(inventory_json.encode('ascii'))
logger.info("Inventory written")

View File

@ -15,6 +15,7 @@
#
# (c) 2014, Kevin Carter <kevin.carter@rackspace.com>
import copy
import json
import logging
import netaddr
@ -1109,6 +1110,9 @@ def main(config=None, check=False, debug=False, environment=None, **kwargs):
# Load existing inventory file if found
inventory, inv_path = filesys.load_inventory(config, INVENTORY_SKEL)
# Make a deep copy for change comparison
orig_inventory = copy.deepcopy(inventory)
# Save the users container cidr as a group variable
cidr_networks = user_defined_config.get('cidr_networks')
if not cidr_networks:
@ -1199,7 +1203,9 @@ def main(config=None, check=False, debug=False, environment=None, **kwargs):
num_hosts = len(inventory['_meta']['hostvars'])
logger.debug("%d hosts found.", num_hosts)
# Save new dynamic inventory
filesys.save_inventory(inventory_json, inv_path)
# Save new dynamic inventory only if modified
if orig_inventory != inventory:
logger.debug("Saving modified inventory")
filesys.save_inventory(inventory_json, inv_path)
return inventory_json