예제 #1
0
def paasta_remote_run(args):
    system_paasta_config = get_system_paasta_config()

    if not args.cluster:
        default_cluster = system_paasta_config.get_remote_run_config().get(
            "default_cluster"
        )
        if not default_cluster:
            print(
                PaastaColors.red(
                    "Error: no cluster specified and no default cluster available"
                )
            )
            return 1
        args.cluster = default_cluster

    cmd_parts = create_remote_run_command(args)
    graceful_exit = args.action == "start" and not args.detach
    return_code, status = run_on_master(
        cluster=args.cluster,
        system_paasta_config=system_paasta_config,
        cmd_parts=cmd_parts,
        graceful_exit=graceful_exit,
    )

    # Status results are streamed. This print is for possible error messages.
    if status is not None:
        for line in status.rstrip().split("\n"):
            print("    %s" % line)

    return return_code
예제 #2
0
파일: remote_run.py 프로젝트: snafis/paasta
def paasta_remote_run(args):
    try:
        system_paasta_config = load_system_paasta_config()
    except PaastaNotConfiguredError:
        paasta_print(
            PaastaColors.yellow(
                "Warning: Couldn't load config files from '/etc/paasta'. This indicates"
                "PaaSTA is not configured locally on this host, and remote-run may not behave"
                "the same way it would behave on a server configured for PaaSTA."
            ),
            sep='\n',
        )
        system_paasta_config = SystemPaastaConfig({"volumes": []},
                                                  '/etc/paasta')

    cmd_parts = ['/usr/bin/paasta_remote_run']
    args_vars = vars(args)
    args_keys = {
        'service': None,
        'cluster': None,
        'yelpsoa_config_root': DEFAULT_SOA_DIR,
        'json_dict': False,
        'cmd': None,
        'verbose': True,
        'dry_run': False,
        'staging_timeout': None,
    }
    for key in args_vars:
        # skip args we don't know about
        if key not in args_keys:
            continue

        value = args_vars[key]

        # skip args that have default value
        if value == args_keys[key]:
            continue

        arg_key = re.sub(r'_', '-', key)

        if isinstance(value, bool) and value:
            cmd_parts.append('--%s' % arg_key)
        elif not isinstance(value, bool):
            cmd_parts.extend(['--%s' % arg_key, str(value)])

    constraints = [x.split(',', 2) for x in args_vars.get('constraint', [])]
    if len(constraints) > 0:
        cmd_parts.extend(
            ['--constraints-json',
             quote(json.dumps(constraints))])

    paasta_print('Running on master: %s' % ' '.join(cmd_parts))
    return_code, status = run_on_master(args.cluster,
                                        system_paasta_config,
                                        cmd_parts,
                                        dry=args.very_dry_run)

    # Status results are streamed. This print is for possible error messages.
    if status is not None:
        for line in status.rstrip().split('\n'):
            paasta_print('    %s' % line)

    return return_code
예제 #3
0
def paasta_start_or_stop(args, desired_state):
    """Requests a change of state to start or stop given branches of a service."""
    soa_dir = args.soa_dir

    pargs = apply_args_filters(args)
    if len(pargs) == 0:
        return 1

    affected_services = {
        s
        for service_list in pargs.values() for s in service_list.keys()
    }
    if len(affected_services) > 1:
        paasta_print(
            PaastaColors.red(
                "Warning: trying to start/stop/restart multiple services:"))

        for cluster, services_instances in pargs.items():
            paasta_print("Cluster %s:" % cluster)
            for service, instances in services_instances.items():
                paasta_print("    Service %s:" % service)
                paasta_print("        Instances %s" %
                             ",".join(instances.keys()))

        if sys.stdin.isatty():
            confirm = choice.Binary('Are you sure you want to continue?',
                                    False).ask()
        else:
            confirm = False
        if not confirm:
            paasta_print()
            paasta_print("exiting")
            return 1

    invalid_deploy_groups = []
    marathon_message_printed = False
    chronos_message_printed = False
    affected_flinkclusters = []

    if args.clusters is None or args.instances is None:
        if confirm_to_continue(pargs.items(), desired_state) is False:
            paasta_print()
            paasta_print("exiting")
            return 1

    for cluster, services_instances in pargs.items():
        for service, instances in services_instances.items():
            for instance in instances.keys():
                service_config = get_instance_config(
                    service=service,
                    cluster=cluster,
                    instance=instance,
                    soa_dir=soa_dir,
                    load_deployments=False,
                )
                if isinstance(service_config, FlinkClusterConfig):
                    affected_flinkclusters.append(service_config)
                    continue

                try:
                    remote_refs = get_remote_refs(service, soa_dir)
                except remote_git.LSRemoteException as e:
                    msg = (
                        "Error talking to the git server: %s\n"
                        "This PaaSTA command requires access to the git server to operate.\n"
                        "The git server may be down or not reachable from here.\n"
                        "Try again from somewhere where the git server can be reached, "
                        "like your developer environment.") % str(e)
                    paasta_print(msg)
                    return 1

                deploy_group = service_config.get_deploy_group()
                (deploy_tag,
                 _) = get_latest_deployment_tag(remote_refs, deploy_group)

                if deploy_tag not in remote_refs:
                    invalid_deploy_groups.append(deploy_group)
                else:
                    force_bounce = utils.format_timestamp(
                        datetime.datetime.utcnow())
                    if isinstance(service_config, MarathonServiceConfig
                                  ) and not marathon_message_printed:
                        print_marathon_message(desired_state)
                        marathon_message_printed = True
                    elif isinstance(
                            service_config,
                            ChronosJobConfig) and not chronos_message_printed:
                        print_chronos_message(desired_state)
                        chronos_message_printed = True

                    issue_state_change_for_service(
                        service_config=service_config,
                        force_bounce=force_bounce,
                        desired_state=desired_state,
                    )

    return_val = 0

    if affected_flinkclusters:
        if os.environ.get('ON_PAASTA_MASTER'):
            print_flinkcluster_message(desired_state)
            kube_client = KubeClient()
            for service_config in affected_flinkclusters:
                set_flinkcluster_desired_state(
                    kube_client=kube_client,
                    service=service_config.service,
                    instance=service_config.instance,
                    desired_state=dict(start='running',
                                       stop='stopped')[desired_state],
                )
        else:
            csi = defaultdict(lambda: defaultdict(list))
            for service_config in affected_flinkclusters:
                csi[service_config.cluster][service_config.service].append(
                    service_config.instance)

            system_paasta_config = load_system_paasta_config()
            for cluster, services_instances in csi.items():
                for service, instances in services_instances.items():
                    cmd_parts = [
                        'ON_PAASTA_MASTER=1',
                        'paasta',
                        desired_state,
                        '-c',
                        cluster,
                        '-s',
                        service,
                        '-i',
                        ','.join(instances),
                    ]
                    return_val, _ = run_on_master(
                        cluster=cluster,
                        system_paasta_config=system_paasta_config,
                        cmd_parts=cmd_parts,
                        graceful_exit=True,
                    )

    if invalid_deploy_groups:
        paasta_print("No branches found for %s in %s." %
                     (", ".join(invalid_deploy_groups), remote_refs))
        paasta_print("Has %s been deployed there yet?" % service)
        return_val = 1

    return return_val
예제 #4
0
def paasta_remote_run(args):
    try:
        system_paasta_config = load_system_paasta_config()
    except PaastaNotConfiguredError:
        paasta_print(
            PaastaColors.yellow(
                "Warning: Couldn't load config files from '/etc/paasta'. This "
                "indicates PaaSTA is not configured locally on this host, and "
                "remote-run may not behave the same way it would behave on a "
                "server configured for PaaSTA.", ),
            sep='\n',
        )
        system_paasta_config = SystemPaastaConfig(
            {"volumes": []},
            '/etc/paasta',
        )

    cmd_parts = ['/usr/bin/paasta_remote_run', args.action]
    args_vars = vars(args)
    args_keys = {
        'service': None,
        'yelpsoa_config_root': DEFAULT_SOA_DIR,
        'cmd': None,
        'verbose': False,
        'debug': False,
        'dry_run': False,
        'staging_timeout': None,
        'detach': False,
        'run_id': None,
        'framework_id': None,
        'instances': None,
        'instance': None,
        'docker_image': None,
    }

    # copy relevant arguments into cmd_parts
    for key in args_vars:
        # skip args we don't know about
        if key not in args_keys:
            continue

        value = args_vars[key]

        # skip args that have default value
        if value == args_keys[key]:
            continue

        arg_key = re.sub(r'_', '-', key)

        if isinstance(value, bool) and value:
            cmd_parts.append('--%s' % arg_key)
        elif not isinstance(value, bool):
            cmd_parts.extend(['--%s' % arg_key, quote(str(value))])

    constraints = [x.split(',', 2) for x in args_vars.get('constraint', [])]
    if len(constraints) > 0:
        cmd_parts.extend(
            ['--constraints-json',
             quote(json.dumps(constraints))], )

    if not args.cluster:
        default_cluster = system_paasta_config.get_remote_run_config().get(
            'default_cluster')
        if not default_cluster and not args.cluster:
            paasta_print(
                PaastaColors.red(
                    "Error: no cluster specified and no default cluster available"
                ))
            return 1
        cluster = default_cluster
    else:
        cluster = args.cluster

    cmd_parts.extend(['--cluster', quote(cluster)], )
    graceful_exit = (args.action == 'start' and not args.detach)
    return_code, status = run_on_master(
        cluster=cluster,
        system_paasta_config=system_paasta_config,
        cmd_parts=cmd_parts,
        graceful_exit=graceful_exit,
    )

    # Status results are streamed. This print is for possible error messages.
    if status is not None:
        for line in status.rstrip().split('\n'):
            paasta_print('    %s' % line)

    return return_code