Sindbad~EG File Manager
#!/usr/bin/python
from fcntl import flock, LOCK_EX, LOCK_UN, LOCK_NB
from imp import load_source
from os import listdir, system
from os.path import dirname, isfile, join, realpath
from shutil import move
from subprocess import Popen, PIPE
from sys import argv, exc_info, exit, stdout, version_info
from traceback import format_exc
from xml.dom.minidom import parse
from OmsConfigHostHelpers import write_omsconfig_host_telemetry, write_omsconfig_host_switch_event, write_omsconfig_host_log, stop_old_host_instances
from time import sleep
pathToCurrentScript = realpath(__file__)
pathToCommonScriptsFolder = dirname(pathToCurrentScript)
helperLibPath = join(pathToCommonScriptsFolder, 'helperlib.py')
helperlib = load_source('helperlib', helperLibPath)
operationStatusUtilityPath = join(pathToCommonScriptsFolder, 'OperationStatusUtility.py')
operationStatusUtility = load_source('operationStatusUtility', operationStatusUtilityPath)
operation = 'PerformInventory'
# Redirect output to our log file
fullPathDSCLogger = join(pathToCommonScriptsFolder, 'nxDSCLog.py')
nxDSCLog = load_source('nxDSCLog', fullPathDSCLogger)
logger = nxDSCLog.ConsoleAndFileLogger()
stdout = logger
def usage():
write_omsconfig_host_log('Incorrect parameters to PerformInventory.py: ' + str(argv), pathToCurrentScript, 'WARNING')
print("""Usage: PerformInventory.py [OPTIONS]
OPTIONS (case insensitive):
--InMOF PATH_TO_INVENTORY.MOF
--OutXML PATH_TO_OUTPUT_REPORT.XML
--help
""")
def exitWithError(message, errorCode = 1):
timestamp = operationStatusUtility.get_current_timestamp()
errorMessage = timestamp + ": ERROR from PerformInventory.py: " + message
print(errorMessage)
exit(errorCode)
def printVerboseMessage(message):
timestamp = operationStatusUtility.get_current_timestamp()
verboseMessage = str(timestamp) + ": VERBOSE from PerformInventory.py: " + str(message)
print(verboseMessage)
def main(args):
try:
perform_inventory(args)
except SystemExit:
exit(exc_info()[1])
except Exception:
# Python 2.4-2.7 and 2.6-3 recognize different formats for exceptions. This methods works in all versions.
formattedExceptionMessage = format_exc()
write_omsconfig_host_log('Python exception raised from PerformInventory.py: ' + formattedExceptionMessage, pathToCurrentScript, 'ERROR')
raise
def perform_inventory(args):
Variables = dict()
# Parse command line arguments
optlist = []
command_line_length = len(args)
argIndex = 0
inArgument = False
currentArgument = ""
arg = ""
while argIndex < command_line_length:
arg = args[argIndex]
if argIndex == 0:
# skip the program name
argIndex += 1
continue
if inArgument:
Variables[currentArgument] = arg
inArgument = False
else:
if arg[0:2] == "--":
inArgument = True
currentArgument = arg[2:].lower()
else:
# The rest are not options
args = args[argIndex:]
break
argIndex += 1
if inArgument:
Variables[currentArgument] = arg
AcceptableOptions = ["inmof", "outxml", "help"]
if "help" in Variables:
usage()
exit(0)
optionsValid = True
for arg in Variables.keys():
if arg.lower() not in AcceptableOptions:
optionsValid = False
exitWithError("Error: %s is not a valid option" % arg)
if optionsValid == False:
usage()
exit(1)
dsc_sysconfdir = join(helperlib.CONFIG_SYSCONFDIR, helperlib.CONFIG_SYSCONFDIR_DSC)
dsc_reportdir = join(dsc_sysconfdir, 'InventoryReports')
omicli_path = join(helperlib.CONFIG_BINDIR, 'omicli')
dsc_host_base_path = helperlib.DSC_HOST_BASE_PATH
dsc_host_path = join(dsc_host_base_path, 'bin/dsc_host')
dsc_host_output_path = join(dsc_host_base_path, 'output')
dsc_host_lock_path = join(dsc_host_base_path, 'dsc_host_lock')
dsc_host_switch_path = join(dsc_host_base_path, 'dsc_host_ready')
dsc_configuration_path = join(dsc_sysconfdir, 'configuration')
temp_report_path = join(dsc_configuration_path, 'Inventory.xml.temp')
report_path = join(dsc_configuration_path, 'Inventory.xml')
inventorylock_path = join(dsc_sysconfdir, 'inventory_lock')
if ("omsconfig" in helperlib.DSC_SCRIPT_PATH):
write_omsconfig_host_switch_event(pathToCurrentScript, isfile(dsc_host_switch_path))
if ("omsconfig" in helperlib.DSC_SCRIPT_PATH) and (isfile(dsc_host_switch_path)):
use_omsconfig_host = True
else:
use_omsconfig_host = False
if "outxml" in Variables:
report_path = Variables["outxml"]
parameters = []
if use_omsconfig_host:
parameters.append(dsc_host_path)
parameters.append(dsc_host_output_path)
if "inmof" in Variables:
parameters.append("PerformInventoryOOB")
parameters.append(Variables["inmof"])
else:
parameters.append("PerformInventory")
else:
parameters.append(omicli_path)
parameters.append("iv")
parameters.append(helperlib.DSC_NAMESPACE)
parameters.append("{")
parameters.append("MSFT_DSCLocalConfigurationManager")
parameters.append("}")
if "inmof" in Variables:
parameters.append("PerformInventoryOOB")
parameters.append("{")
parameters.append("InventoryMOFPath")
parameters.append(Variables["inmof"])
parameters.append("}")
else:
parameters.append("PerformInventory")
# Ensure inventory lock file permission is set correctly before opening
operationStatusUtility.ensure_file_permissions(inventorylock_path, '644')
# Open the inventory lock file. This also creates a file if it does not exist.
inventorylock_filehandle = open(inventorylock_path, 'w')
printVerboseMessage("Opened the inventory lock file at the path '" + inventorylock_path + "'")
retval = 0
inventorylock_acquired = True
dschostlock_filehandle = None
inmof_file = ''
if "inmof" in Variables:
inmof_file = Variables["inmof"]
try:
# Acquire inventory file lock
try:
flock(inventorylock_filehandle, LOCK_EX | LOCK_NB)
write_omsconfig_host_log('Inventory lock is acquired by : ' + inmof_file, pathToCurrentScript)
except IOError:
inventorylock_acquired = False
write_omsconfig_host_log('Failed to acquire inventory lock.', pathToCurrentScript, 'WARNING')
if inventorylock_acquired:
dschostlock_acquired = False
if use_omsconfig_host:
if isfile(dsc_host_lock_path):
stop_old_host_instances(dsc_host_lock_path)
# Open the dsc host lock file. This also creates a file if it does not exist.
dschostlock_filehandle = open(dsc_host_lock_path, 'w')
printVerboseMessage("Opened the dsc host lock file at the path '" + dsc_host_lock_path + "'")
# Acquire dsc host file lock
for retry in range(10):
try:
flock(dschostlock_filehandle, LOCK_EX | LOCK_NB)
dschostlock_acquired = True
write_omsconfig_host_log('dsc_host lock file is acquired by : ' + inmof_file, pathToCurrentScript)
break
except IOError:
write_omsconfig_host_log('dsc_host lock file not acquired. retry (#' + str(retry) + ') after 60 seconds...', pathToCurrentScript)
sleep(60)
else:
write_omsconfig_host_log('dsc_host lock file does not exist. Skipping this operation until next consistency hits.', pathToCurrentScript, 'WARNING')
if dschostlock_acquired or (not use_omsconfig_host):
try:
system("rm -f " + dsc_reportdir + "/*")
process = Popen(parameters, stdout = PIPE, stderr = PIPE)
stdout, stderr = process.communicate()
retval = process.returncode
printVerboseMessage(stdout)
if (retval > 0):
write_omsconfig_host_log('dsc_host failed with code = ' + str(retval), pathToCurrentScript)
exit(retval)
# Combine reports together
reportFiles = listdir(dsc_reportdir)
final_xml_report = '<INSTANCE CLASSNAME="Inventory"><PROPERTY.ARRAY NAME="Instances" TYPE="string" EmbeddedObject="object"><VALUE.ARRAY>'
values = []
for reportFileName in reportFiles:
reportFilePath = join(dsc_reportdir, reportFileName)
if not isfile(reportFilePath):
continue
report = parse(reportFilePath)
for valueNode in report.getElementsByTagName('VALUE'):
values.append(valueNode.toxml())
final_xml_report = final_xml_report + "".join(values) + "</VALUE.ARRAY></PROPERTY.ARRAY></INSTANCE>"
# Ensure temporary inventory report file permission is set correctly before opening
operationStatusUtility.ensure_file_permissions(temp_report_path, '644')
tempReportFileHandle = open(temp_report_path, 'w')
try:
tempReportFileHandle.write(final_xml_report)
finally:
if (tempReportFileHandle):
tempReportFileHandle.close()
# Ensure temporary inventory report file permission is set correctly after opening
operationStatusUtility.ensure_file_permissions(temp_report_path, '644')
system("rm -f " + dsc_reportdir + "/*")
move(temp_report_path, report_path)
# Ensure inventory report file permission is set correctly
operationStatusUtility.ensure_file_permissions(report_path, '644')
finally:
if (dschostlock_filehandle):
# Release inventory file lock
flock(inventorylock_filehandle, LOCK_UN)
# Release dsc host file lock
if isfile(dsc_host_lock_path) and use_omsconfig_host:
try:
flock(dschostlock_filehandle, LOCK_UN)
except:
pass
finally:
if (inventorylock_filehandle):
# Close inventory lock file handle
inventorylock_filehandle.close()
if (dschostlock_filehandle):
# Close dsc host lock file handle
if use_omsconfig_host:
try:
dschostlock_filehandle.close()
except:
pass
# Ensure inventory lock file permission is set correctly after opening
operationStatusUtility.ensure_file_permissions(inventorylock_path, '644')
# Ensure dsc host lock file permission is set correctly after opening
if use_omsconfig_host:
operationStatusUtility.ensure_file_permissions(dsc_host_lock_path, '644')
exit(retval)
if __name__ == "__main__":
main(argv)
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists