10
10
11
11
__RCSID__ = "$Id$"
12
12
13
+ from copy import deepcopy
13
14
import socket
14
15
15
16
from DIRAC import gConfig , gLogger , S_OK , S_ERROR
@@ -103,12 +104,14 @@ def getGridCEs(vo, bdiiInfo=None, ceBlackList=None, hostURL=None):
103
104
return result
104
105
105
106
106
- def getSiteUpdates (vo , bdiiInfo = None , log = None ):
107
+ def getSiteUpdates (vo , bdiiInfo = None , log = None , onecore = False ):
107
108
"""Get all the necessary updates for the already defined sites and CEs
108
109
109
110
:param str vo: VO name
110
111
:param dict bdiiInfo: information from DBII
111
112
:param object log: logger
113
+ :param bool onecore: whether to add single core copies of multicore queues, see the documentation about :ref:`CE`
114
+ and the :mod:`~DIRAC.ConfigurationSystem.Agent.Bdii2CSAgent` configuration for details
112
115
113
116
:result: S_OK(set)/S_ERROR()
114
117
"""
@@ -123,6 +126,24 @@ def addToChangeSet(entry, changeSet):
123
126
if new_value and new_value != value :
124
127
changeSet .add (entry )
125
128
129
+ def dropTag (tags , tagToDrop ):
130
+ """Remove tag from a comma-separated string of tags.
131
+
132
+ :param str tags: the string of current tags
133
+ :param str tagToDrop: the tag to potentially remove
134
+ :return: string of comma separated tags
135
+ """
136
+ return "," .join (sorted (set (tags .split ("," )).difference ({tagToDrop }))).strip ("," )
137
+
138
+ def addTag (tags , tagToAdd ):
139
+ """Add tag to a comma-separated string of tags.
140
+
141
+ :param str tags: the string of current tags
142
+ :param str tagToAdd: the tag to potentially add
143
+ :return: string of comma separated tags
144
+ """
145
+ return "," .join (sorted (set (tags .split ("," )).union ({tagToAdd }))).strip ("," )
146
+
126
147
if log is None :
127
148
log = gLogger
128
149
@@ -133,6 +154,35 @@ def addToChangeSet(entry, changeSet):
133
154
return result
134
155
ceBdiiDict = result ["Value" ]
135
156
157
+ if onecore :
158
+ # If enabled this creates a copy of the queue with multiple processors and sets NumberOfProcessors to 1 for ARC
159
+ # and HTCondorCE entries
160
+
161
+ def makeNewQueueName (queueName , ceType ):
162
+ """Create a new queueName for single core queues."""
163
+ if ceType == "HTCondorCE" :
164
+ return queueName + "1core"
165
+ # we should have only ARC left, we add 1core to the middle part
166
+ queueNameSplit = queueName .split ("-" , 2 )
167
+ queueNameSplit [1 ] = queueNameSplit [1 ] + "1core"
168
+ return "-" .join (queueNameSplit )
169
+
170
+ for siteName , ceDict in ceBdiiDict .items ():
171
+ for _ceName , ceInfo in ceDict ["CEs" ].items ():
172
+ newQueues = dict ()
173
+ for queueName , queueDict in ceInfo ["Queues" ].items ():
174
+ if (
175
+ queueDict ["GlueCEImplementationName" ] not in ("ARC" , "HTCondorCE" )
176
+ or int (queueDict .get ("NumberOfProcessors" , 1 )) == 1
177
+ ):
178
+ continue
179
+ newQueueName = makeNewQueueName (queueName , queueDict ["GlueCEImplementationName" ])
180
+ newQueueDict = deepcopy (queueDict )
181
+ newQueueDict ["NumberOfProcessors" ] = 1
182
+ newQueues [newQueueName ] = newQueueDict
183
+
184
+ ceInfo ["Queues" ].update (newQueues )
185
+
136
186
changeSet = set ()
137
187
for site in ceBdiiDict :
138
188
result = getDIRACSiteName (site )
@@ -266,6 +316,7 @@ def addToChangeSet(entry, changeSet):
266
316
267
317
# tags, processors, localCEType
268
318
tag = queueDict .get ("Tag" , "" )
319
+ reqTag = queueDict .get ("RequiredTag" , "" )
269
320
# LocalCEType can be empty (equivalent to "InProcess")
270
321
# or "Pool", "Singularity", but also "Pool/Singularity"
271
322
localCEType = queueDict .get ("LocalCEType" , "" )
@@ -280,12 +331,19 @@ def addToChangeSet(entry, changeSet):
280
331
# Adding queue info to the CS
281
332
addToChangeSet ((queueSection , "maxCPUTime" , maxCPUTime , newMaxCPUTime ), changeSet )
282
333
addToChangeSet ((queueSection , "SI00" , si00 , newSI00 ), changeSet )
334
+
335
+ # add RequiredTag if onecore is enabled, do this here for previously created MultiCore queues
336
+ if newNOP > 1 and onecore :
337
+ addToChangeSet (
338
+ (queueSection , "RequiredTag" , reqTag , addTag (reqTag , "MultiProcessor" )), changeSet
339
+ )
340
+
283
341
if newNOP != numberOfProcessors :
284
342
addToChangeSet ((queueSection , "NumberOfProcessors" , numberOfProcessors , newNOP ), changeSet )
285
343
if newNOP > 1 :
286
344
# if larger than one, add MultiProcessor to site tags, and LocalCEType=Pool
287
- newTag = "," . join ( sorted ( set ( tag . split ( "," )). union ({ " MultiProcessor"}))). strip ( "," )
288
- addToChangeSet (( queueSection , "Tag" , tag , newTag ), changeSet )
345
+ addToChangeSet (( queueSection , "Tag" , tag , addTag ( tag , " MultiProcessor")), changeSet )
346
+
289
347
if localCEType_inner :
290
348
newLocalCEType = "Pool/" + localCEType_inner
291
349
else :
@@ -294,8 +352,10 @@ def addToChangeSet(entry, changeSet):
294
352
else :
295
353
# if not larger than one, drop MultiProcessor Tag.
296
354
# Here we do not change the LocalCEType as Pool CE would still be perfectly valid.
297
- newTag = "," .join (sorted (set (tag .split ("," )).difference ({"MultiProcessor" }))).strip ("," )
298
- changeSet .add ((queueSection , "Tag" , tag , newTag ))
355
+ changeSet .add ((queueSection , "Tag" , tag , dropTag (tag , "MultiProcessor" )))
356
+ if onecore :
357
+ changeSet .add ((queueSection , "RequiredTag" , reqTag , dropTag (reqTag , "MultiProcessor" )))
358
+
299
359
if maxTotalJobs == "Unknown" :
300
360
newTotalJobs = min (1000 , int (int (queueInfo .get ("GlueCEInfoTotalCPUs" , 0 )) / 2 ))
301
361
newWaitingJobs = max (2 , int (newTotalJobs * 0.1 ))
0 commit comments