|
4 | 4 | import re
|
5 | 5 | import sys
|
6 | 6 | import logging
|
| 7 | +import subprocess |
| 8 | +import textwrap |
7 | 9 | from xml.sax import saxutils
|
8 | 10 |
|
9 | 11 | from osg_configure.modules import exceptions
|
|
20 | 22 |
|
21 | 23 | CE_PROBE_RPMS = ['gratia-probe-htcondor-ce']
|
22 | 24 |
|
| 25 | +CONDOR_CE_CONFIG_VAL = "/usr/bin/condor_ce_config_val" |
| 26 | + |
23 | 27 |
|
24 | 28 | def requirements_are_installed():
|
25 | 29 | return (utilities.gateway_installed() and
|
@@ -237,6 +241,8 @@ def check_attributes(self, attributes):
|
237 | 241 | self.log("GratiaConfiguration.check_attributes completed")
|
238 | 242 | return True
|
239 | 243 | status = self._check_servers()
|
| 244 | + if 'htcondor-ce' in self._probe_config: |
| 245 | + status &= self._verify_gratia_dirs_for_htcondor_ce_probe() |
240 | 246 | self.log("GratiaConfiguration.check_attributes completed")
|
241 | 247 | return status
|
242 | 248 |
|
@@ -419,6 +425,80 @@ def _configure_htcondor_ce_probe(self):
|
419 | 425 | if not utilities.atomic_write(config_location, buf):
|
420 | 426 | return False
|
421 | 427 | return True
|
| 428 | + |
| 429 | + def _verify_gratia_dirs_for_htcondor_ce_probe(self): |
| 430 | + """ |
| 431 | + Verify that the condor per_job_history directory and the DataFolder |
| 432 | + directory are the same and warn if admin if the two don't match |
| 433 | + """ |
| 434 | + |
| 435 | + if not os.path.exists(CONDOR_CE_CONFIG_VAL): |
| 436 | + raise exceptions.ConfigureError(f"{CONDOR_CE_CONFIG_VAL} missing") |
| 437 | + |
| 438 | + config_location = GRATIA_CONFIG_FILES['htcondor-ce'] |
| 439 | + contents = open(config_location, "r", encoding="latin-1").read() |
| 440 | + re_obj = re.compile(r'(?m)^\s*DataFolder\s*=(.*)\s*$') |
| 441 | + match = re_obj.search(contents) |
| 442 | + if not match: |
| 443 | + return True |
| 444 | + |
| 445 | + valid = True |
| 446 | + data_folder = match.group(1) |
| 447 | + data_folder = data_folder.strip('" \t') |
| 448 | + # Per Gratia-126 DataFolder must end in / otherwise gratia won't find certinfo files |
| 449 | + if not data_folder.endswith('/'): |
| 450 | + self.logger.error("DataFolder setting in %s must end in a /", config_location) |
| 451 | + valid = False |
| 452 | + |
| 453 | + # PER_JOB_HISTORY_DIR comes from the schedd, so if condor's not |
| 454 | + # running, we can't get a value (SOFTWARE-1564) |
| 455 | + history_dir = self._get_condor_ce_history_dir() |
| 456 | + if not history_dir: |
| 457 | + self.logger.warning(textwrap.fill( |
| 458 | + """Could not verify DataFolder correctness: unable to get PER_JOB_HISTORY_DIR |
| 459 | + from the running schedd. This may be caused by the condor-ce schedd not running |
| 460 | + or by PER_JOB_HISTORY_DIR not being defined.""" |
| 461 | + )) |
| 462 | + return valid |
| 463 | + |
| 464 | + # os.path.samefile will die if the paths don't exist so check that explicitly (SOFTWARE-1735) |
| 465 | + if not os.path.exists(data_folder): |
| 466 | + self.logger.error("DataFolder setting in %s (%s) points to a nonexistent location", |
| 467 | + config_location, data_folder) |
| 468 | + return False |
| 469 | + elif not os.path.exists(history_dir): |
| 470 | + self.logger.error("condor-ce PER_JOB_HISTORY_DIR (%s) points to a nonexistent location", history_dir) |
| 471 | + return False |
| 472 | + else: |
| 473 | + try: |
| 474 | + if not os.path.samefile(data_folder, history_dir): |
| 475 | + self.logger.error("DataFolder setting in %s (%s) and condor-ce PER_JOB_HISTORY_DIR (%s) " |
| 476 | + "do not match, these settings must match!", |
| 477 | + config_location, data_folder, history_dir) |
| 478 | + return False |
| 479 | + except OSError as e: |
| 480 | + self.logger.error( |
| 481 | + "Error comparing DataFolder setting in %s (%s) and condor PER_JOB_HISTORY_DIR %s:\n%s", |
| 482 | + config_location, data_folder, history_dir, e) |
| 483 | + return False |
| 484 | + |
| 485 | + def _get_condor_ce_history_dir(self): |
| 486 | + cmd = [CONDOR_CE_CONFIG_VAL, '-schedd', 'PER_JOB_HISTORY_DIR'] |
| 487 | + try: |
| 488 | + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="latin-1") |
| 489 | + history_dir, errtext = process.communicate() |
| 490 | + if process.returncode != 0: |
| 491 | + self.logger.info("While checking gratia parameters: %s failed. Output follows:\n%s", |
| 492 | + CONDOR_CE_CONFIG_VAL, errtext) |
| 493 | + return None |
| 494 | + except OSError as err: |
| 495 | + self.logger.info("While checking gratia parameters: Error running %s: %s", |
| 496 | + CONDOR_CE_CONFIG_VAL, err) |
| 497 | + return None |
| 498 | + history_dir = history_dir.strip() |
| 499 | + if history_dir.startswith('Not defined'): |
| 500 | + return None |
| 501 | + return history_dir |
422 | 502 |
|
423 | 503 | @staticmethod
|
424 | 504 | def replace_setting(buf, setting, value, xml_file=True):
|
|
0 commit comments