def getReservationACBR(cp, vog, vor): """ Given a VO group and VO role for a space reservation, return the ACBR, composed of either a FQAN or other string of form ACBR_t in GLUE 1.3. If vog does not start with '/', then it usually means that SRM saved the unix username instead of the VO name; in this case, we try to use the VoMapper object to determine the correct VO name. This will return None if the ACBR can't be determined. @param cp: Site config object @param vog: VO group string @param vor: VO role string @returns: A GLUE 1.3 complain ACBR; not necessarily a trivial one. If no VO can be determined, this MAY return None. """ if vog.startswith('/'): if vor: return 'VOMS:%s/Role=%s' % (vog, vor) else: return 'VOMS:%s' % vog else: mapper = VoMapper(cp) try: vo = mapper[vog] return 'VO:%s' % vo except: return None
def print_VOViewLocal(cp): ce_name = cp_get(cp, ce, "name", "UNKNOWN_CE") vo_map = VoMapper(cp) queue_jobs = getJobsInfo(vo_map, cp) vo_queues = getVoQueues(cp) VOView = getTemplate("GlueCE", "GlueVOViewLocalID") for vo, queue in vo_queues: ce_unique_id = buildCEUniqueID(cp, ce_name, 'sge', queue) info = { 'ceUniqueID' : ce_unique_id, 'voLocalID' : vo, 'acbr' : 'VO:%s' % vo, 'running' : queue_jobs.get(queue, {}).get(vo, {}).\ get('running', 0), 'waiting' : queue_jobs.get(queue, {}).get(vo, {}).\ get('waiting', 0), #'free_slots' : vo.get(queue, {}).get('free_slots', 0), 'free_slots' : 0, #TODO: fix 'ert' : 3600, 'wrt' : 3600, 'default_se' : getDefaultSE(cp), 'app' : cp_get(cp, "osg_dirs", "app", "/OSG_APP_UNKNOWN"), 'data' : cp_get(cp, "osg_dirs", "data", "/OSG_DATA_UNKNOWN"), } info['total'] = info['waiting'] + info['running'] printTemplate(VOView, info)
def guessVO(cp, group): """ From the group name, guess my VO name """ mapper = VoMapper(cp) bycp = determineGroupVOsFromConfig(cp, group, mapper) vos = voList(cp, vo_map=mapper) byname = sets.Set() for vo in vos: if group.find(vo) >= 0: byname.add(vo) altname = group.replace('group', '') altname = altname.replace('-', '') altname = altname.replace('_', '') altname = altname.strip() try: bymapper = mapper[altname] except: bymapper = None if bycp != None: return bycp elif bymapper: return [bymapper] elif byname: return byname else: return [altname]
def getVoQueues(cp): """ Determine the (vo, queue) tuples for this site. This allows for central configuration of which VOs are advertised. Sites will be able to blacklist queues they don't want to advertise, whitelist certain VOs for a particular queue, and blacklist VOs from queues. @param cp: Site configuration @returns: A list of (vo, queue) tuples representing the queues each VO is allowed to run in. """ voMap = VoMapper(cp) try: queue_exclude = [i.strip() for i in cp.get("pbs", "queue_exclude").\ split(',')] except: queue_exclude = [] vo_queues = [] queueInfo = getQueueInfo(cp) rvf_info = parseRvf('pbs.rvf') rvf_queue_list = rvf_info.get('queue', {}).get('Values', None) if rvf_queue_list: rvf_queue_list = rvf_queue_list.split() log.info("The RVF lists the following queues: %s." % ', '.join( \ rvf_queue_list)) for queue, qinfo in queueInfo.items(): if rvf_queue_list and queue not in rvf_queue_list: continue if queue in queue_exclude: continue volist = sets.Set(voList(cp, voMap)) try: whitelist = [i.strip() for i in cp.get("pbs", "%s_whitelist" % \ queue).split(',')] except: whitelist = [] whitelist = sets.Set(whitelist) try: blacklist = [i.strip() for i in cp.get("pbs", "%s_blacklist" % \ queue).split(',')] except: blacklist = [] blacklist = sets.Set(blacklist) if 'users' in qinfo or 'groups' in qinfo: acl_vos = parseAclInfo(queue, qinfo, voMap) volist.intersection_update(acl_vos) # Force any VO in the whitelist to show up in the volist, even if it # isn't in the acl_users / acl_groups for vo in whitelist: if vo not in volist: volist.add(vo) # Apply white and black lists for vo in volist: if (vo in blacklist or "*" in blacklist) and ((len(whitelist) == 0)\ or vo not in whitelist): continue vo_queues.append((vo, queue)) return vo_queues
def print_VOViewLocal(queue_info, cp): """ Print out the VOView objects for the LSF batch system. One VOView per VO per queue, for each VO which has access to the queue. """ ce_name = cp.get(ce, "name") vo_map = VoMapper(cp) queue_jobs = getJobsInfo(vo_map, cp) VOView = getTemplate("GlueCE", "GlueVOViewLocalID") vo_queues = getVoQueues(queue_info, cp) for vo, queue in vo_queues: vo = vo.lower() vo_info = queue_jobs.get(queue, {}) info2 = vo_info.get(vo, {}) ce_unique_id = buildCEUniqueID(cp, ce_name, 'lsf', queue) my_queue_info = queue_info.setdefault(queue, {}) if cp.has_option("lsf", "max_wall"): my_queue_info["max_wall"] = cp_getInt(cp, "lsf", "max_wall", 1440) else: if "max_wall" not in my_queue_info: my_queue_info["max_wall"] = 1440 ert, wrt = responseTimes(cp, info2.get("running", 0), info2.get("waiting", 0), max_job_time=my_queue_info.get("max_wall", 0)) free_slots = my_queue_info.get('free_slots', 0) waiting = info2.get('waiting', 0) if waiting > cp_getInt(cp, 'lsf', 'idle_slack', '10'): free_slots = 0 info = { 'ceUniqueID': ce_unique_id, 'job_slots': my_queue_info.get('job_slots', 0), 'free_slots': free_slots, 'ce_name': ce_name, 'queue': queue, 'vo': vo, 'voLocalID': vo, 'job_manager': 'lsf', 'running': info2.get('running', 0), 'max_running': info2.get('max_running', 0), 'priority': queue_info.get(queue, {}).get('priority', 0), 'waiting': waiting, 'data': cp.get("osg_dirs", "data"), 'app': cp.get("osg_dirs", "app"), 'default_se': getDefaultSE(cp), 'ert': ert, 'wrt': wrt, 'acbr': 'VO:%s' % vo } info['total'] = info['waiting'] + info['running'] printTemplate(VOView, info)
def getVoQueues(cp): voMap = VoMapper(cp) try: queue_exclude = [ i.strip() for i in cp.get("sge", "queue_exclude").split(',') ] except: queue_exclude = [] # SGE has a special "waiting" queue -- ignore it. queue_exclude.append('waiting') vo_queues = [] queue_list, q = getQueueInfo(cp) rvf_info = parseRvf('sge.rvf') rvf_queue_list = rvf_info.get('queue', {}).get('Values', None) if rvf_queue_list: rvf_queue_list = rvf_queue_list.split() log.info("The RVF lists the following queues: %s." % ', '.join( \ rvf_queue_list)) else: log.warning("Unable to load a RVF file for SGE.") for queue, qinfo in queue_list.items(): if rvf_queue_list and queue not in rvf_queue_list: continue if queue in queue_exclude: continue volist = sets.Set(voList(cp, voMap)) try: whitelist = [ i.strip() for i in cp.get("sge", "%s_whitelist" % queue).split(',') ] except: whitelist = [] whitelist = sets.Set(whitelist) try: blacklist = [ i.strip() for i in cp.get("sge", "%s_blacklist" % queue).split(',') ] except: blacklist = [] blacklist = sets.Set(blacklist) if 'user_list' in qinfo: acl_vos = parseAclInfo(queue, qinfo, voMap) if acl_vos: volist.intersection_update(acl_vos) for vo in volist: if (vo in blacklist or "*" in blacklist) and ((len(whitelist) == 0)\ or vo not in whitelist): continue vo_queues.append((vo, queue)) return vo_queues
def main(): try: cp = config() bootstrapSGE(cp) addToPath(cp_get(cp, "sge", "sge_path", ".")) vo_map = VoMapper(cp) pbsVersion = getLrmsInfo(cp) print_CE(cp) print_VOViewLocal(cp) except Exception, e: sys.stdout = sys.stderr log.error(e) raise
def print_VOViewLocal(queue_info, cp): ce_name = cp_get(cp, ce, "name", "UNKNOWN_CE") vo_map = VoMapper(cp) queue_jobs = getJobsInfo(vo_map, cp) VOView = getTemplate("GlueCE", "GlueVOViewLocalID") vo_queues = getVoQueues(cp) for vo, queue in vo_queues: vo_info = queue_jobs.get(queue, {}) info2 = vo_info.get(vo, {}) port = getPort(cp) ce_unique_id = buildCEUniqueID(cp, ce_name, 'pbs', queue) my_queue_info = queue_info.setdefault(queue, {}) max_job_time = my_queue_info.get("max_wall", 0) if cp.has_option("pbs", "max_wall"): max_job_time = cp_getInt(cp, "pbs", "max_wall", 1440) ert, wrt = responseTimes(cp, info2.get("running", 0), info2.get("wait", 0), max_job_time) free_slots = my_queue_info.get('free_slots', 0) waiting = info2.get('wait', 0) if waiting > cp_getInt(cp, 'pbs', 'idle_slack', '10'): free_slots = 0 info = { 'ceUniqueID' : ce_unique_id, 'job_slots' : my_queue_info.get('job_slots', 0), 'free_slots' : free_slots, 'ce_name' : ce_name, 'queue' : queue, 'vo' : vo, 'voLocalID' : vo, 'job_manager' : 'pbs', 'running' : info2.get('running', 0), 'max_running' : info2.get('max_running', 0), 'priority' : queue_info.get(queue, {}).get('priority', 0), 'waiting' : waiting, 'data' : cp_get(cp, "osg_dirs", "data", "UNKNOWN_DATA"), 'app' : cp_get(cp, "osg_dirs", "app", "UNKNOWN_APP"), 'default_se' : getDefaultSE(cp), 'ert' : 3600, 'wrt' : 3600, 'acbr' : 'VO:%s' % vo } info['total'] = info['waiting'] + info['running'] printTemplate(VOView, info)
def main(): try: cp = config() slurm_path = cp_get(cp, "slurm", "slurm_path", ".") addToPath(slurm_path) # adding slurm_path/bin to the path as well, since slurm/torque home # points to /usr/local and the binaries exist in /usr/local/bin addToPath(slurm_path + "/bin") vo_map = VoMapper(cp) slurmVersion = getLrmsInfo(cp) queueInfo = print_CE(cp) print_VOViewLocal(queueInfo, cp) except Exception, e: sys.stdout = sys.stderr log.exception(e) raise
def getQueueList(cp): #pylint: disable-msg=C0103 """ Returns a list of all the queue names that are supported. @param cp: Site configuration @returns: List of strings containing the queue names. """ doPath(cp) vo_map = VoMapper(cp) # Determine the group information, if there are any Condor groups try: groupInfo = getGroupInfo(vo_map, cp) except Exception, e: log.exception(e) # Default to no groups. groupInfo = {}
def getLGAllowedVOs(cp, vos, name=None): """ Return the allowed VOs for a certain linkgroup. Uses getAllowedVOs to determine any manual mappings from the config file. """ allowed = [] # See if we've manually set this information if name: try: return getAllowedVOs(cp, name, return_default=False) except: pass mapper = VoMapper(cp) for vo_policy in vo_re.finditer(vos): vo_policy = vo_policy.groups()[0] if vo_policy == '*:*': return ['VO:%s' % i for i in voListStorage(cp)] if vo_policy.startswith('/'): log.debug("VO Policy: %s" % vo_policy) info = tuple(vo_policy.split(':')) if len(info) == 2: try: allowed.append('VOMS:%s/Role=%s' % info) except: pass else: log.error("Invalid VO policy: %s" % vo_policy) else: try: vo = mapper[vo_policy.split(':')[0]] allowed.append('VO:%s' % vo) except: pass # Remove duplicates and return allowed = list(sets.Set(allowed)) # If there aren't any allowed VOs, then use the manual overrides. if not allowed: return getAllowedVOs(cp, name) return allowed
def print_VOViewLocal(cp): """ Print the GLUE VOView entity; shows the VO's view of the condor batch system. Config options used: * ce.name. The human-readable name of the ce. * condor.status. The status of condor; defaults to "Production" * osg_dirs.app. The $OSG_APP directory; defaults to "/Unknown" * osg_dirs.data. The $OSG_DATA directory; defaults to "/Unknown" * se.name. The human-readable name of the closest SE. @param cp: The GIP configuration object @type cp: ConfigParser.ConfigParser """ VOView = getTemplate("GlueCE", "GlueVOViewLocalID") ce_name = cp_get(cp, "ce", "name", "") #status = cp_get(cp, "condor", "status", "Production") #condorVersion = getLrmsInfo(cp) total_nodes, _, unclaimed = parseNodes(cp) vo_map = VoMapper(cp) jobs_info = getJobsInfo(vo_map, cp) groupInfo = getGroupInfo(vo_map, cp) # Add in the default group all_group_vos = [] total_assigned = 0 for key, val in groupInfo.items(): if key == 'default': continue all_group_vos.extend(val['vos']) total_assigned += val.get('quota', 0) all_vos = sets.Set(voList(cp)) defaultVoList = [i for i in all_vos if i not in all_group_vos] if 'default' not in groupInfo: groupInfo['default'] = {} groupInfo['default']['vos'] = defaultVoList if total_nodes > total_assigned: log.info("There are %i assigned job slots out of %i total; assigning" \ " the rest to the default group." % (total_assigned, total_nodes)) groupInfo['default']['quota'] = total_nodes - total_assigned else: log.warning("More assigned nodes (%i) than actual nodes (%i)!" % \ (total_assigned, total_nodes)) if defaultGroupIsExcluded(cp): if groupInfo.has_key('default'): del groupInfo['default'] for group in groupInfo: jinfo = jobs_info.get(group, {}) vos = sets.Set(groupInfo[group].get('vos', [group])) vos.update(jinfo.keys()) vos.intersection_update(all_vos) # Enforce invariants # VO_FREE_SLOTS <= CE_FREE_SLOTS # VO_FREE_SLOTS <= CE_ASSIGNED - VO_RUNNING # This code determines CE_ASSIGNED ginfo = groupInfo[group] if ginfo.get("quota", 0) > 0: assigned = ginfo.get("quota", 0) else: assigned = total_nodes log.debug("All VOs for %s: %s" % (group, ", ".join(vos))) ce_unique_id = buildCEUniqueID(cp, ce_name, 'condor', group) max_wall = cp_getInt(cp, "condor", "max_wall", 1440) myrunning = sum([i.get('running', 0) for i in jinfo.values()], 0) assigned = max(assigned, myrunning) for vo in vos: acbr = 'VO:%s' % vo info = jinfo.get(vo.lower(), {"running": 0, "idle": 0, "held": 0}) ert, wrt = responseTimes(cp, info["running"], info["idle"] + \ info["held"], max_job_time=max_wall*60) free = min(unclaimed, assigned - myrunning, assigned - int(info['running'])) free = int(free) waiting = int(info["idle"]) + int(info["held"]) if waiting > cp_getInt(cp, 'condor', 'idle_slack', '10'): free = 0 info = { "vo": vo, "acbr": acbr, "ceUniqueID": ce_unique_id, "voLocalID": vo, "ce_name": ce_name, "job_manager": 'condor', "queue": vo, "running": info["running"], # Held jobs are included as "waiting" since the definition is: # Number of jobs that are in a state different than running "waiting": waiting, "total": info["running"] + info["idle"] + info["held"], "free_slots": free, "job_slots": int(total_nodes), "ert": ert, "wrt": wrt, "default_se": getDefaultSE(cp), 'app': cp_get(cp, 'osg_dirs', 'app', '/Unknown'), "data": cp_get(cp, "osg_dirs", "data", "/Unknown"), } printTemplate(VOView, info)
status = cp_get(cp, "condor", "status", "Production") # Get condor version try: condorVersion = getLrmsInfo(cp) except: condorVersion = "Unknown" # Get the node information for condor try: total_nodes, claimed, unclaimed = parseNodes(cp) except Exception, e: log.exception(e) total_nodes, claimed, unclaimed = 0, 0, 0 vo_map = VoMapper(cp) # Determine the information about the current jobs in queue try: jobs_info = getJobsInfo(vo_map, cp) except Exception, e: log.exception(e) jobs_info = { 'default': dict([(vo, { 'running': 0, 'idle': 0, 'held': 0 }) for vo in voList(cp)]) }