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