(file) Return to localize.py CVS log (file) (dir) Up to [Development] / JSOC

   1 arta  1.1 #!/home/jsoc/bin/linux_x86_64/activepython
   2           
   3 arta  1.13 # When run with the -s flag, localize.py configures the SUMS-server component of NetDRMS.
   4            
   5 arta  1.1  import sys
   6            import getopt
   7            import re
   8 arta  1.6  import os
   9            import stat
  10 arta  1.13 import filecmp
  11 arta  1.6  import xml.etree.ElementTree as ET
  12 arta  1.1  from subprocess import check_output, CalledProcessError
  13            
  14            # Constants
  15            VERS_FILE = 'jsoc_version.h'
  16            SDP_CFG = 'configsdp.txt'
  17            NET_CFG = 'config.local'
  18            NET_CFGMAP = 'config.local.map'
  19            RET_SUCCESS = 0
  20            RET_NOTDRMS = 1
  21            
  22 arta  1.2  PREFIX = """# This file was auto-generated by localize.py. Please do not edit it directly (running
  23            # configure will run localize.py, which will then overwrite any edits manually performed).
  24            """
  25 arta  1.1  
  26 arta  1.2  C_PREFIX = """/* This file was auto-generated by localize.py. Please do not edit it directly (running
  27             * configure will run localize.py, which will then overwrite any edits manually performed). */
  28 arta  1.1  """
  29            
  30 arta  1.2  PERL_BINPATH = '#!/usr/bin/perl\n'
  31            
  32            PERL_INTIAL = """package drmsparams;
  33                
  34            use warnings;
  35            use strict;
  36            """
  37            
  38            PERL_FXNS_A = """sub new
  39 arta  1.1  {
  40                my($clname) = shift;
  41                
  42                my($self) = 
  43                {
  44                    _paramsH => undef
  45                };
  46                
  47                bless($self, $clname);
  48 arta  1.9      $self->{_paramsH} = {};
  49                $self->initialize();
  50 arta  1.1      
  51                return $self;
  52            }
  53                
  54            sub DESTROY
  55            {
  56                my($self) = shift;
  57            }
  58 arta  1.2  """
  59            
  60            PERL_FXNS_B = """sub get
  61            {
  62                my($self) = shift;
  63                my($name) = shift;
  64                my($rv);
  65 arta  1.1      
  66 arta  1.2      if (exists($self->{_paramsH}->{$name}))
  67                {
  68                    return $self->{_paramsH}->{$name};
  69                }
  70                else
  71                {
  72                    return undef;
  73                }
  74            }
  75            1;"""
  76 arta  1.1  
  77 arta  1.13 SUMRM_COMMENT = """# This is the configuration file for the sum_rm program. It was auto-generated by the DRMS master configure script.
  78            # It controls the behavior of the sum_rm program, and is loaded each time sum_rm runs. To change the
  79            # parameter values in this configuration file, modify config.local, then re-run configure. This configuration
  80            # file will be updated only if parameters affecting it are modified. If such changes are made to config.local,
  81            # please make sure that the sum_rm service is disabled while configure in running.
  82            """
  83            
  84            SUMRM_DOC = """# sum_rm removes end-of-life SUMS data files to prevent disk-partitions from becomming 100% full. 
  85            # sum_svc, the main SUMS service, starts this daemon when it is launched. Within an infinite loop, sum_rm sleeps
  86            # for SLEEP number of seconds (defined below). When it awakes, it loads the sum_rm configuration file. For each SU,
  87            # it then examines the 'effective_date' column within the sum_partn_alloc table of the SUMS database. It does so by
  88            # sorting all SUs by effective date (this date is actually an expiration date - the SU is good until the end of that day),
  89            # and then, starting with the SU with the oldest effective date, it deletes the SUs. It continues deleting SUs until one
  90            # of three conditions is met:
  91            #
  92            #   (a) The disk has at least PART_PERCENT_FREE percent free space.
  93            #   (b) All SUs have effective_date values in the future.
  94            #   (c) At least 600 SUs have been deleted (this is defined in the LIMIT statement in the file SUMLIB_RmDoX.pgc).
  95            #
  96            # After sum_rm stops deleteing SUs, it then sleeps for SLEEP seconds, completing the first iteration of the
  97            # infinite loop.
  98 arta  1.13 """
  99            
 100            SUMRM_PARTN_PERCENT_FREE = """
 101            # This is the percentage at which all disk partitions are to be kept free.
 102            # If not specified, this defaults to 3. For example, setting PART_PERCENT_FREE = 5 will allow all partitions to
 103            # fill to 95% full. Dividing the number of unused blocks by the total number of blocks, and rounding up,
 104            # will result in the number specified by PART_PERCENT_FREE.
 105            #
 106            # NOTE : This behavior was previously controlled by the MAX_FREE_{n} family of parameters. {n} referred to the
 107            # disk-partition number and the value of parameter MAX_FREE_{n} was the MINIMUM number of free MB in the
 108            # partition [No clue why the word MAX was used]. As of NetDRMS 7.0, MAX_FREE_{n} has no effect."""
 109            
 110            SUMRM_SLEEP = """
 111            # The value is the number of seconds to sleep between iterations of the main loop in sum_rm."""
 112            
 113            SUMRM_LOG = """
 114            # The value is the log file (opened only at sum_rm startup; the sum_rm pid is appended to this file name)."""
 115            
 116            SUMRM_MAIL = """
 117            # The value is the email address of the recipient to be notified in case of a problem."""
 118            
 119 arta  1.13 SUMRM_NOOP = """
 120            # If the value is set to anything other than 0, then sum_rm is rendered inactive. Otherwise, sum_rm is active."""
 121            
 122            SUMRM_USER = """
 123            # The value designates the linux user who is allowed to run sum_rm."""
 124            
 125            SUMRM_NORUN = """
 126            # This pair of paramters defines a window of time, during which sum_rm will become torpid - in this
 127            # window, sum_rm will not scan for SUs to delete, not will it delete any SUs. Each value is an integer, 0-23, that
 128            # represents an hour of the day. For example, if NORUN_START=8 and NORUN_STOP=10, then between 8am and 10am
 129            # local time, sum_rm will be dormant. To disable this behavior, set both parameters to the same value."""
 130 arta  1.6  
 131            RULESPREFIX = """# Standard things
 132            sp 		:= $(sp).x
 133            dirstack_$(sp)	:= $(d)
 134            d		:= $(dir)
 135            """
 136            
 137            RULESSUFFIX = """dir	:= $(d)/example
 138            -include		$(SRCDIR)/$(dir)/Rules.mk
 139            dir	:= $(d)/cookbook
 140            -include		$(SRCDIR)/$(dir)/Rules.mk
 141            dir	:= $(d)/myproj
 142            -include		$(SRCDIR)/$(dir)/Rules.mk
 143            
 144            # Standard things
 145            d		:= $(dirstack_$(sp))
 146            sp		:= $(basename $(sp))
 147            """
 148            
 149            TARGETPREFIX = """$(PROJOBJDIR):\n\t+@[ -d $@ ] || mkdir -p $@"""
 150            
 151 arta  1.3  ICC_MAJOR = 9
 152            ICC_MINOR = 0
 153            GCC_MAJOR = 3
 154            GCC_MINOR = 0
 155            IFORT_MAJOR = 9
 156            IFORT_MINOR = 0
 157            GFORT_MAJOR = 4
 158            GFORT_MINOR = 2
 159            
 160            
 161 arta  1.1  # Read arguments
 162            #  d - localization directory
 163            #  b - base name of all parameter files (e.g., -b drmsparams --> drmsparams.h, drmsparams.mk, drmsparams.pm, etc.)
 164 arta  1.13 #  s - configure a NetDRMS server (i.e., SUMS server). Otherwise, do client configuration only. A server
 165            #      configuration will modify something that only the production user has access to. An example is the sum_rm.cfg
 166            #      file. To modify that file, the user running configure must be running configure on the SUMS-server host, and
 167            #      must have write permission on sum_rm.cfg.
 168 arta  1.1  def GetArgs(args):
 169                rv = bool(0)
 170                optD = {}
 171                
 172                try:
 173 arta  1.13         opts, remainder = getopt.getopt(args, "hd:b:s",["dir=", "base="])
 174 arta  1.1      except getopt.GetoptError:
 175                    print('Usage:')
 176                    print('localize.py [-h] -d <localization directory> -b <parameter file base>')
 177                    rv = bool(1)
 178                
 179                if rv == bool(0):
 180                    for opt, arg in opts:
 181                        if opt == '-h':
 182                            print('localize.py [-h] -d <localization directory> -b <parameter file base>')
 183                        elif opt in ("-d", "--dir"):
 184                            regexp = re.compile(r"(\S+)/?")
 185                            matchobj = regexp.match(arg)
 186                            if matchobj is None:
 187                                rv = bool(1)
 188                            else:
 189                                optD['dir'] = matchobj.group(1)
 190                        elif opt in ("-b", "--base"):
 191                            optD['base'] = arg
 192 arta  1.13             elif opt in ("-s"):
 193                            optD['server'] = ""
 194 arta  1.1              else:
 195                            optD[opt] = arg
 196            	
 197                return optD
 198            
 199            def createMacroStr(key, val, keyColLen, status):
 200                if keyColLen < len(key):
 201                    status = bool(1)
 202                    return None
 203                else:
 204                    nsp = keyColLen - len(key)
 205                    spaces = str()
 206                    for isp in range(nsp):
 207                        spaces += ' '
 208                    status = bool(0)
 209                    return '#define ' + key + spaces + val + '\n'
 210            
 211            def createPerlConst(key, val, keyColLen, status):
 212                if keyColLen < len(key):
 213                    status = bool(1)
 214                    return None
 215 arta  1.1      else:
 216                    nsp = keyColLen - len(key)
 217                    spaces = str()
 218                    for isp in range(nsp):
 219                        spaces += ' '
 220                    status = bool(0)
 221                    return 'use constant ' + key + ' => ' + spaces + val + ';\n'
 222            
 223 arta  1.3  def isSupportedPlat(plat):
 224                regexp = re.compile(r"\s*(^x86_64|^ia32|^ia64|^avx)", re.IGNORECASE)
 225                matchobj = regexp.match(plat);
 226                    
 227                if not matchobj is None:
 228                    return bool(1);
 229                else:
 230                    return bool(0);
 231            
 232 arta  1.6  def processMakeParam(mDefs, key, val, platDict, machDict):
 233 arta  1.3      varMach = None
 234                regexp = re.compile(r"(\S+):(\S+)")
 235                matchobj = regexp.match(key)
 236                if not matchobj is None:
 237                    varName = matchobj.group(1)
 238                    varMach = matchobj.group(2)
 239                else:
 240                    varName = key
 241                
 242                varValu = val
 243                    
 244                if varMach is None:
 245                    mDefs.extend(list('\n' + varName + ' = ' + varValu))
 246                else:
 247                    if isSupportedPlat(varMach):
 248                        # The guard will compare varValu to $JSOC_MACHINE.
 249                        if not varMach in platDict:
 250                            platDict[varMach] = {}
 251                        platDict[varMach][varName] = varValu
 252                    else:
 253                        # The guard will compare varValu to $MACHINETYPE (this is just the hostname of the machine on which localize.py is running).
 254 arta  1.3              if not varMach in machDict:
 255                            machDict[varMach] = {}
 256                        machDict[varMach][varName] = varValu
 257            
 258 arta  1.6  def processParam(cfgfile, line, regexpQuote, regexp, keymap, defs, cDefs, mDefsGen, mDefsMake, perlConstSection, perlInitSection, platDict, machDict, section):
 259 arta  1.1      status = 0
 260                        
 261                if ''.join(section) == 'defs' or not cfgfile:
 262                    matchobj = regexp.match(line)
 263                    if not matchobj is None:
 264                        # We have a key-value line
 265                        keyCfgSp = matchobj.group(1)
 266                        val = matchobj.group(2)
 267                        
 268                        # Must map the indirect name to the actual name
 269                        if keymap:
 270                            # Map to actual name only if the keymap is not empty (which signifies NA).
 271                            if keyCfgSp in keymap:
 272                                key = keymap[keyCfgSp]
 273                            elif keyCfgSp == 'LOCAL_CONFIG_SET' or keyCfgSp == 'DRMS_SAMPLE_NAMESPACE':
 274 arta  1.6                      # Ignore parameters that are not useful and shouldn't have been there in the first place. But
 275                                # they have been released to the world, so we have to account for them.
 276 arta  1.1                      return bool(0)
 277                            elif not cfgfile:
 278                                # Should not be doing mapping for addenda
 279                                key = keyCfgSp
 280                            else:
 281                                raise Exception('badKeyMapKey', keyCfgSp)
 282                        else:
 283                            key = keyCfgSp
 284                        
 285                        matchobj = regexpQuote.match(key)
 286                        if not matchobj is None:
 287                            quote = matchobj.group(1)
 288                            key = matchobj.group(2)
 289            
 290                            # master defs dictionary
 291                            defs[key] = val
 292                            
 293                            # C header file
 294                            if quote == "q":
 295                                # Add double-quotes
 296                                cDefs.extend(list(createMacroStr(key, '"' + val + '"', 40, status)))
 297 arta  1.1                  elif quote == "p":
 298                                # Add parentheses
 299                                cDefs.extend(list(createMacroStr(key, '(' + val + ')', 40, status)))
 300                            elif quote == "a":
 301                                # Leave as-is
 302                                cDefs.extend(list(createMacroStr(key, val, 40, status)))
 303                            else:
 304                                # Unknown quote type
 305                                raise Exception('badQuoteQual', key)
 306                            
 307                            if status:
 308                                raise Exception('paramNameTooLong', key)
 309                            
 310                            # Make file - val should never be quoted; just use as is
 311 arta  1.4                  mDefsGen.extend(list('\n' + key + ' = ' + val))
 312 arta  1.1                  
 313                            # Perl file - val should ALWAYS be single-quote quoted
 314                            # Save const info to a string
 315                            perlConstSection.extend(list(createPerlConst(key, "'" + val + "'", 40, status)))
 316                            
 317                            if status:
 318                                raise Exception('paramNameTooLong', key)
 319                            
 320                            # Save initialization information as a string. Now that we've defined
 321                            # constants (the names of which are the parameter names) 
 322                            # we can refer to those in the init section. The key variable holds the
 323                            # name of the constant.
 324 arta  1.9                  perlInitSection.extend(list("\n  $self->{_paramsH}->{'" + key + "'} = " + key + ';'))
 325 arta  1.1              else:
 326                            # No quote qualifier
 327                            raise Exception('missingQuoteQual', key)
 328 arta  1.3      elif ''.join(section) == 'make' and cfgfile:
 329                    # Configure the remaining make variables defined in the __MAKE__ section of the configuration file. Third-party
 330                    # library make variables are specified in the __MAKE__ section.
 331                    matchobj = regexp.match(line)
 332                    if not matchobj is None:
 333                        # We have a key-value line
 334                        key = matchobj.group(1)
 335                        val = matchobj.group(2)
 336            
 337                        # This information is for making make variables only. We do not need to worry about quoting any values
 338                        defs[key] = val
 339 arta  1.4              processMakeParam(mDefsMake, key, val, platDict, machDict)
 340 arta  1.1      
 341                return bool(0)
 342            
 343            # We have some extraneous line or a newline - ignore.
 344            
 345 arta  1.6  def processXML(xml, projRules, projTarget):
 346                rv = bool(0)
 347                
 348                # <projects>
 349                root = ET.fromstring(xml)
 350                
 351                # Iterate through each proj child.
 352                for proj in root.iter('proj'):
 353                    # Rules.mk
 354                    nameElem = proj.find('name')
 355                    rulesStr = 'dir     := $(d)/' + nameElem.text + '\n-include          $(SRCDIR)/$(dir)/Rules.mk\n'
 356                    
 357                    # make doesn't support logical operations in ifeq conditionals (you can't do ifeq (A AND B)), 
 358                    # so we need to write:
 359                    #   ifeq (A)
 360                    #      ifeq (B)
 361                    #        <do something>
 362                    #      endif
 363                    #   endif
 364                        
 365                    rulesPref = '';
 366 arta  1.6          rulesSuff = '';
 367                
 368                    filters = proj.find('filters')
 369                    if filters is not None:
 370                        for filter in filters.findall('filter'):
 371                            rulesPref += 'ifeq ($(' + filter.find('name').text + '),' + filter.find('value').text + ')\n'
 372                            rulesSuff += 'endif\n'
 373                        
 374                    if len(rulesPref) > 0 and len(rulesSuff) > 0:
 375                        projRules.extend(list(rulesPref))
 376                        projRules.extend(list(rulesStr))
 377                        projRules.extend(list(rulesSuff))
 378                    else:
 379                        projRules.extend(list(rulesStr))
 380                    
 381                    # target.mk
 382                    subdirs = proj.find('subdirs')
 383                    if subdirs is not None:
 384                        for subdir in subdirs.findall('subdir'):
 385                            targetStr = '\n\t+@[ -d $@/' + nameElem.text + '/' + subdir.text + ' ] || mkdir -p $@/' + nameElem.text + '/' + subdir.text
 386                            projTarget.extend(list(targetStr))
 387 arta  1.6  
 388                return rv
 389            
 390            def determineSection(line, regexpDefs, regexpMake, regexpProjMkRules, regexpProj, regexpProjCfg):
 391                matchobj = regexpDefs.match(line)
 392                if not matchobj is None:
 393                    return 'defs'
 394                    
 395                matchobj = regexpMake.match(line)
 396                if not matchobj is None:
 397                    return 'make'
 398                    
 399                matchobj = regexpProjMkRules.match(line)
 400                if not matchobj is None:
 401                    return 'projmkrules'
 402                    
 403                matchobj = regexpProj.match(line)
 404                if not matchobj is None:
 405                    return 'proj'
 406                    
 407                matchobj = regexpProjCfg.match(line)
 408 arta  1.6      if not matchobj is None:
 409                    return 'projcfg'
 410            
 411                return None
 412            
 413 arta  1.1  # defs is a dictionary containing all parameters (should they be needed in this script)
 414 arta  1.6  # projCfg is the list containing the configure script content.
 415            # projMkRules is the list containing the make_basic.mk content.
 416            # projRules is the list containing the Rules.mk content.
 417            # projTargert is the list containing the target.mk content.
 418            def parseConfig(fin, keymap, addenda, defs, cDefs, mDefsGen, mDefsMake, projCfg, projMkRules, projRules, projTarget, perlConstSection, perlInitSection):
 419 arta  1.1      rv = bool(0)
 420                
 421                # Open required config file (config.local)
 422                try:
 423                    # Examine each line, looking for key=value pairs.
 424                    regexpDefs = re.compile(r"^__DEFS__")
 425                    regexpMake = re.compile(r"^__MAKE__")
 426 arta  1.6          regexpProjMkRules = re.compile(r"__PROJ_MK_RULES__")
 427                    regexpProj = re.compile(r"^__PROJ__")
 428                    regexpProjCfg = re.compile(r"^__PROJCFG__")
 429 arta  1.1          regexpComm = re.compile(r"^\s*#")
 430 arta  1.6          regexpSp = re.compile(r"^s*$")
 431 arta  1.1          regexpQuote = re.compile(r"^\s*(\w):(.+)")
 432 arta  1.6          regexpCustMkBeg = re.compile(r"^_CUST_")
 433                    regexpCustMkEnd = re.compile(r"^_ENDCUST_")
 434                    regexpDiv = re.compile(r"^__")
 435 arta  1.11         regexp = re.compile(r"^\s*(\S+)\s+(\S.*)")
 436 arta  1.1          
 437 arta  1.3          platDict = {}
 438                    machDict = {}
 439 arta  1.6          
 440                    xml = None
 441 arta  1.1          
 442                    # Process the parameters in the configuration file
 443                    if not fin is None:
 444                        for line in fin:
 445 arta  1.6                  matchobj = regexpComm.match(line)
 446                            if not matchobj is None:
 447                                # Skip comment line
 448                                continue
 449                            
 450                            matchobj = regexpSp.match(line)
 451                            if not matchobj is None:
 452                                # Skip whitespace line
 453                                continue
 454 arta  1.1              
 455 arta  1.6                  newSection = determineSection(line, regexpDefs, regexpMake, regexpProjMkRules, regexpProj, regexpProjCfg)
 456                            if not newSection is None:
 457                                section = newSection
 458                
 459                            if section == 'make':
 460 arta  1.10 
 461 arta  1.6                      # There are some blocks of lines in the __MAKE__ section that must be copied ver batim to the output make file. 
 462                                # The blocks are defined by _CUST_/_ENDCUST_ tags.
 463                                matchobj = regexpCustMkBeg.match(line)
 464                                    
 465                                if not matchobj is None:
 466                                    mDefsMake.extend(list('\n'))
 467                                    for line in fin:
 468                                        matchobj = regexpCustMkEnd.match(line)
 469                                        if not matchobj is None:
 470                                            break;
 471                                        mDefsMake.extend(list(line))
 472                                    newSection = determineSection(line, regexpDefs, regexpMake, regexpProjMkRules, regexpProj, regexpProjCfg)
 473                                    if not newSection is None:
 474                                        section = newSection
 475                                    continue
 476                                # Intentional fall through to next if statement
 477                            if section == 'defs' or section == 'make':
 478                                iscfg = bool(1)
 479                                ppRet = processParam(iscfg, line, regexpQuote, regexp, keymap, defs, cDefs, mDefsGen, mDefsMake, perlConstSection, perlInitSection, platDict, machDict, section)
 480 arta  1.10                     
 481 arta  1.6                      if ppRet:
 482 arta  1.10                         break
 483 arta  1.6                  elif section == 'projcfg':
 484                                # Copy the line ver batim to the projCfg list (configure)
 485                                for line in fin:
 486                                    matchobj = regexpDiv.match(line)
 487                                    if not matchobj is None:
 488                                        break;
 489                                    projCfg.extend(list(line))
 490                                newSection = determineSection(line, regexpDefs, regexpMake, regexpProjMkRules, regexpProj, regexpProjCfg)
 491                                if not newSection is None:
 492                                    section = newSection
 493                                continue
 494                            elif section == 'projmkrules':
 495                                # Copy the line ver batim to the projMkRules list (make_basic.mk)
 496                                for line in fin:
 497                                    matchobj = regexpDiv.match(line)
 498                                    if not matchobj is None:
 499                                        break;
 500                                    projMkRules.extend(list(line))
 501                                newSection = determineSection(line, regexpDefs, regexpMake, regexpProjMkRules, regexpProj, regexpProjCfg)
 502                                if not newSection is None:
 503                                    section = newSection
 504 arta  1.6                      continue
 505                            elif section == 'proj':
 506                                # Must parse xml and use the project-specific information to populate the Rules.mk and target.mk files.
 507                                # Collect all xml lines for now, then process after file-read loop.
 508                                if xml is None:
 509                                    xml = line
 510                                else:
 511                                    xml += line
 512                            else:
 513 arta  1.10                     # Unknown section
 514 arta  1.6                      raise Exception('unknownSection', section)
 515 arta  1.1      except Exception as exc:
 516 arta  1.6          msg = exc.args[0]
 517 arta  1.1          if msg == 'badKeyMapKey':
 518                        # If we are here, then there was a non-empty keymap, and the parameter came from
 519                        # the configuration file.
 520 arta  1.6              violator = exc.args[1]
 521 arta  1.1              print('Unknown parameter name ' + "'" + violator + "'" + ' in ' + cfgfile + '.', file=sys.stderr)
 522                        rv = bool(1)
 523                    elif msg == 'badQuoteQual':
 524                        # The bad quote qualifier came from the configuration file, not the addenda, since
 525                        # we will have fixed any bad qualifiers in the addenda (which is populated by code).
 526 arta  1.6              violator = exc.args[1]
 527 arta  1.1              print('Unknown quote qualifier ' + "'" + violator + "'" + ' in ' + cfgfile + '.', file=sys.stderr)
 528                        rv = bool(1)
 529                    elif msg == 'missingQuoteQual':
 530 arta  1.6              violator = exc.args[1]
 531 arta  1.1              print('Missing quote qualifier for parameter ' + "'" + violator + "'" + ' in ' + cfgfile + '.', file=sys.stderr)
 532                        rv = bool(1)
 533                    elif msg == 'paramNameTooLong':
 534 arta  1.6              violator = exc.args[1]
 535 arta  1.1              print('Macro name ' + "'" + violator + "' is too long.", file=sys.stderr)
 536                        rv = bool(1)
 537 arta  1.6          elif msg == 'unknownSection':
 538                        violator = exc.args[1]
 539                        print('Unknown section ' + "'" + violator + "' in configuration file.", file=sys.stderr)
 540                        rv = bool(1)
 541 arta  1.1          else:
 542                        # re-raise the exception
 543                        raise
 544            
 545 arta  1.6      if not rv:
 546                    if not xml is None:
 547                        # Process xml.
 548                        projRules.extend(list(RULESPREFIX))
 549                        projTarget.extend(list(TARGETPREFIX))            
 550                        rv = processXML(xml, projRules, projTarget)
 551                        projRules.extend(RULESSUFFIX)
 552            
 553                # Process addenda - these are parameters that are not configurable and must be set in the 
 554                # NetDRMS build.
 555                if not rv:
 556                    iscfg = bool(0)
 557                    for key in addenda:
 558                        item = key + ' ' + addenda[key]
 559                        ppRet = processParam(iscfg, item, regexpQuote, regexp, keymap, defs, cDefs, mDefsGen, mDefsMake, perlConstSection, perlInitSection, platDict, machDict, 'defs')
 560                        if ppRet:
 561                            break;
 562            
 563 arta  1.4      # Put information collected in platDict and machDict into mDefs. Must do this here, and not in processParam, since
 564                # we need to parse all platform-specific make variables before grouping them into platform categories.
 565 arta  1.3      if not rv:
 566                    for plat in platDict:
 567 arta  1.4              mDefsMake.extend(list('\nifeq ($(JSOC_MACHINE), linux_' + plat.lower() + ')'))
 568 arta  1.3              for var in platDict[plat]:
 569 arta  1.4                  mDefsMake.extend(list('\n' + var + ' = ' + platDict[plat][var]))
 570                        mDefsMake.extend(list('\nendif\n'))
 571 arta  1.3                               
 572                if not rv:
 573                    for mach in machDict:
 574 arta  1.4              mDefsMake.extend(list('\nifeq ($(MACHTYPE), ' + mach + ')'))
 575 arta  1.7              for var in machDict[mach]:
 576                            mDefsMake.extend(list('\n' + var + ' = ' + machDict[mach][var]))
 577 arta  1.4              mDefsMake.extend(list('\nendif\n'))
 578 arta  1.1      return rv
 579            
 580            def getMgrUIDLine(defs, uidParam):
 581                rv = bool(0)
 582                
 583                cmd = 'id -u ' + defs['SUMS_MANAGER']
 584                try:
 585                    ret = check_output(cmd, shell=True)
 586                    uidParam['q:SUMS_MANAGER_UID'] = ret.decode("utf-8")
 587                except ValueError:
 588                    print('Unable to run cmd: ' + cmd + '.')
 589                    rv = bool(1)
 590                except CalledProcessError:
 591                    print('Command ' + "'" + cmd + "'" + ' ran improperly.')
 592                    rv = bool(1)
 593            
 594                return rv
 595            
 596 arta  1.3  def isVersion(maj, min, majDef, minDef):
 597                res = 0
 598                
 599                if maj > majDef or (maj == majDef and min >= minDef):
 600                    res = 1
 601                
 602                return res
 603            
 604            def configureComps(defs, mDefs):
 605                rv = bool(0)
 606 arta  1.6      autoConfig = bool(1)
 607            
 608                if 'AUTOSELCOMP' in defs:
 609                    autoConfig = (not defs['AUTOSELCOMP'] == '0')
 610 arta  1.3      
 611                if autoConfig:
 612                    hasicc = bool(0)
 613                    hasgcc = bool(0)
 614                    hasifort = bool(0)
 615                    hasgfort = bool(0)
 616                    
 617                    # Try icc.
 618 arta  1.12         cmd = 'icc --version 2>&1'
 619 arta  1.3          try:
 620                        ret = check_output(cmd, shell=True)
 621                        ret = ret.decode("utf-8")
 622                    except CalledProcessError:
 623                        print('Command ' + "'" + cmd + "'" + ' ran improperly.')
 624                        rv = bool(1)
 625                    
 626 arta  1.6          if not rv:
 627 arta  1.12             regexp = re.compile(r"\s*\S+\s+\S+\s+(\d+)[.](\d+)", re.DOTALL)
 628 arta  1.3              matchobj = regexp.match(ret)
 629                        if matchobj is None:
 630                            raise Exception('unexpectedIccRet', ret)
 631                        else:
 632                            major = matchobj.group(1)
 633                            minor = matchobj.group(2)
 634                            if isVersion(int(major), int(minor), ICC_MAJOR, ICC_MINOR):
 635                                hasicc = bool(1)
 636                        
 637                    # Try gcc.
 638                    if not hasicc:
 639                        cmd = 'gcc -v 2>&1'
 640                        try:
 641                            ret = check_output(cmd, shell=True)
 642                            ret = ret.decode("utf-8")
 643                        except CalledProcessError:
 644                            print('Command ' + "'" + cmd + "'" + ' ran improperly.')
 645                            rv = bool(1)
 646            
 647                        if rv == bool(0):
 648                            regexp = re.compile(r".+gcc\s+version\s+(\d+)\.(\d+)", re.DOTALL)
 649 arta  1.3                  matchobj = regexp.match(ret)
 650                            if matchobj is None:
 651                                raise Exception('unexpectedGccRet', ret)
 652                            else:
 653                                major = matchobj.group(1)
 654                                minor = matchobj.group(2)
 655                                if isVersion(int(major), int(minor), GCC_MAJOR, GCC_MINOR):
 656                                    hasgcc = bool(1)
 657            
 658                    # Try ifort.
 659 arta  1.12         cmd = 'ifort --version 2>&1'
 660 arta  1.3          try:
 661                        ret = check_output(cmd, shell=True)
 662                        ret = ret.decode("utf-8")
 663                    except CalledProcessError:
 664                        print('Command ' + "'" + cmd + "'" + ' ran improperly.')
 665                        rv = bool(1)
 666            
 667 arta  1.6          if not rv:
 668 arta  1.12             regexp = re.compile(r"\s*\S+\s+\S+\s+(\d+)\.(\d+)", re.DOTALL)
 669 arta  1.3              matchobj = regexp.match(ret)
 670                        if matchobj is None:
 671                            raise Exception('unexpectedIfortRet', ret)
 672                        else:
 673                            major = matchobj.group(1)
 674                            minor = matchobj.group(2)
 675                            if isVersion(int(major), int(minor), IFORT_MAJOR, IFORT_MINOR):
 676                                hasifort = bool(1)
 677                    
 678                    # Try gfortran
 679                    if not hasifort:
 680                        cmd = 'gfortran -v 2>&1'
 681                        try:
 682                            ret = check_output(cmd, shell=True)
 683                            ret = ret.decode("utf-8")
 684                        except CalledProcessError:
 685                            print('Command ' + "'" + cmd + "'" + ' ran improperly.')
 686                            rv = bool(1)
 687            
 688                        if rv == bool(0):
 689                            regexp = re.compile(r".+gcc\s+version\s+(\d+)\.(\d+)", re.DOTALL)
 690 arta  1.3                  matchobj = regexp.match(ret)
 691                            if matchobj is None:
 692                                raise Exception('unexpectedGfortranRet', ret)
 693                            else:
 694                                major = matchobj.group(1)
 695                                minor = matchobj.group(2)
 696                                if isVersion(int(major), int(minor), GFORT_MAJOR, GFORT_MINOR):
 697                                    hasgfort = bool(1)
 698                    
 699                    # Append the compiler make variables to the make file 
 700                    if not hasicc and not hasgcc:
 701                        print('Fatal error: Acceptable C compiler not found! You will be unable to build the DRMS library.', file=sys.stderr)
 702                        rv = bool(1)
 703                    elif hasicc:
 704                        mDefs.extend(list('\nCOMPILER = icc'))
 705                    else:
 706                        mDefs.extend(list('\nCOMPILER = gcc'))
 707            
 708                    if not hasifort and not hasgfort:
 709                        print('Warning: Acceptable Fortran compiler not found! Fortran interface will not be built, and you will be unable to build Fortran modules.', file=sys.stderr)
 710                    elif hasifort:
 711 arta  1.3              mDefs.extend(list('\nFCOMPILER = ifort'))
 712                    else:
 713                        mDefs.extend(list('\nFCOMPILER = gfortran'))
 714                
 715                    # Environment overrides. These get written, regardless of the disposition of auto-configuration.
 716 arta  1.9          mDefs.extend(list('\nifneq ($(JSOC_COMPILER),)\n  COMPILER = $(JSOC_COMPILER)\nendif'))
 717                    mDefs.extend(list('\nifneq ($(JSOC_FCOMPILER),)\n  FCOMPILER = $(JSOC_FCOMPILER)\nendif'))
 718 arta  1.3  
 719                return rv
 720            
 721 arta  1.6  def writeParamsFiles(base, cfile, mfile, pfile, cDefs, mDefsGen, mDefsMake, mDefsComps, perlConstSection, perlInitSection):
 722 arta  1.1      rv = bool(0)
 723 arta  1.4  
 724                # Merge mDefsGen, mDefsMake, and mDefsComps into a single string with compiler configuration first, general parameters next, then
 725                # make-specific make variables (e.g., third-party library information) last.
 726                mDefs = '\n# Compiler Selection\n' + ''.join(mDefsComps) + '\n\n# General Parameters\n' + ''.join(mDefsGen) + '\n\n# Parameters to Configure make\n' + ''.join(mDefsMake)
 727 arta  1.1      
 728                try:
 729                    with open(cfile, 'w') as cout, open(mfile, 'w') as mout, open(pfile, 'w') as pout:
 730                        # C file of macros
 731 arta  1.2              print(C_PREFIX, file=cout)
 732                        print('/* This file contains a set of preprocessor macros - one for each configuration parameter. */\n', file=cout)
 733 arta  1.1              buf = '__' + base.upper() + '_H'
 734                        print('#ifndef ' + buf, file=cout)
 735                        print('#define ' + buf, file=cout)
 736                        print(''.join(cDefs), file=cout)
 737                        print('#endif', file=cout)
 738                        
 739                        # Make file of make variables
 740 arta  1.2              print(PREFIX, file=mout)
 741 arta  1.4              print('# This file contains a set of make-variable values. The first section contains compiler-selection variables, the second contains general configuration variables, and the third section contains variables that configure how make is run.', file=mout)
 742                        print(mDefs, file=mout)
 743 arta  1.1              
 744 arta  1.2              # Perl module
 745                        print(PERL_BINPATH, file=pout)
 746                        print(PREFIX, file=pout)
 747                        print('# This file contains a set of constants - one for each configuration parameter.\n', file=pout)
 748                        print(PERL_INTIAL, file=pout)
 749 arta  1.1              print(''.join(perlConstSection), file=pout)
 750 arta  1.2              print(PERL_FXNS_A, file=pout)
 751 arta  1.1              print('sub initialize', file=pout)
 752                        print('{', file=pout)
 753 arta  1.2              print('  my($self) = shift;', file=pout, end='')
 754 arta  1.1              print('', file=pout)
 755                        print(''.join(perlInitSection), file=pout)
 756 arta  1.2              print('}\n', file=pout)
 757                        print(PERL_FXNS_B, file=pout)
 758 arta  1.1      except IOError as exc:
 759 arta  1.6          type, value, traceback = sys.exc_info()
 760                    print(exc.strerror, file=sys.stderr)
 761                    print('Unable to open ' + "'" + value.filename + "'.", file=sys.stderr)        
 762                    rv = bool(1)
 763            
 764                return rv
 765            
 766            def writeProjFiles(pCfile, pMfile, pRfile, pTfile, projCfg, projMkRules, projRules, projTarget):
 767                rv = bool(0)
 768            
 769                try:
 770                    if projCfg:
 771                        with open(pCfile, 'w') as cout:
 772                            # configure
 773                            print(''.join(projCfg), file=cout)
 774                    
 775                    if projMkRules:
 776                        with open(pMfile, 'w') as mout:
 777                            # make_basic.mk
 778                            print(PREFIX, file=mout)
 779                            print(''.join(projMkRules), file=mout)
 780 arta  1.6      
 781                    if projRules:
 782                        with open(pRfile, 'w') as rout:
 783                            # Rules.mk
 784                            print(PREFIX, file=rout)
 785                            print(''.join(projRules), file=rout)
 786                    
 787                    if projTarget:
 788                        with open(pTfile, 'w') as tout:
 789                            # target.mk
 790                            print(PREFIX, file=tout)
 791 arta  1.10                 print(''.join(projTarget), file=tout)
 792 arta  1.6      except IOError as exc:
 793                    type, value, traceback = sys.exc_info()
 794                    print(exc.strerror, file=sys.stderr)
 795                    print('Unable to open ' + "'" + value.filename + "'.", file=sys.stderr)
 796 arta  1.1          rv = bool(1)
 797            
 798 arta  1.6      if not rv:
 799 arta  1.10         if os.path.exists(pCfile):
 800                        try:
 801                            os.chmod(pCfile, stat.S_IRWXU | stat.S_IRGRP | stat.S_IROTH)
 802                        except OSError as exc:
 803                            type, value, traceback = sys.exc_info()
 804                            print('Unable to chmod file ' + "'" + value.filename + "'.", file=sys.stderr)
 805                            print(exc.strerror, file=sys.stderr)
 806                            rv = bool(1)
 807 arta  1.6  
 808 arta  1.1      return rv
 809 arta  1.3  
 810 arta  1.13 def generateSumRmCfg(defs):
 811                rv = bool(0)
 812                # ACK! Remember that Rick renamed these parameters. The ones in config.local are the aliases - do not use those.
 813                # Use the ones that those map to (defined in config.local.map).
 814                cFileTmp = defs['SUMLOG_BASEDIR'] + '/' + '.sum_rm.cfg.tmp'
 815                cFile = defs['SUMLOG_BASEDIR'] + '/' + 'sum_rm.cfg'
 816            
 817                # Write a temporary file sum_rm configuration file.
 818                try:
 819                    with open(cFileTmp, 'w') as fout:
 820                        # Print comment at the top of the configuration file.
 821                        print(SUMRM_COMMENT, file=fout)
 822                        print(SUMRM_DOC, file=fout)
 823                        print(SUMRM_PARTN_PERCENT_FREE, file=fout)
 824                        if 'SUMRM_PART_PERCENT_FREE' in defs:
 825                            print('PART_PERCENT_FREE=' + defs['SUMRM_PART_PERCENT_FREE'], file=fout)
 826                        else:
 827                            print('PART_PERCENT_FREE=3', file=fout)
 828            
 829                        print(SUMRM_SLEEP, file=fout)
 830                        if 'SUMRM_SLEEP' in defs:
 831 arta  1.13                 print('SLEEP=' + defs['SUMRM_SLEEP'], file=fout)
 832                        else:
 833                            print('SLEEP=300', file=fout)
 834            
 835                        print(SUMRM_LOG, file=fout)
 836                        if 'SUMRM_LOG' in defs:
 837                            print('LOG=' + defs['SUMRM_LOG'], file=fout)
 838                        else:
 839                            print('LOG=/tmp/sum_rm.log', file=fout)
 840            
 841                        print(SUMRM_MAIL, file=fout)
 842                        # No default for mail - don't send nothing to nobody unless the operator has asked for notifications.
 843                        if 'SUMRM_MAIL' in defs:
 844                            print('MAIL=' + defs['SUMRM_MAIL'], file=fout)
 845                        else:
 846                            print('# MAIL=president@whitehouse.gov', file=fout)
 847            
 848                        print(SUMRM_NOOP, file=fout)
 849                        if 'SUMRM_NOOP' in defs:
 850                            print('NOOP=' + defs['SUMRM_NOOP'], file=fout)
 851                        else:
 852 arta  1.13                 print('NOOP=0', file=fout)
 853            
 854                        print(SUMRM_USER, file=fout)
 855                        if 'SUMRM_USER' in defs:
 856                            print('USER=' + defs['SUMRM_USER'], file=fout)
 857                        else:
 858                            print('USER=production', file=fout)
 859            
 860                        print(SUMRM_NORUN, file=fout)
 861                        # Default norun window is to have no such window. This can be accomplished by simply not providing either argument.
 862                        if 'SUMRM_NORUN_START' in defs or 'SUMRM_NORUN_STOP' in defs:
 863                            if 'SUMRM_NORUN_START' in defs:
 864                                print('NORUN_START=' + defs['SUMRM_NORUN_START'], file=fout)
 865                            else:
 866                                print('NORUN_START=0', file=fout)
 867                            if 'SUMRM_NORUN_STOP' in defs:
 868                                print('NORUN_STOP=' + defs['SUMRM_NORUN_STOP'], file=fout)
 869                            else:
 870                                print('NORUN_STOP=0', file=fout)
 871                        else:
 872                            print('# NORUN_START=0', file=fout)
 873 arta  1.13                 print('# NORUN_STOP=0', file=fout)
 874                        
 875                except OSError:
 876                    print('Unable to open sum_rm temporary configuration file ' + cFileTmp + 'for writing.', file=sys.stderr)
 877                    rv = bool(1)
 878            
 879                # If the content of the temporary file differs from the content of the existing configuration file, then overwrite
 880                # the original file. Otherwise, delete the temporary file
 881                if not rv:
 882                    try:
 883                        if filecmp.cmp(cFile, cFileTmp):
 884                            # Files identical - delete temporary file
 885                            try:
 886                                os.remove(cFileTmp)
 887                            
 888                            except OSError as exc:
 889                                print('Unable to remove temporary file ' + exc.filename + '.', file=sys.stderr)
 890                                print(exc.strerr, file=sys.stderr)
 891                        else:
 892                            # Replace original with temporary file
 893                            try:
 894 arta  1.13                     os.rename(cFileTmp, cFile)
 895            
 896                            except OSError as exc:
 897                                print('Unable to update sum_rm configuration file ' + cFile + '.', file=sys.stderr)
 898                                print(exc.strerr, file=sys.stderr)
 899                                rv = bool(1)
 900                    except OSError as exc:
 901                        # One of the files doesn't exist.
 902                        if exc.filename == cFile:
 903                            # We are ok - there might be no configuration file yet.
 904                            # Replace original with temporary file
 905                            try:
 906                                os.rename(cFileTmp, cFile)
 907            
 908                            except OSError as exc:
 909                                print('Unable to update sum_rm configuration file ' + cFile + '.', file=sys.stderr)
 910                                print(exc.strerr, file=sys.stderr)
 911                                rv = bool(1)
 912                        else:
 913                            # There is a problem with the temp file - bail.
 914                            print('Unable to update sum_rm configuration file ' + cFile + '.', file=sys.stderr)
 915 arta  1.13                 print(exc.strerr, file=sys.stderr)
 916                            rv = bool(1)
 917            
 918                return rv
 919            
 920            def configureNet(cfgfile, cfile, mfile, pfile, pCfile, pMfile, pRfile, pTfile, base, keymap, createSumRmCfg):
 921 arta  1.1      rv = bool(0)
 922                
 923                defs = {}
 924                cDefs = list()
 925 arta  1.4      mDefsGen = list()
 926                mDefsMake = list()
 927                mDefsComps = list()
 928 arta  1.6      projCfg = list()
 929                projMkRules = list()
 930                projRules = list()
 931                projTarget = list()
 932 arta  1.1      perlConstSection = list()
 933                perlInitSection = list()
 934 arta  1.2      addenda = {}
 935                
 936 arta  1.6      # There are three parameters that were not included in the original config.local parameter set, for some reason.
 937                # Due to this omission, then are not configurable, and must be set in the script.
 938 arta  1.2      addenda['a:USER'] = 'NULL'
 939                addenda['a:PASSWD'] = 'NULL'
 940                addenda['p:DSDS_SUPPORT'] = '0'
 941 arta  1.6      
 942                # This parameter is not configurable. BUILD_TYPE is used to distinguish between a NetDRMS and an JSOC-SDP build.
 943 arta  1.2      addenda['a:BUILD_TYPE'] = 'NETDRMS' # Means a non-Stanford build. This will set two additional macros used by make:
 944                                                    #   __LOCALIZED_DEFS__ and NETDRMS_BUILD. The former is to support legacy code
 945                                                    #   which incorrectly used this macro, and the latter is for future use. 
 946                                                    #   __LOCALIZED_DEFS__ is deprecated and should not be used in new code.
 947 arta  1.1  
 948                try:
 949                    with open(cfgfile, 'r') as fin:
 950 arta  1.3              # Process configuration parameters
 951 arta  1.6              rv = parseConfig(fin, keymap, addenda, defs, cDefs, mDefsGen, mDefsMake, projCfg, projMkRules, projRules, projTarget, perlConstSection, perlInitSection)
 952                        if not rv:
 953 arta  1.3                  # Must add a parameter for the SUMS_MANAGER UID (for some reason). This must be done after the
 954                            # config file is processed since an input to getMgrUIDLine() is one of the config file's
 955                            # parameter values.
 956 arta  1.1                  uidParam = {}
 957                            rv = getMgrUIDLine(defs, uidParam)
 958                            if rv == bool(0):
 959 arta  1.6                      rv = parseConfig(None, keymap, uidParam, defs, cDefs, mDefsGen, None, projCfg, projMkRules, projRules, projTarget, perlConstSection, perlInitSection)
 960 arta  1.3              # Configure the compiler-selection make variables.
 961 arta  1.6              if not rv:
 962 arta  1.4                  rv = configureComps(defs, mDefsComps)
 963 arta  1.1  
 964 arta  1.3              # Write out the parameter files.
 965 arta  1.6              if not rv:
 966                            rv = writeParamsFiles(base, cfile, mfile, pfile, cDefs, mDefsGen, mDefsMake, mDefsComps, perlConstSection, perlInitSection)
 967 arta  1.13 
 968 arta  1.6              # Write out the project-specific make files (make_basic.mk, Rules.mk, and target.mk).
 969                        if not rv:
 970                            rv = writeProjFiles(pCfile, pMfile, pRfile, pTfile, projCfg, projMkRules, projRules, projTarget)
 971 arta  1.13 
 972                        # Write out the sum_rm.cfg file.
 973                        if not rv and createSumRmCfg:
 974                            rv = generateSumRmCfg(defs)
 975 arta  1.1      except IOError as exc:
 976 arta  1.6          print(exc.strerror, file=sys.stderr)
 977                    print('Unable to read configuration file ' + cfgfile + '.', file=sys.stderr)
 978 arta  1.3      except Exception as exc:
 979                    type, msg = exc.args
 980                    if type == 'unexpectedIccRet':
 981                        print('icc -V returned this unexpected message:\n' + msg, file=sys.stderr)
 982                        rv = bool(1)
 983                    elif type == 'unexpectedGccRet':
 984                        print('gcc -v returned this unexpected message:\n' + msg, file=sys.stderr)
 985                        rv = bool(1)
 986                    elif type == 'unexpectedIfortRet':
 987                        print('ifort -V returned this unexpected message:\n' + msg, file=sys.stderr)
 988                        rv = bool(1)
 989                    elif type == 'unexpectedGfortranRet':
 990                        print('gfortran -v returned this unexpected message:\n' + msg, file=sys.stderr)
 991                        rv = bool(1)
 992                    else:
 993                        # re-raise the exception
 994                        raise
 995 arta  1.1          
 996 arta  1.2      return rv
 997 arta  1.1  
 998 arta  1.6  def configureSdp(cfgfile, cfile, mfile, pfile, pCfile, pMfile, pRfile, pTfile, base):
 999 arta  1.1      rv = bool(0)
1000                
1001                defs = {}
1002                cDefs = list()
1003 arta  1.5      mDefsGen = list()
1004                mDefsMake = list()
1005 arta  1.6      projCfg = list()
1006                projMkRules = list()
1007                projRules = list()
1008                projTarget = list()
1009 arta  1.5      mDefsComps = list()
1010 arta  1.1      perlConstSection = list()
1011                perlInitSection = list()
1012 arta  1.2      addenda = {}
1013                
1014 arta  1.6      # There are three parameters that were not included in the original config.local parameter set, for some reason.
1015                # Due to this omission, then are not configurable, and must be set in the script.
1016 arta  1.5      addenda['a:USER'] = 'NULL'
1017                addenda['a:PASSWD'] = 'NULL'
1018                addenda['p:DSDS_SUPPORT'] = '1'
1019 arta  1.6      
1020                # This parameter is not configurable. BUILD_TYPE is used to distinguish between a NetDRMS and an JSOC-SDP build.
1021 arta  1.5      addenda['a:BUILD_TYPE'] = 'JSOC_SDP' # Means a Stanford build. This will set one additional macro used by make: JSOC_SDP_BUILD.
1022 arta  1.1      
1023                try:
1024                    with open(cfgfile, 'r') as fin:
1025 arta  1.6              rv = parseConfig(fin, None, addenda, defs, cDefs, mDefsGen, mDefsMake, projCfg, projMkRules, projRules, projTarget, perlConstSection, perlInitSection)
1026                        
1027                        if not rv:
1028 arta  1.2                  # Must add a parameter for the SUMS_MANAGER UID (for some reason)
1029                            uidParam = {}
1030                            rv = getMgrUIDLine(defs, uidParam)
1031 arta  1.6                  if not rv:
1032                                rv = parseConfig(None, None, uidParam, defs, cDefs, mDefsGen, None, projCfg, projMkRules, projRules, projTarget, perlConstSection, perlInitSection)
1033            
1034 arta  1.5                  # Configure the compiler-selection make variables.
1035 arta  1.6                  if not rv:
1036 arta  1.5                      rv = configureComps(defs, mDefsComps)
1037 arta  1.3                  
1038 arta  1.6                  # Write out the parameter files.
1039                            if not rv:
1040                                rv = writeParamsFiles(base, cfile, mfile, pfile, cDefs, mDefsGen, mDefsMake, mDefsComps, perlConstSection, perlInitSection)
1041            
1042                            # Write out the project-specific make files (make_basic.mk, Rules.mk, and target.mk).
1043                            if not rv:
1044                                rv = writeProjFiles(pCfile, pMfile, pRfile, pTfile, projCfg, projMkRules, projRules, projTarget)
1045 arta  1.13 
1046                            # At Stanford, skip the creation of the sum_rm configuration file. config.local will still
1047                            # have the SUMRM parameters, but they will not be used.
1048 arta  1.1      except IOError as exc:
1049 arta  1.6          print(exc.strerror, file=sys.stderr)
1050                    print('Unable to read configuration file ' + cfgfile + '.', file=sys.stderr)
1051 arta  1.5      except Exception as exc:
1052 arta  1.6          type = exc.args[0]
1053 arta  1.5          if type == 'unexpectedIccRet':
1054 arta  1.6              msg = exc.args[1]
1055 arta  1.5              print('icc -V returned this unexpected message:\n' + msg, file=sys.stderr)
1056                        rv = bool(1)
1057                    elif type == 'unexpectedGccRet':
1058 arta  1.6              msg = exc.args[1]
1059 arta  1.5              print('gcc -v returned this unexpected message:\n' + msg, file=sys.stderr)
1060                        rv = bool(1)
1061                    elif type == 'unexpectedIfortRet':
1062 arta  1.6              msg = exc.args[1]
1063 arta  1.5              print('ifort -V returned this unexpected message:\n' + msg, file=sys.stderr)
1064                        rv = bool(1)
1065                    elif type == 'unexpectedGfortranRet':
1066 arta  1.6              msg = exc.args[1]
1067 arta  1.5              print('gfortran -v returned this unexpected message:\n' + msg, file=sys.stderr)
1068                        rv = bool(1)
1069                    else:
1070                        # re-raise the exception
1071                        raise
1072                    
1073 arta  1.2      return rv
1074            
1075 arta  1.1  # Beginning of program
1076            rv = RET_SUCCESS
1077            net = bool(1)
1078            
1079            # Parse arguments
1080            if __name__ == "__main__":
1081                optD = GetArgs(sys.argv[1:])
1082            
1083            if not(optD is None):
1084                # Ensure we are configuring a DRMS tree
1085                cdir = os.path.realpath(os.getcwd())
1086                versfile = cdir + '/base/' + VERS_FILE
1087            
1088                if not os.path.isfile(versfile):
1089                    rv = RET_NOTDRMS
1090            
1091            # Determine whether we are localizing a Stanford build, or a NetDRMS build. If configsdp.txt exists, then
1092            # it is a Stanford build, otherwise it is a NetDRMS build.
1093            if rv == RET_SUCCESS:
1094                stanfordFile = cdir + '/' + SDP_CFG
1095                if os.path.isfile(stanfordFile):
1096 arta  1.1          net = bool(0)
1097                
1098                cfile = optD['dir'] + '/' + optD['base'] + '.h'
1099                mfile = optD['dir'] + '/' + optD['base'] + '.mk'
1100                pfile = optD['dir'] + '/' + optD['base'] + '.pm'
1101 arta  1.6      pCfile = optD['dir'] + '/configure'
1102                pMfile = optD['dir'] + '/make_basic.mk'
1103                pRfile = optD['dir'] + '/Rules.mk'
1104                pTfile = optD['dir'] + '/target.mk'
1105 arta  1.1  
1106                if net:
1107                    try:
1108                        with open(NET_CFGMAP, 'r') as fin:
1109                            regexpComm = re.compile(r"^\s*#")
1110                            regexp = re.compile(r"^\s*(\S+)\s+(\w:\S+)")
1111                            # Must map from config.local namespace to DRMS namespace (e.g., the names used for the C macros)
1112                            keymap = {}
1113                            for line in fin:
1114                                matchobj = regexpComm.match(line)
1115                                if not matchobj is None:
1116                                    # Skip comment line
1117                                    continue
1118            
1119                                matchobj = regexp.match(line)
1120                                if not(matchobj is None):
1121                                    # We have a key-value line
1122                                    key = matchobj.group(1)
1123                                    val = matchobj.group(2)
1124                                    keymap[key] = val
1125                    except OSError:
1126 arta  1.1              sys.stderr.write('Unable to read configuration map-file ' + NET_CFGMAP + '.')
1127                        rv = bool(1)
1128            
1129                    # We also need to set the UID of the SUMS manager. We have the name of the
1130                    # SUMS manager (it is in the configuration file)
1131 arta  1.13         configureNet(NET_CFG, cfile, mfile, pfile, pCfile, pMfile, pRfile, pTfile, optD['base'], keymap, 'server' in optD)
1132 arta  1.1      else:
1133 arta  1.8          # A Stanford user can override the parameters in configsdp.txt by copying that file to config.local, 
1134                    # and then editing config.local. So, if config.local exists, use that.
1135                    if os.path.isfile(cdir + '/' + NET_CFG):
1136                        configureSdp(NET_CFG, cfile, mfile, pfile, pCfile, pMfile, pRfile, pTfile, optD['base'])
1137                    else:
1138                        configureSdp(SDP_CFG, cfile, mfile, pfile, pCfile, pMfile, pRfile, pTfile, optD['base'])

Karen Tian
Powered by
ViewCVS 0.9.4