def _EnsureRapiFilesPresence(): """Ensures that the specified RAPI files are present on the cluster, if any. """ rapi_files_location = qa_config.get("rapi-files-location", None) if rapi_files_location is None: # No files to be had return print( qa_logging.FormatWarning("Replacing the certificate and users file on" " the node with the ones provided in %s" % rapi_files_location)) # The RAPI files AssertCommand(["mkdir", "-p", pathutils.RAPI_DATA_DIR]) for filename in _FILES_TO_COPY: basename = os.path.split(filename)[-1] AssertCommand( ["cp", os.path.join(rapi_files_location, basename), filename]) AssertCommand(["gnt-cluster", "copyfile", filename]) # The certificates have to be reloaded now AssertCommand(["service", "ganeti", "restart"])
def ReloadCertificates(ensure_presence=True): """Reloads the client RAPI certificate with the one present on the node. If the QA is set up to use a specific certificate using the "rapi-files-location" parameter, it will be put in place prior to retrieving it. """ if ensure_presence: _EnsureRapiFilesPresence() if _rapi_username is None or _rapi_password is None: raise qa_error.Error("RAPI username and password have to be set before" " attempting to reload a certificate.") # pylint: disable=W0603 # due to global usage global _rapi_ca global _rapi_client master = qa_config.GetMasterNode() # Load RAPI certificate from master node cmd = [ "openssl", "x509", "-in", qa_utils.MakeNodePath(master, pathutils.RAPI_CERT_FILE) ] # Write to temporary file _rapi_ca = tempfile.NamedTemporaryFile() _rapi_ca.write( qa_utils.GetCommandOutput(master.primary, utils.ShellQuoteArgs(cmd))) _rapi_ca.flush() port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT) cfg_curl = rapi.client.GenericCurlConfig(cafile=_rapi_ca.name, proxy="") if qa_config.UseVirtualCluster(): # TODO: Implement full support for RAPI on virtual clusters print qa_logging.FormatWarning( "RAPI tests are not yet supported on" " virtual clusters and will be disabled") assert _rapi_client is None else: _rapi_client = rapi.client.GanetiRapiClient(master.primary, port=port, username=_rapi_username, password=_rapi_password, curl_config_fn=cfg_curl) print "RAPI protocol version: %s" % _rapi_client.GetVersion()
def _VerifySubmissionDuration(duration_seconds): # only start to verify the submission duration once we got data from the # first 10 job submissions if len(submission_durations) >= 10: avg_duration = sum(submission_durations) / len( submission_durations) max_duration = avg_duration * 1.5 if duration_seconds > max_duration: print( qa_logging.FormatWarning( "Submitting a delay job took %f seconds, max %f expected" % (duration_seconds, max_duration))) else: submission_durations.append(duration_seconds)
def Setup(username, password): """Configures the RAPI client. """ # pylint: disable=W0603 # due to global usage global _rapi_ca global _rapi_client global _rapi_username global _rapi_password _rapi_username = username _rapi_password = password master = qa_config.GetMasterNode() # Load RAPI certificate from master node cmd = ["cat", qa_utils.MakeNodePath(master, pathutils.RAPI_CERT_FILE)] # Write to temporary file _rapi_ca = tempfile.NamedTemporaryFile() _rapi_ca.write( qa_utils.GetCommandOutput(master.primary, utils.ShellQuoteArgs(cmd))) _rapi_ca.flush() port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT) cfg_curl = rapi.client.GenericCurlConfig(cafile=_rapi_ca.name, proxy="") if qa_config.UseVirtualCluster(): # TODO: Implement full support for RAPI on virtual clusters print qa_logging.FormatWarning( "RAPI tests are not yet supported on" " virtual clusters and will be disabled") assert _rapi_client is None else: _rapi_client = rapi.client.GanetiRapiClient(master.primary, port=port, username=username, password=password, curl_config_fn=cfg_curl) print "RAPI protocol version: %s" % _rapi_client.GetVersion() return _rapi_client
def ApplyPatch(data, patch_module, patches, patch_path): """Applies a single patch. @type data: dict (deserialized json) @param data: The QA configuration to modify @type patch_module: module @param patch_module: The json patch module, loaded dynamically @type patches: dict of string to dict @param patches: The dictionary of patch path to content @type patch_path: string @param patch_path: The path to the patch, relative to the QA directory """ patch_content = patches[patch_path] print qa_logging.FormatInfo("Applying patch %s" % patch_path) if not patch_content and patch_path != _QA_DEFAULT_PATCH: print qa_logging.FormatWarning("The patch %s added by the user is empty" % patch_path) patch_module.apply_patch(data, patch_content, in_place=True)
def _ExecuteJobSubmittingCmd(cmd): """Executes a job submitting command and returns the resulting job ID. This will fail if submitting the job takes longer than L{MAX_JOB_SUBMISSION_DURATION}. @type cmd: list of string or string @param cmd: the job producing command to execute on the cluster @rtype: int @return: job-id """ start = datetime.datetime.now() result = qa_job_utils.ExecuteJobProducingCommand(cmd) duration = qa_utils.TimedeltaToTotalSeconds(datetime.datetime.now() - start) if duration > MAX_JOB_SUBMISSION_DURATION: print( qa_logging.FormatWarning( "Executing '%s' took %f seconds, a maximum of %f was expected" % (cmd, duration, MAX_JOB_SUBMISSION_DURATION))) return result