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