Package Ganga :: Package Utility :: Package Config :: Module Config
[hide private]
[frames] | no frames]

Source Code for Module Ganga.Utility.Config.Config

  1  """ 
  2  A simple configuration interface for Ganga packages. 
  3   
  4  1) Overview 
  5   
  6  PackageConfig object corresponds to a configuration section in the INI file. 
  7  Typically each plugin handler has its own section. Additionally Ganga provides 
  8  a somewhat arbitrary number of other configuration packages. 
  9   
 10  Configuration of the package is done in several phases: 
 11   - phase one: developer defines the hardcoded values in his package (default level); 
 12                addOption 
 13   - phase two: at startup ganga reads config files and set options (session level); 
 14                setSessionValue() is used 
 15   - phase three: at runtime user may modify options via GPI (user level); 
 16                setUserValue() is used for setting, getEffectiveOption() for getting 
 17   
 18   
 19  2) Defining default options for your package: 
 20   
 21  #MyPackage.py# 
 22   
 23  import Ganga.Utility.Config 
 24   
 25  config = Ganga.Utility.Config.getConfig('MyPackage') 
 26   
 27  config.addOption('opt1','x','this is option 1') 
 28  config.addOption('opt2',3.0, 'this is option 2') 
 29   
 30  The  default  values of  the  options  may  be strings,  numbers,other 
 31  built-in  types  or  any  GPI  objects names  defined  in  the  global 
 32  config_scope dictionary (in this module). 
 33   
 34  IMPORTANT: choose the type of the default value carefully: session and 
 35  user options  will be automatically  converted to the type  implied by 
 36  the default value (you may  also override the type checking default in 
 37  setDefaultOption)  .   The  conversion   is  done  as  following  (for 
 38  setSessionValue and setUserValue): 
 39   
 40   - nothing is done (value is assigned 'as-is'): 
 41      - if the default type is a string and the assigned value is a string 
 42      - if there is no default value 
 43   
 44   - eval the string value 
 45   
 46   - check if the type matches the default type and raise ConfigError in case of mismatch 
 47      - unless the default type is None 
 48    
 49  Typically strings are assigned via setSessionValue() as they are read 
 50  from the config file or command line. 
 51   
 52  Note for bootstrap procedure: it is OK to first set the session option 
 53  and  then  to  set  it's  default  value. That  is  to  say  that  the 
 54  configuration may  be read from the  config file prior  to loading the 
 55  corresponding module which  uses it. It is NOT OK  to set user options 
 56  before the end of the bootstrap procedure. 
 57   
 58   
 59  3) Getting effective values and using callback handlers 
 60   
 61  To get the effective value of an option you may use: 
 62   
 63  print config['opt1'] 
 64  print config.getEffectiveOption('opt1') 
 65  print config.getEffectiveOptions() # all options 
 66   
 67  The  effective value  takes  into account  default,  session and  user 
 68  settings  and  may change  at  runtime.  In  GPI  users  only get  the 
 69  effective values and may only set values at the user level. 
 70   
 71  You  may also attach  the callback  handlers at  the session  and user 
 72  level.     Pre-process   handlers   may    modify   what    has   been 
 73  set. Post-process handlers may be used to trigger extra actions. 
 74   
 75  def pre(opt,val): 
 76      print 'always setting a square of the value' 
 77      return val*2 
 78   
 79  def post(opt,val): 
 80      print 'effectively set',val 
 81       
 82  config.attachUserHandler(pre,post) 
 83   
 84  4) How does user see all this in GPI ? 
 85   
 86  There is a GPI wrapper in Ganga.GPIDev.Lib.Config which: 
 87       - internally uses setUserValue and getEffectiveOption 
 88       - has a more appealing interface 
 89   
 90   
 91  """ 
 92   
 93  from Ganga.Core.exceptions import GangaException 
94 -class ConfigError(GangaException):
95 """ ConfigError indicates that an option does not exist or it cannot be set. 96 """
97 - def __init__(self,what):
98 GangaException.__init__(self) 99 self.what = what
100
101 - def __str__(self):
102 return "ConfigError: %s "%(self.what)
103 104 # WARNING: avoid importing logging at the module level in this file 105 # for example, do not do here: from Ganga.Utility.logging import logger 106 # use getLogger() function defined below: 107 108 logger = None 109
110 -def getLogger():
111 global logger 112 if not logger is None: 113 return logger 114 115 # for the configuration of the logging package itself (in the initial phases) the logging may be disabled 116 try: 117 import Ganga.Utility.logging 118 logger = Ganga.Utility.logging.getLogger() 119 return logger 120 except AttributeError: 121 # in such a case we return a mock proxy object which ignore all calls such as logger.info()... 122 class X: 123 def __getattr__(self,name): 124 def f(*args,**kwds): 125 pass
126 return f 127 return X() 128 129 130 # All configuration units 131 allConfigs = {} 132 133 # configuration session buffer 134 # this dictionary contains the value for the options which are defined in the configuration file and which have 135 # not yet been defined 136 allConfigFileValues = {} 137 138 # helper function which helps migrating the names from old naming convention 139 # to the stricter new one: spaces are removed, colons replaced by underscored 140 # returns a valid name or raises a ValueError
141 -def _migrate_name(name):
142 import Ganga.Utility.strings as strings 143 144 if not strings.is_identifier(name): 145 name2 = strings.drop_spaces(name) 146 name2 = name2.replace(':','_') 147 148 if not strings.is_identifier(name2): 149 raise ValueError('config name %s is not a valid python identifier' % name) 150 else: 151 logger = getLogger() 152 logger.warning('obsolete config name found: replaced "%s" -> "%s"'%(name,name2)) 153 logger.warning('config names must be python identifiers, please correct your usage in the future ') 154 name = name2 155 return name
156 157
158 -def getConfig(name):
159 """ Get an exisiting PackageConfig or create a new one if needed. 160 Temporary name migration conversion applies -- see _migrate_name(). 161 Principle is the same as for getLogger() -- the config instances may 162 be easily shared between different parts of the program.""" 163 164 name = _migrate_name(name) 165 try: 166 return allConfigs[name] 167 except KeyError: 168 #print 'getConfig',name 169 allConfigs[name] = PackageConfig(name,'Documentation not available') 170 return allConfigs[name]
171
172 -def makeConfig(name,docstring,**kwds):
173 """ 174 Create a config package and attach metadata to it. makeConfig() should be called once for each package. 175 """ 176 177 if _after_bootstrap: 178 raise ConfigError('attempt to create a configuration section [%s] after bootstrap'%name) 179 180 name = _migrate_name(name) 181 try: 182 #print 'makeConfig',name 183 c = allConfigs[name] 184 c.docstring = docstring 185 for k in kwds: 186 setattr(c,k,kwds[k]) 187 except KeyError: 188 c = allConfigs[name] = PackageConfig(name,docstring,**kwds) 189 190 ## # _after_bootstrap flag solves chicken-egg problem between logging and config modules 191 ## if _after_bootstrap: 192 ## # make the GPI proxy 193 ## from Ganga.GPIDev.Lib.Config.Config import createSectionProxy 194 ## createSectionProxy(name) 195 196 c._config_made = True 197 return c
198 199
200 -class ConfigOption:
201 """ Configuration Option has a name, default value and a docstring. 202 203 Metainformation: 204 * type - if not specified, then the type is inferred from the default value, type may be a type object such as type(1), StringType, type(None) or a list 205 of such objects - in this case any type in the list is accepted 206 * examples - example how to use the option 207 * hidden - True => do not show the option at the level of GPI proxy (default False) 208 * cfile - False => do not put the option in the generated config file (default True) 209 * filter - None => filter the option value when set (session and user levels) 210 * typelist - None => a typelist as in GPI schema 211 The configuration option may also define the session_value and default_value. The value property gives the effective value. 212 """
213 - def __init__(self,name):
214 self.name = name
215
216 - def defineOption(self,default_value,docstring,**meta):
217 218 #if self.check_defined(): 219 # print 'option',self.name,'already defined' 220 221 self.default_value = default_value 222 self.docstring = docstring 223 self.hidden=False 224 self.cfile=True 225 self.examples = None 226 self.filter = None 227 self.typelist = None 228 229 for m in meta: 230 setattr(self,m,meta[m]) 231 232 self.convert_type('session_value') 233 self.convert_type('user_value')
234
235 - def setSessionValue(self,session_value):
236 #try: 237 if self.filter: 238 session_value = self.filter(self,session_value) 239 #except Exception,x: 240 # import Ganga.Utility.logging 241 # logger = Ganga.Utility.logging.getLogger() 242 # logger.warning('problem with option filter: %s: %s',self.name,x) 243 244 #print 'setting session value %s = %s',self.name,str(session_value) 245 try: 246 session_value = self.transform_PATH_option(session_value,self.session_value) 247 except AttributeError: 248 pass 249 250 try: 251 old_value = self.session_value 252 except AttributeError: 253 pass 254 255 self.session_value = session_value 256 try: 257 self.convert_type('session_value') 258 except Exception,x: 259 #rollback if conversion failed 260 try: 261 self.session_value = old_value 262 except NameError: 263 del self.session_value 264 raise x
265
266 - def setUserValue(self,user_value):
267 268 try: 269 if self.filter: 270 user_value = self.filter(self,user_value) 271 except Exception,x: 272 logger = getLogger() 273 logger.warning('problem with option filter: %s: %s',self.name,x) 274 275 try: 276 user_value = self.transform_PATH_option(user_value,self.user_value) 277 except AttributeError: 278 pass 279 280 try: 281 old_value = self.user_value 282 except AttributeError: 283 pass 284 285 self.user_value = user_value 286 try: 287 self.convert_type('user_value') 288 except Exception,x: 289 #rollback if conversion failed 290 try: 291 self.user_value = old_value 292 except NameError: 293 del self.user_value 294 raise x
295
296 - def overrideDefaultValue(self,default_value):
297 try: 298 default_value = self.transform_PATH_option(default_value,self.default_value) 299 except AttributeError: 300 pass 301 self.default_value = default_value 302 self.convert_type('user_value') 303 self.convert_type('session_value')
304
305 - def __getattr__(self,name):
306 if name == 'value': 307 values = [] 308 309 for n in ['user','session','default']: 310 try: 311 values.append(getattr(self,n+'_value')) 312 except AttributeError: 313 pass 314 315 if values: 316 return reduce(self.transform_PATH_option,values) 317 318 #for n in ['user','session','default']: 319 # try: 320 # return getattr(self,n+'_value') 321 # except AttributeError: 322 # pass 323 324 if name == 'level': 325 326 for level,name in [(0,'user'),(1,'session'),(2,'default')]: 327 if hasattr(self,name+'_value'): 328 return level 329 raise AttributeError,name
330
331 - def __setattr__(self,name,value):
332 if name in ['value','level']: 333 raise AttributeError('Cannot set "%s" attribute of the option object'%name) 334 self.__dict__[name]=value
335
336 - def check_defined(self):
337 return hasattr(self,'default_value')
338
339 - def transform_PATH_option(self,new_value,current_value):
340 return transform_PATH_option(self.name,new_value,current_value)
341
342 - def convert_type(self,x_name):
343 ''' Convert the type of session_value or user_value (referred to by x_name) according to the types defined by the self. 344 If the option has not been defined or the x_name in question is not defined, then this method is no-op. 345 If conversion cannot be performed (type mismatch) then raise ConfigError. 346 ''' 347 348 try: 349 value = getattr(self,x_name) 350 except AttributeError: 351 return 352 353 logger = getLogger() 354 355 # calculate the cast type, if it cannot be done then the option has not been yet defined (setDefaultValue) 356 # in this case do not modify the value 357 if not self.typelist is None: 358 cast_type = self.typelist # in this case cast_type is a list of string dotnames (like for typelist property in schemas) 359 else: 360 try: 361 cast_type = type(self.default_value) # in this case cast_type is a single type object 362 except AttributeError: 363 return 364 365 new_value = value 366 367 #optdesc = 'while setting option [%s]%s = %s ' % (self.name,o,str(value)) 368 optdesc = 'while setting option [.]%s = %s ' % (self.name,str(value)) 369 370 # eval string values only if the cast_type is not exactly a string 371 if type(value) is type('') and not cast_type is type(''): 372 try: 373 new_value = eval(value,config_scope) 374 logger.debug('applied eval(%s) -> %s (%s)',value,new_value,optdesc) 375 except Exception,x: 376 logger.debug('ignored failed eval(%s): %s (%s)',value,x,optdesc) 377 378 # check the type of the value unless the cast_type is not NoneType 379 logger.debug('checking value type: %s (%s)',str(cast_type),optdesc) 380 381 import types 382 def check_type(x,t): 383 return type(x) is t or x is t
384 385 type_matched = False 386 387 # first we check using the same rules for typelist as for the GPI proxy objects 388 try: 389 import Ganga.GPIDev.TypeCheck 390 type_matched = Ganga.GPIDev.TypeCheck._valueTypeAllowed(new_value,cast_type,logger) 391 except TypeError: #cast_type is not a list 392 type_matched = check_type(new_value,cast_type) 393 394 from Ganga.Utility.logic import implies 395 if not implies(not cast_type is type(None), type_matched): 396 raise ConfigError('type mismatch: expected %s got %s (%s)'%(str(cast_type),str(type(new_value)),optdesc)) 397 398 setattr(self,x_name,new_value)
399 400 # indicate if the GPI proxies for the configuration have been created 401 _after_bootstrap = False 402 403 # Scope used by eval when reading-in the configuration. 404 # Symbols defined in this scope will be correctly evaluated. For example, File class adds itself here. 405 # This dictionary may also be used by other parts of the system, e.g. XML repository. 406 config_scope = {} 407
408 -class PackageConfig:
409 """ Package Config object represents a Configuration Unit (typically 410 related to Ganga Packages). It should not be created directly 411 but only via the getConfig method. 412 413 PackageConfig has a name which corresponds to the [name] section in 414 the .gangarc file. Once initialized the configuration may only be 415 modified by special setUserValues methods. This will give a chance 416 to Ganga to take further actions such as automatic update of the 417 .gangarc file. 418 419 The PackageConfig interface is designed for Ganga Package Developers. 420 User oriented interface is available via the GPI. 421 422 meta keywords: 423 - is_open : True => new options may be added by the users (default False) 424 - cfile : True => section will be generated in the config file 425 - hidden: True => section is not visible in the GPI 426 427 """ 428
429 - def __init__(self,name,docstring,**meta):
430 """ Arguments: 431 - name may not contain blanks and should be a valid python identifier otherwise ValueError is raised 432 - temporary name migration conversion applies -- see _migrate_name() 433 meta args have the same meaning as for the ConfigOption: 434 - hidden 435 - cfile 436 """ 437 self.name = _migrate_name(name) 438 self.options = {} # {'name':Option('name',default_value,docstring)} 439 self.docstring = docstring 440 self.hidden = False 441 self.cfile = True 442 443 # processing handlers 444 self._user_handlers = [] 445 self._session_handlers = [] 446 447 self.is_open = False 448 449 for m in meta: 450 setattr(self,m,meta[m]) 451 452 # sanity check to force using makeConfig() 453 self._config_made = False 454 455 if _configured and self.is_open: 456 print 'cannot define open configuration section %s after configure() step'%self.name 457 logger = getLogger() 458 logger.error('cannot define open configuration section %s after configure() step',self.name)
459
460 - def _addOpenOption(self,name,value):
461 self.addOption(name,value,"",override=True)
462
463 - def __iter__(self):
464 """ Iterate over the effective options. """ 465 #return self.getEffectiveOptions().__iter__() 466 return self.options.__iter__()
467
468 - def __getitem__(self,o):
469 """ Get the effective value of option o. """ 470 return self.getEffectiveOption(o)
471
472 - def addOption(self,name,default_value, docstring, override=False, **meta):
473 474 if _after_bootstrap and not self.is_open: 475 raise ConfigError('attempt to add a new option [%s]%s after bootstrap'%(self.name,name)) 476 477 try: 478 option = self.options[name] 479 except KeyError: 480 option = ConfigOption(name) 481 482 if option.check_defined() and not override: 483 logger = getLogger() 484 logger.warning('attempt to add again the option [%s]%s (ignored)',self.name,name) 485 return 486 487 option.defineOption(default_value,docstring,**meta) 488 self.options[option.name] = option 489 490 try: 491 session_value = allConfigFileValues[self.name][option.name] 492 option.setSessionValue(session_value) 493 del allConfigFileValues[self.name][option.name] 494 except KeyError: 495 pass
496 497 498 ## # set the GPI proxy object if already created, if not it will be created by bootstrap() function in the GPI Config module 499 ## if _after_bootstrap: 500 ## from Ganga.GPIDev.Lib.Config.Config import createOptionProxy 501 ## createOptionProxy(self.name,name) 502
503 - def setSessionValue(self,name,value,raw=0):
504 """ Add or override options as a part of second phase of 505 initialization of this configuration module (PHASE 2) If the 506 default type of the option is not string, then the expression 507 will be evaluated. Optional argument raw indicates if special 508 treatment of PATH-like variables is disabled (enabled by 509 default). The special treatment applies to the session level 510 values only (and not the default one!). """ 511 512 logger = getLogger() 513 514 logger.debug('trying to set session option [%s]%s = %s',self.name, name,value) 515 516 for h in self._session_handlers: 517 value = h[0](name,value) 518 519 if not self.options.has_key(name): 520 self.options[name] = ConfigOption(name) 521 522 self.options[name].setSessionValue(value) 523 524 logger.debug('sucessfully set session option [%s]%s = %s',self.name, name,value) 525 526 for h in self._session_handlers: 527 h[1](name,value)
528 529
530 - def setUserValue(self,name,value):
531 """ Modify option at runtime. This method corresponds to the user 532 action so the value of the option is considered 'modified' If 533 the default type of the option is not string, then the 534 expression will be evaluated. """ 535 536 logger = getLogger() 537 538 logger.debug('trying to set user option [%s]%s = %s',self.name, name,value) 539 540 for h in self._user_handlers: 541 value = h[0](name,value) 542 543 self.options[name].setUserValue(value) 544 545 logger.debug('successfully set user option [%s]%s = %s',self.name, name,value) 546 547 for h in self._user_handlers: 548 h[1](name,value)
549 550
551 - def overrideDefaultValue(self,name,val):
552 self.options[name].overrideDefaultValue(val)
553
554 - def revertToSession(self,name):
555 try: 556 del self.options[name].user_value 557 except AttributeError: 558 pass
559
560 - def revertToDefault(self,name):
561 self.revertToSession(name) 562 try: 563 del self.options[name].session_value 564 except AttributeError: 565 pass
566
567 - def revertToSessionOptions(self):
568 for name in self.options: 569 self.revertToSession(name)
570
571 - def revertToDefaultOptions(self):
572 self.revertToSessionOptions() 573 for name in self.options: 574 self.revertToDefault(name)
575
576 - def getEffectiveOptions(self):
577 eff = {} 578 for name in self.options: 579 eff[name] = self.options[name].value 580 return eff
581
582 - def getEffectiveOption(self,name):
583 try: 584 return self.options[name].value 585 except KeyError: 586 raise ConfigError('option "%s" does not exist in "%s"'%(name,self.name))
587
588 - def getEffectiveLevel(self,name):
589 """ Return 0 if option is effectively set at the user level, 1 590 if at session level or 2 if at default level """ 591 try: 592 return self.options[name].level 593 except KeyError,x: 594 raise ConfigError('option "%s" does not exist in "%s"'%(x,self.name))
595
596 - def attachUserHandler(self,pre,post):
597 """ Attach a user handler: 598 - pre(name,x) will be always called before setUserValue(name,x) 599 - post(name,x2) will be always called after setUserValue(name,x) 600 601 pre() acts as a filter for the value of the option: its return value (x2) will be set 602 Before setting the value will be evaluated (unless a default value type is a string) 603 post() will get x2 as the option value. 604 605 It is OK to give None for pre or post. For example: 606 config.attachUserHandler(None,post) attaches only the post handler. """ 607 608 if pre is None: pre = lambda opt,val:val 609 if post is None: post = lambda opt,val:None 610 611 self._user_handlers.append((pre,post))
612
613 - def attachSessionHandler(self,pre,post):
614 """See attachUserHandler(). """ 615 # FIXME: this will NOT always work and should be redesigned, see ConfigOption.filter 616 if pre is None: pre = lambda opt,val:val 617 if post is None: post = lambda opt,val:None 618 619 self._session_handlers.append((pre,post))
620
621 - def deleteUndefinedOptions(self):
622 for o in self.options.keys(): 623 if not self.options[o].check_defined(): 624 del self.options[o]
625 626 import ConfigParser 627
628 -def make_config_parser(system_vars):
629 cfg = ConfigParser.ConfigParser() 630 cfg.optionxform = str # case sensitive 631 cfg.defaults().update(system_vars) 632 return cfg
633
634 -def transform_PATH_option(name,new_value,current_value):
635 """ 636 Return the new value of the option 'name' taking into account special rules for PATH-like variables: 637 638 A variable is PATH-like if the name ends in _PATH. 639 Return 'new_value:current_value' unless new_value starts in ':::' or current_value is None. 640 In that case return new_value. 641 642 Example: 643 if a name of a option terminates in _PATH then the value will not be overriden but 644 appended: 645 file1.ini: 646 ANY_PATH = x 647 file2.ini: 648 ANY_PATH = y 649 650 result of the merge is: ANY_PATH = x:y 651 652 If you want to override the path you should use :::path, for example: 653 file1.ini: 654 ANY_PATH = x 655 file2.ini 656 ANY_PATH = :::y 657 result of the merge is: ANY_PATH = y 658 659 For other variables just return the new_value. 660 """ 661 662 663 664 PATH_ITEM = '_PATH' 665 if name[-len(PATH_ITEM):] == PATH_ITEM: 666 logger.debug('PATH-like variable: %s %s %s',name,new_value,current_value) 667 if current_value is None: 668 return new_value 669 if new_value[:3] != ':::': 670 logger.debug('Prepended %s to PATH-like variable %s',new_value,name) 671 return new_value + ':' + current_value 672 else: 673 logger.debug('Resetting PATH-like variable %s to %s',name,new_value) 674 return new_value[3:] 675 return new_value
676
677 -def read_ini_files(filenames,system_vars):
678 """ Return a ConfigParser object which contains all options from the 679 sequence of files (which are parsed from left-to-right). 680 Apply special rules for PATH-like variables - see transform_PATH_option() """ 681 682 import re, os 683 logger = getLogger() 684 685 logger.debug('reading ini files: %s',str(filenames)) 686 687 main = make_config_parser(system_vars) 688 689 #load all config files and apply special rules for PATH-like variables 690 #note: main.read(filenames) cannot be used because of that 691 692 if type(filenames) is type(''): 693 filenames = [filenames] 694 695 for f in filenames: 696 if f is None or f=='': 697 continue 698 cc = make_config_parser(system_vars) 699 logger.info('reading config file %s',f) 700 try: 701 cc.readfp(file(f)) 702 except IOError,x: 703 logger.warning('%s',str(x)) 704 705 for sec in cc.sections(): 706 if not main.has_section(sec): 707 main.add_section(sec) 708 709 for name in cc.options(sec): 710 value = cc.get(sec,name) 711 712 # do not put the DEFAULTS into the sections (no need) 713 if name in cc.defaults().keys(): 714 continue 715 716 # special rules (NOT APPLIED IN DEFAULT SECTION): 717 718 try: 719 current_value = main.get(sec,name) 720 except ConfigParser.NoOptionError: 721 current_value = None 722 723 value = transform_PATH_option(name,value,current_value) 724 725 # check for the use of environment vars 726 #m = re.search('\$\{[^${}]*\}', value) # matches on ${...} 727 m = re.search('\$\$[^${}]*\$\$', value) # matches on $$...$$ 728 while m: 729 envvar = m.group(0).strip('$') 730 731 # is env variable 732 envval = '' 733 if os.environ.has_key(envvar): 734 envval = os.environ[envvar] 735 736 value = value.replace( m.group(0), envval ) 737 m = re.search('\$\{[^${}]*\}', value ) 738 739 # FIXME: strip trailing whitespaces -- SHOULD BE DONE BEFORE IF AT ALL? 740 value = value.rstrip() 741 main.set(sec,name,value) 742 743 return main
744 745
746 -def setSessionValue(config_name,option_name,value):
747 if allConfigs.has_key(config_name): 748 c = getConfig(config_name) 749 if c.options.has_key(option_name): 750 c.setSessionValue(option_name,value) 751 return 752 if c.is_open: 753 c._addOpenOption(option_name,value) 754 c.setSessionValue(option_name,value) 755 return 756 757 # put value in the buffer, it will be removed from the buffer when option is added 758 allConfigFileValues.setdefault(config_name,{}) 759 allConfigFileValues[config_name][option_name] = value
760 761 762 _configured = False 763
764 -def configure(filenames,system_vars):
765 """ Sets session values for all options in all configuration units 766 defined in the sequence of config files. Initialize config parser 767 object with system variables (such as GANGA_TOP, GANGA_VERSION and 768 alike). Contrary to standard config parser behaviour the options 769 from the DEFAULTS section are not visible in the config units. 770 771 At the time of reading the initialization files, the default options in 772 the configuration options (default values) may have not yet been defined. 773 """ 774 775 776 cfg = read_ini_files(filenames,system_vars) 777 778 for name in cfg.sections(): 779 for o in cfg.options(name): 780 # Important: do not put the options from the DEFAULTS section into the configuration units! 781 if o in cfg.defaults().keys(): 782 continue 783 v = cfg.get(name,o) 784 setSessionValue(name,o,v) 785 786 _configured = True
787 788 789 # KH 050725: Add possibility to overwrite at run-time option set in 790 # configuration file 791 # => useful for executables where particular actions need 792 # to be forced or suppressed
793 -def setConfigOption( section = "", item = "", value = "" ):
794 """Function to overwrite option values set in configuration file: 795 796 Arguments: 797 section - Name of relevant section within configuration file 798 item - Item for which value is to be changed 799 value - Value to be assigned 800 801 Function needs to be called after configuration file has been parsed. 802 803 Return value: None""" 804 805 if bool( section ) and bool( item ): 806 try: 807 config = getConfig( section ) 808 if config.getEffectiveOptions().has_key( item ): 809 config.setSessionValue( item, value ) 810 except: 811 pass 812 813 return None
814 # KH 050725: End of addition 815 816
817 -def expandConfigPath(path,top):
818 """ Split the path and return a list, where all relative path components will have top prepended. 819 Example: 'A:/B/C::D/E' -> ['top/A','/B/C','top/D/E'] 820 """ 821 import os.path 822 l = [] 823 for p in path.split(':'): 824 if p: 825 if not os.path.isabs(p): 826 p = os.path.join(top,p) 827 l.append(p) 828 return l
829
830 -def sanityCheck():
831 832 logger = getLogger() 833 for c in allConfigs.values(): 834 if not c._config_made: 835 logger.error("sanity check failed: %s: no makeConfig() found in the code",c.name) 836 837 for name in allConfigFileValues: 838 opts = allConfigFileValues[name] 839 try: 840 cfg = allConfigs[name] 841 except KeyError: 842 logger.error("unknown configuration section: [%s]",name) 843 continue 844 845 if not cfg.is_open: 846 if opts: 847 logger.error("unknown options [%s]%s",name,','.join(opts.keys())) 848 else: 849 # add all options for open sections 850 for o,v in zip(opts.keys(),opts.values()): 851 cfg._addOpenOption(o,v) 852 cfg.setSessionValue(o,v)
853
854 -def getFlavour():
855 856 runtimepath = getConfig('Configuration')['RUNTIME_PATH'] 857 858 if 'GangaLHCb' in runtimepath: 859 lhcb = True 860 else: 861 lhcb = False 862 863 if 'GangaAtlas' in runtimepath: 864 atlas = True 865 else: 866 atlas = False 867 868 if lhcb and atlas: 869 raise ConfigError('Atlas and LHCb conflict') 870 871 if lhcb: 872 return 'LHCb' 873 874 if atlas: 875 return 'Atlas' 876 877 return ''
878