Ejemplo n.º 1
0
def main():
    args = parse_args()

    system_paasta_config = load_system_paasta_config()
    cluster = system_paasta_config.get_cluster()

    service, instance = chronos_tools.decompose_job_id(args.service_instance)

    config = chronos_tools.load_chronos_config()
    client = chronos_tools.get_chronos_client(config)

    related_jobs = chronos_tools.get_related_jobs_configs(cluster,
                                                          service,
                                                          instance,
                                                          soa_dir=args.soa_dir)
    if not related_jobs:
        error_msg = "No deployment found for {} in cluster {}. Has Jenkins run for it?".format(
            args.service_instance,
            cluster,
        )
        paasta_print(error_msg)
        raise NoDeploymentsAvailable

    if not args.run_all_related_jobs:
        # Strip all the configuration for the related services
        # those information will not be used by the rest of the flow
        related_jobs = {
            (service, instance): related_jobs[(service, instance)],
        }

    complete_job_configs = {}
    for (srv, inst) in related_jobs:
        try:
            complete_job_configs.update(
                {
                    (srv, inst):
                    chronos_tools.create_complete_config(
                        service=srv,
                        job_name=inst,
                        soa_dir=args.soa_dir,
                    ),
                }, )
        except (NoDeploymentsAvailable, NoDockerImageError) as e:
            error_msg = "No deployment found for {} in cluster {}. Has Jenkins run for it?".format(
                chronos_tools.compose_job_id(srv, inst),
                cluster,
            )
            paasta_print(error_msg)
            raise e
        except NoConfigurationForServiceError as e:
            error_msg = (
                "Could not read chronos configuration file for {} in cluster {}\nError was: {}"
                .format(
                    chronos_tools.compose_job_id(srv, inst),
                    cluster,
                    str(e),
                ))
            paasta_print(error_msg)
            raise e
        except chronos_tools.InvalidParentError as e:
            raise e

    if not args.run_all_related_jobs:
        sorted_jobs = [(service, instance)]
    else:
        sorted_jobs = chronos_tools.topological_sort_related_jobs(
            cluster, service, instance, soa_dir=args.soa_dir)

    timestamp = datetime.datetime.utcnow().isoformat()

    chronos_to_add = []
    for (service, instance) in sorted_jobs:
        # complete_job_config is a formatted version of the job,
        # so the command is formatted in the context of 'now'
        # replace it with the 'original' cmd so it can be re rendered
        chronos_job_config = chronos_tools.load_chronos_job_config(
            service=service,
            instance=instance,
            cluster=cluster,
            soa_dir=args.soa_dir,
        )
        original_command = chronos_job_config.get_cmd()
        complete_job_config = complete_job_configs[(service, instance)]
        complete_job_config['command'] = original_command
        clone = clone_job(
            chronos_job=complete_job_config,
            timestamp=timestamp,
            force_disabled=args.force_disabled,
        )
        # modify the command to run commands for a given date
        clone = modify_command_for_date(
            chronos_job=clone,
            date=datetime.datetime.strptime(args.execution_date,
                                            "%Y-%m-%dT%H:%M:%S"),
            verbose=args.verbose,
        )

        if not args.run_all_related_jobs and chronos_tools.get_job_type(
                clone) == chronos_tools.JobType.Dependent:
            # If the job is a dependent job and we want to re-run only the specific instance
            # remove the parents and update the schedule to start the job as soon as possible
            clone = set_default_schedule(remove_parents(clone))

        chronos_to_add.append(clone)

    for job_to_add in chronos_to_add:
        client.add(job_to_add)
Ejemplo n.º 2
0
def paasta_rerun(args):
    """Reruns a Chronos job.
    :param args: argparse.Namespace obj created from sys.args by cli"""
    system_paasta_config = load_system_paasta_config()
    soa_dir = args.soa_dir
    service = figure_out_service_name(
        args, soa_dir)  # exit with an error if the service doesn't exist
    if args.execution_date:
        execution_date = args.execution_date
    else:
        execution_date = None

    all_clusters = list_clusters(soa_dir=soa_dir)
    actual_deployments = get_actual_deployments(
        service, soa_dir)  # cluster.instance: sha
    if actual_deployments:
        deploy_pipeline = list(get_planned_deployments(
            service, soa_dir))  # cluster.instance
        deployed_clusters = list_deployed_clusters(deploy_pipeline,
                                                   actual_deployments)
        deployed_cluster_instance = _get_cluster_instance(
            actual_deployments.keys())

    if args.clusters is not None:
        clusters = args.clusters.split(",")
    else:
        clusters = deployed_clusters

    for cluster in clusters:
        paasta_print("cluster: %s" % cluster)

        if cluster not in all_clusters:
            paasta_print(
                "  Warning: \"%s\" does not look like a valid cluster." %
                cluster)
            continue
        if cluster not in deployed_clusters:
            paasta_print(
                f"  Warning: service \"{service}\" has not been deployed to \"{cluster}\" yet."
            )
            continue
        if not deployed_cluster_instance[cluster].get(args.instance, False):
            paasta_print(("  Warning: instance \"%s\" is either invalid "
                          "or has not been deployed to \"%s\" yet." %
                          (args.instance, cluster)))
            continue

        try:
            chronos_job_config = chronos_tools.load_chronos_job_config(
                service,
                args.instance,
                cluster,
                load_deployments=False,
                soa_dir=soa_dir,
            )
            if chronos_tools.uses_time_variables(
                    chronos_job_config) and execution_date is None:
                paasta_print(
                    ("  Warning: \"%s\" uses time variables interpolation, "
                     "please supply a `--execution_date` argument." %
                     args.instance))
                continue
        except NoConfigurationForServiceError as e:
            paasta_print("  Warning: %s" % e)
            continue
        if execution_date is None:
            execution_date = _get_default_execution_date()

        related_job_configs = get_related_jobs_configs(cluster, service,
                                                       args.instance)

        if not args.rerun_type and len(related_job_configs) > 1:
            instance_names = sorted([
                f'- {srv}{chronos_tools.INTERNAL_SPACER}{inst}'
                for srv, inst in related_job_configs
                if srv != service or inst != args.instance
            ])
            paasta_print(PaastaColors.red('  error'))
            paasta_print(
                'Instance {instance} has dependency relations with the following jobs:\n'
                '{relations}\n'
                '\n'
                'Please specify the rerun policy via --rerun-type argument'.
                format(
                    instance=args.instance,
                    relations='\n'.join(instance_names),
                ), )
            return

        rc, output = execute_chronos_rerun_on_remote_master(
            service=service,
            instancename=args.instance,
            cluster=cluster,
            verbose=args.verbose,
            execution_date=execution_date.strftime(
                chronos_tools.EXECUTION_DATE_FORMAT),
            system_paasta_config=system_paasta_config,
            run_all_related_jobs=args.rerun_type == 'graph',
            force_disabled=args.force_disabled,
        )
        if rc == 0:
            paasta_print(PaastaColors.green('  successfully created job'))
        else:
            paasta_print(PaastaColors.red('  error'))
            paasta_print(output)