fixed bug: made parseQstatOutput handle domains other than ipr.univ-rennes1.fr properly
before this fix, `parseQstatOutput` created a list of machines with a hardcoded ipr.univ-rennes1.fr domain, resulting in potentatially wrong fqdn work related to https://bugzilla.ipr.univ-rennes.fr/show_bug.cgi?id=3693
This commit is contained in:
		
							parent
							
								
									5bf1cbe664
								
							
						
					
					
						commit
						891182587d
					
				|  | @ -54,9 +54,11 @@ class QstatParser: | |||
|                 assert False, 'unhandled queue machine state flag :"' + c + '"' | ||||
|         return queueMachineState | ||||
| 
 | ||||
|     def parseQstatOutput(self, qstatOutput): | ||||
|     def parseQstatOutput(self, qstatOutput, cluster_domain: str = 'ipr.univ-rennes1.fr'): | ||||
|         """ | ||||
|         parses result of command 'qstat -f -u \* -pri' | ||||
|         parses result of command 'qstat -f -u \\* -pri' | ||||
| 
 | ||||
|         cluster_domain: network domain of the cluster (eg 'ipr.univ-rennes.fr'). This information is missing from qstat's output and is used to form the fully qualified domain name of the cluster machines. | ||||
|         """ | ||||
|         logging.debug('qstatOutput type : %s' % type(qstatOutput)) | ||||
| 
 | ||||
|  | @ -70,25 +72,25 @@ class QstatParser: | |||
|             for example, this function would return [1, 2, 3, 4, 6, 7, 8] for the input string "1-4:1,6-8:1" | ||||
|             """ | ||||
|             task_ids = [] | ||||
|             astrRanges = re.split(',', task_ranges_sequence) | ||||
|             for strRange in astrRanges: | ||||
|                 singleIndexMatch = re.match('^(?P<elementIndex>[0-9]+)$', strRange) | ||||
|                 if singleIndexMatch: | ||||
|                     iElementIndex = int(singleIndexMatch.group('elementIndex')) | ||||
|                     task_ids.extend(range(iElementIndex, iElementIndex + 1)) | ||||
|             ranges = re.split(',', task_ranges_sequence) | ||||
|             for task_range in ranges: | ||||
|                 single_index_match = re.match('^(?P<elementIndex>[0-9]+)$', task_range) | ||||
|                 if single_index_match: | ||||
|                     element_index = int(single_index_match.group('elementIndex')) | ||||
|                     task_ids.extend(range(element_index, element_index + 1)) | ||||
|                 else: | ||||
|                     # we expect strRange to be of the form "1-4:1", where : | ||||
|                     # the 1st number is the min element index (sge imposes it to be greater than 0) | ||||
|                     # the 2nd number is the max element index | ||||
|                     # the 3rd number is the step between consecutive element indices | ||||
|                     rangeMatch = re.match('^(?P<minElementIndex>[0-9]+)-(?P<maxElementIndex>[0-9]+):(?P<stepBetweenIndices>[0-9]+)$', strRange) | ||||
|                     if rangeMatch is None: | ||||
|                         logError('unexpected format for job array details : "%s" (line="%s"' % (strRange, line)) | ||||
|                     range_match = re.match('^(?P<minElementIndex>[0-9]+)-(?P<maxElementIndex>[0-9]+):(?P<stepBetweenIndices>[0-9]+)$', task_range) | ||||
|                     if range_match is None: | ||||
|                         logError('unexpected format for job array details : "%s" (line="%s"' % (task_range, line)) | ||||
|                         assert False | ||||
|                     iMinElementIndex = int(rangeMatch.group('minElementIndex')) | ||||
|                     iMaxElementIndex = int(rangeMatch.group('maxElementIndex')) | ||||
|                     iStepBetweenIndices = int(rangeMatch.group('stepBetweenIndices')) | ||||
|                     task_ids.extend(range(iMinElementIndex, iMaxElementIndex + 1, iStepBetweenIndices)) | ||||
|                     min_element_index = int(range_match.group('minElementIndex')) | ||||
|                     min_element_index = int(range_match.group('maxElementIndex')) | ||||
|                     step_between_indices = int(range_match.group('stepBetweenIndices')) | ||||
|                     task_ids.extend(range(min_element_index, min_element_index + 1, step_between_indices)) | ||||
|             return task_ids | ||||
| 
 | ||||
|         # ugly hack to work around the fact that qstat truncates the fqdn of cluster nodes | ||||
|  | @ -97,7 +99,7 @@ class QstatParser: | |||
|         # --------------------------------------------------------------------------------- | ||||
|         # main.q@physix88.ipr.univ-renne BIP   0/0/36         14.03    lx-amd64 | ||||
|         # TODO: fix this properly by parsing the output of 'qstat -f -u \* -xml' instead of 'qstat -f -u \*' | ||||
|         qstatOutput = re.sub(r'\.univ[^ ]*', '.univ-rennes1.fr', qstatOutput) | ||||
|         qstatOutput = re.sub(r'\.ipr\.univ[^ ]*', f'.{cluster_domain}', qstatOutput) | ||||
| 
 | ||||
|         jobsState = JobsState() | ||||
|         f = io.StringIO(qstatOutput) | ||||
|  | @ -209,8 +211,7 @@ class QstatParser: | |||
|                             bInPendingJobsSection = True | ||||
|                             currentQueueMachine = None | ||||
|                         else: | ||||
|                             # print line | ||||
|                             None | ||||
|                             pass | ||||
|                 else: | ||||
|                     # we are in a pending jobs section | ||||
|                     matchObj = re.match('^[#]+$', line) | ||||
|  | @ -218,7 +219,6 @@ class QstatParser: | |||
|                         # unexpected line | ||||
|                         print('line = "' + line + '"') | ||||
|                         assert False | ||||
|                     None | ||||
|             line = f.readline() | ||||
|         f.close() | ||||
|         return jobsState | ||||
|  |  | |||
|  | @ -69,7 +69,7 @@ def executeCommand(command): | |||
|     return result | ||||
| 
 | ||||
| 
 | ||||
| def executeCommandOn(target_machine_fqdn, command, user=None): | ||||
| def executeCommandOn(target_machine_fqdn: str, command: str, user: str = None): | ||||
|     """ | ||||
|     execute command on a local or remote machine (using ssh then) | ||||
|     :param str user: if not None, the user that should be used to execute the command (instead of the current user) | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ class CoclutoTestCase(unittest.TestCase): | |||
|             qstat_output = file.read() | ||||
|             # qstatParser = ClusterController.QstatParser() | ||||
|             qstatParser = QstatParser() | ||||
|             job_state = qstatParser.parseQstatOutput(qstat_output) | ||||
|             job_state = qstatParser.parseQstatOutput(qstat_output, cluster_domain='ipr.univ-rennes1.fr') | ||||
| 
 | ||||
|         self.assertIsInstance(job_state, JobsState) | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue