From 08f917e721f569bc071a0e8ccc9ba4e8262c1eb2 Mon Sep 17 00:00:00 2001 From: aguerre Date: Wed, 10 Jul 2013 14:18:47 +0000 Subject: [PATCH] Consider echo and unset keywords when parsing configuration files --- bin/appli_gen.py | 47 ++++++++++++++++++++++++++++++++++++++++-- bin/parseConfigFile.py | 30 ++++++++++++++++++++------- bin/salomeRunner.py | 23 ++++++++++++++++++++- 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/bin/appli_gen.py b/bin/appli_gen.py index cd64c5f87..3b4c21355 100644 --- a/bin/appli_gen.py +++ b/bin/appli_gen.py @@ -41,6 +41,7 @@ import virtual_salome # --- names of tags in XML configuration file appli_tag = "application" prereq_tag = "prerequisites" +system_conf_tag = "system_conf" modules_tag = "modules" module_tag = "module" samples_tag = "samples" @@ -83,6 +84,10 @@ class xml_parser: if self.space == [appli_tag, prereq_tag] and path_att in attrs.getNames(): self.config["prereq_path"] = attrs.getValue( path_att ) pass + # --- if we are analyzing "system_conf" element then store its "path" attribute + if self.space == [appli_tag, system_conf_tag] and path_att in attrs.getNames(): + self.config["system_conf_path"] = attrs.getValue( path_att ) + pass # --- if we are analyzing "resources" element then store its "path" attribute if self.space == [appli_tag, resources_tag] and path_att in attrs.getNames(): self.config["resources_path"] = attrs.getValue( path_att ) @@ -203,6 +208,7 @@ def install(prefix,config_file,verbose=0): os.system(command) pass + # Creation of env.d directory virtual_salome.mkdir(os.path.join(home_dir,'env.d')) if os.path.isfile(_config["prereq_path"]): command='cp -p ' + _config["prereq_path"] + ' ' + os.path.join(home_dir,'env.d','envProducts.sh') @@ -211,8 +217,16 @@ def install(prefix,config_file,verbose=0): else: print "WARNING: prerequisite file does not exist" pass + # :NOTE: For the new launch procedure, we do not use a "physical" .cfg + # file for prerequisites; the launch procedure automatically reads and + # converts the envProducts.sh file. - #environment file: configSalome.sh + if _config.has_key("system_conf_path") and os.path.isfile(_config["system_conf_path"]): + command='cp -p ' + _config["system_conf_path"] + ' ' + os.path.join(home_dir,'env.d','envConfSystem.sh') + os.system(command) + pass + + # Create environment file: configSalome.sh f =open(os.path.join(home_dir,'env.d','configSalome.sh'),'w') for module in _config["modules"]: command='export '+ module + '_ROOT_DIR=${HOME}/${APPLI}\n' @@ -228,8 +242,26 @@ def install(prefix,config_file,verbose=0): f.close() + # Create configuration file: configSalome.cfg + f =open(os.path.join(home_dir,'env.d','configSalome.cfg'),'w') + command = "[SALOME ROOT_DIR (modules) Configuration]\n" + f.write(command) + for module in _config["modules"]: + command=module + '_ROOT_DIR=${HOME}/${APPLI}\n' + f.write(command) + pass + if _config.has_key("samples_path"): + command='DATA_DIR=' + _config["samples_path"] +'\n' + f.write(command) + pass + if _config.has_key("resources_path") and os.path.isfile(_config["resources_path"]): + command='USER_CATALOG_RESOURCES_FILE=' + os.path.abspath(_config["resources_path"]) +'\n' + f.write(command) + + f.close() + - #environment file: configGUI.sh + # Create environment file: configGUI.sh f =open(os.path.join(home_dir,'env.d','configGUI.sh'),'w') command = """export SalomeAppConfig=${HOME}/${APPLI} export SUITRoot=${HOME}/${APPLI}/share/salome @@ -239,6 +271,17 @@ export MMGT_REENTRANT=1 f.write(command) f.close() + # Create configuration file: configGUI.cfg + f =open(os.path.join(home_dir,'env.d','configGUI.cfg'),'w') + command = """[SALOME GUI Configuration] +SalomeAppConfig=${HOME}/${APPLI} +SUITRoot=${HOME}/${APPLI}/share/salome +DISABLE_FPE=1 +MMGT_REENTRANT=1 +""" + f.write(command) + f.close() + #SalomeApp.xml file f =open(os.path.join(home_dir,'SalomeApp.xml'),'w') command=""" diff --git a/bin/parseConfigFile.py b/bin/parseConfigFile.py index cd2240199..808505561 100644 --- a/bin/parseConfigFile.py +++ b/bin/parseConfigFile.py @@ -3,11 +3,13 @@ import os import logging import re from io import StringIO +import subprocess logging.basicConfig() logConfigParser = logging.getLogger(__name__) -RESERVED_PREFIX = 'ADD_TO_' +ADD_TO_PREFIX = 'ADD_TO_' +UNSET_KEYWORD = 'UNSET' # :TRICKY: So ugly solution... @@ -143,9 +145,10 @@ def _processConfigFile(config, reserved = []): # :TODO: may detect duplicated variables in the same section (raise a warning) # or even duplicate sections + unsetVariables = [] outputVariables = [] # Get raw items for each section, and make some processing for environment variables management - reservedKeys = [RESERVED_PREFIX+str(x) for x in reserved] # produce [ 'ADD_TO_reserved_1', 'ADD_TO_reserved_2', ..., ADD_TO_reserved_n ] + reservedKeys = [ADD_TO_PREFIX+str(x) for x in reserved] # produce [ 'ADD_TO_reserved_1', 'ADD_TO_reserved_2', ..., ADD_TO_reserved_n ] reservedValues = dict([str(i),[]] for i in reserved) # create a dictionary in which keys are the 'ADD_TO_reserved_i' and associated values are empty lists: { 'reserved_1':[], 'reserved_2':[], ..., reserved_n:[] } sections = config.sections() for section in sections: @@ -156,6 +159,8 @@ def _processConfigFile(config, reserved = []): for key,val in entries: if key in reserved: logConfigParser.error("Invalid use of reserved variable: %s in file: %s"%(key, filename)) + elif key == UNSET_KEYWORD: + unsetVariables += val.replace(',', ' ').split() else: expandedVal = os.path.expandvars(val) # expand environment variables # Search for not expanded variables (i.e. non-existing environment variables) @@ -165,7 +170,7 @@ def _processConfigFile(config, reserved = []): expandedVal = _trimColons(expandedVal) if key in reservedKeys: - shortKey = key[len(RESERVED_PREFIX):] + shortKey = key[len(ADD_TO_PREFIX):] vals = expandedVal.split(',') reservedValues[shortKey] += vals # remove left&right spaces on each element @@ -177,7 +182,7 @@ def _processConfigFile(config, reserved = []): pass # end for key,val pass # end for section - return outputVariables, reservedValues + return unsetVariables, outputVariables, reservedValues # def _trimColons(var): @@ -203,9 +208,11 @@ class EnvFileConverter(object): self.outputFile = outputFile self.allParsedVariableNames=[] # exclude line that begin with: - self.exclude = [ 'if', 'then', 'fi', '#' ] + self.exclude = [ 'if', 'then', 'fi', '#', 'echo' ] # discard the following keywords if at the beginning of line: self.discard = [ 'export' ] + # the following keywords imply a special processing if at the beginning of line: + self.special = [ 'unset' ] def readline(self): if self.sechead: @@ -225,6 +232,12 @@ class EnvFileConverter(object): return '\n' # look for substrinsg beginning with sharp charcter ('#') line = re.sub(r'#.*$', r'', line) + # line to be pre-processed? (beginning by a keyword of self.special) + for k in self.special: + if k == "unset" and line.startswith(k): + line = line[len(k):] + line = line.strip(' \t\n\r') + line = UNSET_KEYWORD + ": " + line # line to be pre-processed? (beginning by a keyword of self.discard) for k in self.discard: if line.startswith(k): @@ -235,7 +248,7 @@ class EnvFileConverter(object): if line.startswith(k) and "=" in line: variable, value = line.split('=') value = self._purgeValue(value, k) - line = RESERVED_PREFIX + k + ": " + value + line = ADD_TO_PREFIX + k + ": " + value # Update list of variable names if "=" in line: variable, value = line.split('=') @@ -257,8 +270,8 @@ class EnvFileConverter(object): # Replace `shell_command` by its result def myrep(obj): obj = re.sub('`', r'', obj.group(0)) # remove quotes - import subprocess - res = subprocess.Popen([obj], stdout=subprocess.PIPE).communicate()[0] + obj = obj.split() + res = subprocess.Popen(obj, stdout=subprocess.PIPE).communicate()[0] res = res.strip(' \t\n\r') # trim whitespaces return res # @@ -295,6 +308,7 @@ def convertEnvFileToConfigFile(envFilename, configFilename): config = MultiOptSafeConfigParser() config.optionxform = str # case sensitive config.readfp(EnvFileConverter(finput, 'SALOME Configuration', reserved, outputFile=foutput)) + foutput.close() logConfigParser.info('Configuration file generated: %s'%configFilename) diff --git a/bin/salomeRunner.py b/bin/salomeRunner.py index df8846a97..bea729836 100644 --- a/bin/salomeRunner.py +++ b/bin/salomeRunner.py @@ -1,6 +1,7 @@ import os import sys import logging +import ConfigParser from parseConfigFile import parseConfigFile from parseConfigFile import convertEnvFileToConfigFile @@ -42,10 +43,15 @@ class SalomeRunner: if extension == ".cfg": self.__setEnvironmentFromConfigFile(filename) elif extension == ".sh": + #temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False) temp = tempfile.NamedTemporaryFile(suffix='.cfg') try: convertEnvFileToConfigFile(filename, temp.name) self.__setEnvironmentFromConfigFile(temp.name) + except ConfigParser.ParsingError, e: + self.getLogger().warning("Invalid token found when parsing file: %s\n"%(filename)) + print e + print '\n' finally: # Automatically cleans up the file temp.close() @@ -91,6 +97,12 @@ class SalomeRunner: os.environ[name] = value # + """Unset environment variable""" + def unsetEnviron(self, name): + if os.environ.has_key(name): + del os.environ[name] + # + ################################### # This begins the private section # ################################### @@ -161,10 +173,19 @@ Commands: except AttributeError: self.getLogger().error("Method %s is not implemented.", command) sys.exit(1) + except: + self.getLogger().error("Unexpected error:") + import traceback + traceback.print_exc() + sys.exit(1) # def __setEnvironmentFromConfigFile(self, filename): - configVars, reservedDict = parseConfigFile(filename, reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH']) + unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH']) + + # unset variables + for var in unsetVars: + self.unsetEnviron(var) # set environment for reserved in reservedDict: -- 2.39.2