示例#1
0
def test_run_cancels_timer_thread_on_keyboard_interrupt():
    mock_process = mock.Mock()
    mock_timer_object = mock.Mock()
    with contextlib.nested(
        mock.patch("paasta_tools.utils.Popen", autospec=True, return_value=mock_process),
        mock.patch("paasta_tools.utils.threading.Timer", autospec=True, return_value=mock_timer_object),
    ) as (mock_popen, mock_timer):
        mock_process.stdout.readline.side_effect = KeyboardInterrupt
        with raises(KeyboardInterrupt):
            utils._run("sh echo foo", timeout=10)
        assert mock_timer_object.cancel.call_count == 1
示例#2
0
文件: sysdig.py 项目: oktopuz/paasta
def paasta_sysdig(args):
    if not args.local:
        mesos_master = get_any_mesos_master(cluster=args.cluster)
        ssh_cmd = 'ssh -At -o LogLevel=QUIET {0} "sudo paasta {1} --local"'.format(mesos_master, ' '.join(sys.argv[1:]))
        return_code, output = _run(ssh_cmd)
        if return_code != 0:
            print output
            sys.exit(return_code)
        slave, command = output.split(':', 1)
        subprocess.call(shlex.split("ssh -tA {0} '{1}'".format(slave, command.strip())))
        return
    status = get_status_for_instance(cluster=args.cluster,
                                     service=args.service,
                                     instance=args.instance)
    slave = pick_slave_from_status(status=status,
                                   host=args.host)
    marathon_config = load_marathon_config()
    marathon_url = marathon_config.get_url()[0]
    marathon_user = marathon_config.get_username()
    marathon_pass = marathon_config.get_password()
    mesos_url = get_mesos_master().host
    marathon_parsed_url = urlparse(marathon_url)
    marathon_creds_url = marathon_parsed_url._replace(netloc="{0}:{1}@{2}".format(marathon_user, marathon_pass,
                                                                                  marathon_parsed_url.netloc))
    print format_mesos_command(slave, status.marathon.app_id, mesos_url, marathon_creds_url.geturl())
示例#3
0
def run_chronos_rerun(context, service_instance):
    cmd = (
        "python ../paasta_tools/chronos_rerun.py -d %s '%s' "
        "2016-03-13T04:50:31"
    ) % (context.soa_dir, service_instance)
    exit_code, output = _run(cmd)
    context.exit_code, context.output = exit_code, output
示例#4
0
def mark_for_deployment(git_url, cluster, instance, service, commit):
    """Mark a docker image for deployment"""
    cmd = build_command(git_url, commit, cluster=cluster, instance=instance)
    # Clusterinstance should be in cluster.instance format
    returncode, output = _run(
        cmd,
        timeout=30,
    )
    loglines = get_loglines(
        returncode=returncode,
        cmd=cmd,
        output=output,
        commit=commit,
        cluster=cluster,
        instance=instance
    )
    for logline in loglines:
        _log(
            service=service,
            line=logline,
            component='deploy',
            level='event',
            cluster=cluster,
            instance=instance,
        )
    return returncode
示例#5
0
def paasta_push_to_registry(args):
    """Upload a docker image to a registry"""
    service = args.service
    if service and service.startswith('services-'):
        service = service.split('services-', 1)[1]
    validate_service_name(service)

    cmd = build_command(service, args.commit)
    loglines = []
    returncode, output = _run(
        cmd,
        timeout=3600,
        log=True,
        component='build',
        service=service,
        loglevel='debug'
    )
    if returncode != 0:
        loglines.append('ERROR: Failed to promote image for %s.' % args.commit)
        output = get_jenkins_build_output_url()
        if output:
            loglines.append('See output: %s' % output)
    else:
        loglines.append('Successfully pushed image for %s to registry' % args.commit)
    for logline in loglines:
        _log(
            service=service,
            line=logline,
            component='build',
            level='event',
        )
    return returncode
示例#6
0
文件: utils.py 项目: timopek/paasta
def run_paasta_serviceinit(subcommand, master, service, instancename, cluster, **kwargs):
    """Run 'paasta_serviceinit <subcommand>'. Return the output from running it."""
    if 'verbose' in kwargs and kwargs['verbose']:
        verbose_flag = "-v "
        timeout = 240
    else:
        verbose_flag = ''
        timeout = 60
    if 'app_id' in kwargs and kwargs['app_id']:
        app_id_flag = "--appid %s " % kwargs['app_id']
    else:
        app_id_flag = ''
    if 'delta' in kwargs and kwargs['delta']:
        delta = "--delta %s" % kwargs['delta']
    else:
        delta = ''
    command = 'ssh -A -n %s sudo paasta_serviceinit %s%s%s %s %s' % (
        master,
        verbose_flag,
        app_id_flag,
        compose_job_id(service, instancename),
        subcommand,
        delta
    )
    log.debug("Running Command: %s" % command)
    _, output = _run(command, timeout=timeout)
    return output
示例#7
0
文件: itest.py 项目: ashwinaj/paasta
def paasta_itest(args):
    """Build and test a docker image"""
    service = args.service
    if service and service.startswith("services-"):
        service = service.split("services-", 1)[1]
    validate_service_name(service)

    tag = build_docker_tag(service, args.commit)
    run_env = os.environ.copy()
    run_env["DOCKER_TAG"] = tag
    cmd = "make itest"
    loglines = []

    _log(service=service, line="starting itest for %s." % args.commit, component="build", level="event")
    returncode, output = _run(
        cmd, env=run_env, timeout=3600, log=True, component="build", service=service, loglevel="debug"
    )
    if returncode != 0:
        loglines.append("ERROR: itest failed for %s." % args.commit)
        output = get_jenkins_build_output_url()
        if output:
            loglines.append("See output: %s" % output)
    else:
        loglines.append("itest passed for %s." % args.commit)
        if not check_docker_image(service, args.commit):
            loglines.append("ERROR: itest has not created %s" % tag)
            returncode = 1
    for logline in loglines:
        _log(service=service, line=logline, component="build", level="event")
    sys.exit(returncode)
def run_cleanup_marathon_job(context, flags, expected_return_code):
    cmd = '../paasta_tools/cleanup_marathon_jobs.py --soa-dir %s %s' % (context.soa_dir, flags)
    paasta_print('Running cmd %s' % (cmd))
    exit_code, output = _run(cmd)
    paasta_print(output)

    assert exit_code == int(expected_return_code)
示例#9
0
文件: utils.py 项目: timopek/paasta
def check_ssh_and_sudo_on_master(master, timeout=10):
    """Given a master, attempt to ssh to the master and run a simple command
    with sudo to verify that ssh and sudo work properly. Return a tuple of the
    success status (True or False) and any output from attempting the check.
    """
    check_command = 'ssh -A -n %s sudo paasta_serviceinit -h' % master
    rc, output = _run(check_command, timeout=timeout)
    if rc == 0:
        return (True, None)
    if rc == 255:  # ssh error
        reason = 'Return code was %d which probably means an ssh failure.' % rc
        hint = 'HINT: Are you allowed to ssh to this machine %s?' % master
    if rc == 1:  # sudo error
        reason = 'Return code was %d which probably means a sudo failure.' % rc
        hint = 'HINT: Is your ssh agent forwarded? (ssh-add -l)'
    if rc == -9:  # timeout error
        reason = 'Return code was %d which probably means ssh took too long and timed out.' % rc
        hint = 'HINT: Is there network latency? Try running somewhere closer to the cluster.'
    else:  # unknown error
        reason = 'Return code was %d which is an unknown failure.' % rc
        hint = 'HINT: Talk to #operations and pastebin this output'
    output = ('ERROR cannot run check command %(check_command)s\n'
              '%(reason)s\n'
              '%(hint)s\n'
              'Output from check command: %(output)s' %
              {
                  'check_command': check_command,
                  'reason': reason,
                  'hint': hint,
                  'output': output,
              })
    return (False, output)
示例#10
0
文件: utils.py 项目: S-Chan/paasta
def run_paasta_serviceinit(subcommand, master, service, instances, cluster, stream, **kwargs):
    """Run 'paasta_serviceinit <subcommand>'. Return the output from running it."""
    if 'verbose' in kwargs and kwargs['verbose'] > 0:
        verbose_flag = ' '.join(['-v' for i in range(kwargs['verbose'])])
        timeout = 960 if subcommand == 'status' else 240
    else:
        verbose_flag = ''
        timeout = 240 if subcommand == 'status' else 60

    if 'app_id' in kwargs and kwargs['app_id']:
        app_id_flag = "--appid %s" % kwargs['app_id']
    else:
        app_id_flag = ''

    if 'delta' in kwargs and kwargs['delta']:
        delta_flag = "--delta %s" % kwargs['delta']
    else:
        delta_flag = ''

    ssh_flag = '-t' if stream else '-n'

    command_parts = [
        "ssh -A %s %s sudo paasta_serviceinit" % (ssh_flag, master),
        "-s %s" % service,
        "-i %s" % instances,
        verbose_flag,
        app_id_flag,
        delta_flag,
        subcommand
    ]
    command_without_empty_strings = [part for part in command_parts if part != '']
    command = ' '.join(command_without_empty_strings)
    log.debug("Running Command: %s" % command)
    _, output = _run(command, timeout=timeout, stream=stream)
    return output
示例#11
0
def paasta_serviceinit_command(context, command, job_id):
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s %s %s' % (context.soa_dir, job_id, command)
    print 'Running cmd %s' % cmd
    (exit_code, output) = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
def paasta_serviceinit_command_scale(context, delta, job_id):
    cmd = "../paasta_tools/paasta_serviceinit.py --soa-dir %s %s scale --delta %s" % (context.soa_dir, job_id, delta)
    print "Running cmd %s" % cmd
    (exit_code, output) = _run(cmd)
    print "Got exitcode %s with output:\n%s" % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
示例#13
0
def chronos_emergency_restart_job(context):
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s test-service.job restart' % context.soa_dir
    print 'Running cmd %s' % cmd
    (exit_code, output) = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
示例#14
0
文件: check.py 项目: somic/paasta
def makefile_responds_to(target):
    """Runs `make --dry-run <target>` to detect if a makefile responds to the
    specified target."""
    cmd = "make --dry-run %s" % target
    # According to http://www.gnu.org/software/make/manual/make.html#index-exit-status-of-make,
    # 0 means OK, and 2 means error
    returncode, _ = _run(cmd, timeout=5)
    return returncode == 0
示例#15
0
文件: check.py 项目: seco/paasta
def git_repo_check(service):
    git_url = get_git_url(service)
    cmd = 'git ls-remote %s' % git_url
    returncode, _ = _run(cmd, timeout=5)
    if returncode == 0:
        print PaastaCheckMessages.GIT_REPO_FOUND
    else:
        print PaastaCheckMessages.git_repo_missing(git_url)
def chronos_emergency_stop_job(context, service_instance):
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s %s stop' % (context.soa_dir, service_instance)
    print 'Running cmd %s' % cmd
    exit_code, output = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
示例#17
0
def chronos_status_verbose_returns_healthy(context):
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s test-service.job status --verbose' % context.soa_dir
    print 'Running cmd %s' % cmd
    (exit_code, output) = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
    assert "Running Tasks:" in output
def chronos_status_verbose_returns_healthy(context, service_instance):
    cmd = "../paasta_tools/paasta_serviceinit.py --soa-dir %s %s status --verbose" % (context.soa_dir, service_instance)
    print "Running cmd %s" % cmd
    (exit_code, output) = _run(cmd)
    print "Got exitcode %s with output:\n%s" % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
    assert "Running Tasks:" in output
def run_cleanup_marathon_job(context, flags, expected_return_code):
    cmd = '../paasta_tools/cleanup_marathon_jobs.py --soa-dir %s %s' % (context.soa_dir, flags)
    env = dict(os.environ)
    env['MESOS_CLI_CONFIG'] = '/nail/etc/mesos-cli.json'  # context.mesos_cli_config_filename
    print 'Running cmd %s with MESOS_CLI_CONFIG=%s' % (cmd, env['MESOS_CLI_CONFIG'])
    exit_code, output = _run(cmd, env=env)
    print output

    assert exit_code == int(expected_return_code)
def paasta_serviceinit_tail_stdstreams(context, service_instance):
    cmd = "../paasta_tools/paasta_serviceinit.py --soa-dir %s %s status -vv" % (context.soa_dir, service_instance)
    print 'Running cmd %s' % cmd
    exit_code, output = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
    assert "stdout EOF" in output
示例#21
0
def local_run_on_chronos_job_with_cmd(context):
    with Path("fake_simple_service"):
        local_run_cmd = ("paasta local-run "
                         "--yelpsoa-config-root ../fake_soa_configs_local_run/ "
                         "--service fake_simple_service "
                         "--cluster test-cluster "
                         "--instance chronos_job_with_cmd "
                         "--build ")
        context.local_run_return_code, context.local_run_output = _run(command=local_run_cmd, timeout=60)
def paasta_serviceinit_status_single_instance(context, service, instances):
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s -s %s -i %s status' % \
        (context.soa_dir, service, instances)
    print 'Running cmd %s' % cmd
    exit_code, output = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert "Running" in output
    assert exit_code == 0
示例#23
0
def run_paasta_metastatus(master, verbose=0):
    if verbose > 0:
        verbose_flag = " -%s" % "v" * verbose
        timeout = 120
    else:
        verbose_flag = ""
        timeout = 20
    command = "ssh -A -n %s sudo paasta_metastatus%s" % (master, verbose_flag)
    _, output = _run(command, timeout=timeout)
    return output
def chronos_status_returns_healthy(context, service_instance):
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s %s status' % (context.soa_dir, service_instance)
    print 'Running cmd %s' % cmd
    exit_code, output = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
    assert "Disabled" in output
    assert "New" in output
示例#25
0
文件: utils.py 项目: S-Chan/paasta
def run_chronos_rerun(master, service, instancename, **kwargs):
    timeout = 60
    verbose_flags = '-v ' * kwargs['verbose']
    command = 'ssh -A -n %s \'sudo chronos_rerun %s"%s %s" "%s"\'' % (
        master,
        verbose_flags,
        service,
        instancename,
        kwargs['execution_date'],
    )
    return _run(command, timeout=timeout)
示例#26
0
def paasta_serviceinit_status_multi_instances(context, service, instances):
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s -s %s -i %s status' % \
        (context.soa_dir, service, instances)
    paasta_print('Running cmd %s' % cmd)
    exit_code, output = _run(cmd)
    paasta_print('Got exitcode %s with output:\n%s' % (exit_code, output))
    paasta_print()  # sacrificial line for behave to eat instead of our output

    # one service is deployed and the other is not
    assert "Configured" in output
    assert exit_code != 0
示例#27
0
def docker_pull_image(docker_url):
    """Pull an image via ``docker pull``. Uses the actual pull command instead of the python
    bindings due to the docker auth/registry transition. Once we are past Docker 1.6
    we can use better credential management, but for now this function assumes the
    user running the command has already been authorized for the registry"""
    sys.stderr.write("Please wait while the image (%s) is pulled...\n" % docker_url)
    DEVNULL = open(os.devnull, 'wb')
    ret, output = _run('docker pull %s' % docker_url, stream=True, stdin=DEVNULL)
    if ret != 0:
        sys.stderr.write("\nPull failed. Are you authorized to run docker commands?\n")
        sys.exit(ret)
示例#28
0
def check_cleanup_chronos_jobs_output(context, expected_return_code):
    cmd = '../paasta_tools/cleanup_chronos_jobs.py --soa-dir %s' % context.soa_dir
    exit_code, output = _run(cmd)
    paasta_print(context.unconfigured_job_names)
    paasta_print('Got exitcode %s with output:\n%s' % (exit_code, output))

    assert exit_code == int(expected_return_code)
    assert "Successfully Removed Tasks (if any were running) for:" in output
    assert "Successfully Removed Jobs:" in output
    for job in context.unconfigured_job_names:
        assert '  %s' % job in output
示例#29
0
def paasta_serviceinit_command_appid(context, command, job_id):
    (service, instance, _, __) = decompose_job_id(job_id)
    app_id = marathon_tools.create_complete_config(service, instance, None, soa_dir=context.soa_dir)['id']
    cmd = '../paasta_tools/paasta_serviceinit.py --soa-dir %s --appid %s %s %s' \
          % (context.soa_dir, app_id, job_id, command)
    print 'Running cmd %s' % cmd
    (exit_code, output) = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
def paasta_serviceinit_tail_stdstreams(context, service_instance):
    cmd = "../paasta_tools/paasta_serviceinit.py --soa-dir %s %s status -vv" % (context.soa_dir, service_instance)
    print 'Running cmd %s' % cmd
    exit_code, output = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    print  # sacrificial line for behave to eat instead of our output

    assert exit_code == 0
    # The container we run doesn't really have a stdout/stderr. The message below
    # comes from mesos.cli, proving that paasta_serviceinit tried to read stdout/sdterr,
    # caught the Exception and presented the right information to the user.
    assert "No such task has the requested file or directory" in output
示例#31
0
def docker_pull_image(docker_url):
    """Pull an image via ``docker pull``. Uses the actual pull command instead of the python
    bindings due to the docker auth/registry transition. Once we are past Docker 1.6
    we can use better credential management, but for now this function assumes the
    user running the command has already been authorized for the registry"""
    paasta_print(
        "Please wait while the image (%s) is pulled (times out after 30m)..." %
        docker_url,
        file=sys.stderr)
    DEVNULL = open(os.devnull, 'wb')
    with open('/tmp/paasta-local-run-pull.lock', 'w') as f:
        with timed_flock(f, seconds=1800):
            ret, output = _run('docker pull %s' % docker_url,
                               stream=True,
                               stdin=DEVNULL)
            if ret != 0:
                paasta_print(
                    "\nPull failed. Are you authorized to run docker commands?",
                    file=sys.stderr,
                )
                sys.exit(ret)
示例#32
0
文件: utils.py 项目: rajacsp/paasta
def run_paasta_metastatus(
    master: str,
    groupings: Sequence[str],
    verbose: int = 0,
    autoscaling_info: bool = False,
    use_mesos_cache: bool = False,
) -> Tuple[int, str]:
    cmd_args, timeout = get_paasta_metastatus_cmd_args(
        groupings=groupings,
        verbose=verbose,
        autoscaling_info=autoscaling_info,
        use_mesos_cache=use_mesos_cache,
    )
    command = (
        'ssh -A -n -o StrictHostKeyChecking=no {} sudo paasta_metastatus {}'.
        format(
            master,
            " ".join(cmd_args),
        )).strip()
    return_code, output = _run(command, timeout=timeout)
    return return_code, output
示例#33
0
文件: utils.py 项目: pjbaur/paasta
def run_paasta_cluster_boost(
    master,
    action,
    pool,
    duration,
    override,
    boost,
    verbose,
):
    timeout = 20

    verbose_flag: Optional[str]
    if verbose > 0:
        verbose_flag = '-{}'.format('v' * verbose)
    else:
        verbose_flag = None

    pool_flag = f'--pool {pool}'
    duration_flag = f'--duration {duration}' if duration is not None else ''
    boost_flag = f'--boost {boost}' if boost is not None else ''
    override_flag = '--force' if override is not None else ''

    cmd_args = " ".join(
        filter(
            None, [
                action,
                pool_flag,
                duration_flag,
                boost_flag,
                override_flag,
                verbose_flag,
            ],
        ),
    )
    command = ('ssh -A -n -o StrictHostKeyChecking=no {} paasta_cluster_boost {}'.format(
        master,
        cmd_args,
    )).strip()
    return_code, output = _run(command, timeout=timeout)
    return return_code, output
示例#34
0
def run_paasta_metastatus(
    master,
    humanize,
    groupings,
    verbose=0,
    autoscaling_info=False,
    use_mesos_cache=False,
):
    if verbose > 0:
        verbose_flag = "-%s" % ('v' * verbose)
        timeout = 120
    else:
        verbose_flag = ''
        timeout = 20
    autoscaling_flag = "-a" if autoscaling_info else ""
    if autoscaling_flag and verbose < 2:
        verbose_flag = '-vv'
    humanize_flag = "-H" if humanize else ''
    groupings_flag = "-g %s" % " ".join(groupings) if groupings else ''
    cache_flag = "--use-mesos-cache" if use_mesos_cache else ''
    cmd_args = " ".join(
        filter(
            None,
            [
                verbose_flag,
                humanize_flag,
                groupings_flag,
                autoscaling_flag,
                cache_flag,
            ],
        ), )
    command = (
        'ssh -A -n -o StrictHostKeyChecking=no %s sudo paasta_metastatus %s' %
        (
            master,
            cmd_args,
        )).strip()
    return_code, output = _run(command, timeout=timeout)
    return return_code, output
示例#35
0
文件: utils.py 项目: mrtyler/paasta
def run_paasta_serviceinit(subcommand, master, service, instances, cluster, stream, ssh_flags='', **kwargs):
    """Run 'paasta_serviceinit <subcommand>'. Return the output from running it."""
    if 'verbose' in kwargs and kwargs['verbose'] > 0:
        verbose_flag = ' '.join(['-v' for i in range(kwargs['verbose'])])
        timeout = 960 if subcommand == 'status' else 240
    else:
        verbose_flag = ''
        timeout = 240 if subcommand == 'status' else 60

    if 'app_id' in kwargs and kwargs['app_id']:
        app_id_flag = "--appid %s" % kwargs['app_id']
    else:
        app_id_flag = ''

    if 'delta' in kwargs and kwargs['delta']:
        delta_flag = "--delta %s" % kwargs['delta']
    else:
        delta_flag = ''

    ssh_flags += ' -t' if stream else ' -n'
    ssh_flags = ssh_flags.strip()

    command_parts = [
        "ssh -A %s %s sudo paasta_serviceinit" % (ssh_flags, master),
        "-s %s" % service,
        "-i %s" % instances,
        verbose_flag,
        app_id_flag,
        delta_flag,
        subcommand
    ]
    command_without_empty_strings = [part for part in command_parts if part != '']
    command = ' '.join(command_without_empty_strings)
    log.debug("Running Command: %s" % command)
    return_code, output = _run(command, timeout=timeout, stream=stream)
    if return_code != 0:
        raise CalledProcessError(return_code, command, output)
    return output
示例#36
0
def perform_security_check(args):
    """It runs a few security tests, checks the return code and prints output that should help in fixing failures.
    If you are at Yelp, please visit https://confluence.yelpcorp.com/display/PAASTA/PaaSTA+security-check+explained
    to learn more.
    :param args: service - the name of the service; commit - upstream git commit.
    :return: 0 if the security-check passed, non-zero if it failed.
    """
    security_check_command = load_system_paasta_config(
    ).get_security_check_command()
    if not security_check_command:
        paasta_print("Nothing to be executed during the security-check step")
        return 0

    command = f"{security_check_command} {args.service} {args.commit}"

    ret_code, output = _run(command, timeout=3600, stream=True)
    if ret_code != 0:
        paasta_print(
            "The security-check failed. Please visit y/security-check-runbook to learn how to fix it ("
            "including whitelisting safe versions of packages and docker images)."
        )

    return ret_code
示例#37
0
def run_paasta_serviceinit(subcommand, master, service, instancename, cluster,
                           **kwargs):
    """Run 'paasta_serviceinit <subcommand>'. Return the output from running it."""
    if 'verbose' in kwargs and kwargs['verbose']:
        verbose_flag = "-v "
        timeout = 240
    else:
        verbose_flag = ''
        timeout = 60
    if 'app_id' in kwargs and kwargs['app_id']:
        app_id_flag = "--appid %s " % kwargs['app_id']
    else:
        app_id_flag = ''
    if 'delta' in kwargs and kwargs['delta']:
        delta = "--delta %s" % kwargs['delta']
    else:
        delta = ''
    command = 'ssh -A -n %s sudo paasta_serviceinit %s%s%s %s %s' % (
        master, verbose_flag, app_id_flag, compose_job_id(
            service, instancename), subcommand, delta)
    log.debug("Running Command: %s" % command)
    _, output = _run(command, timeout=timeout)
    return output
示例#38
0
def generate_pipeline(service):
    email_address = get_team_email_address(service=service)
    repo = get_git_repo_for_fab_repo(service)
    if email_address is None:
        owner = get_team(overrides={}, service=service)
    else:
        # fab_repo tacks on the domain, so we only want the first
        # part of the email.
        owner = re.sub('@.*', '', email_address)
    cmds = [
        'fab_repo setup_jenkins:services/%s,'
        'profile=paasta,job_disabled=False,owner=%s,repo=%s' %
        (service, owner, repo),
        'fab_repo setup_jenkins:services/%s,'
        'profile=paasta_boilerplate,owner=%s,repo=%s' % (service, owner, repo),
    ]
    for cmd in cmds:
        print "INFO: Executing %s" % cmd
        returncode, output = _run(cmd, timeout=90)
        if returncode != 0:
            print "ERROR: Failed to generate Jenkins pipeline"
            print output
            sys.exit(returncode)
示例#39
0
def check_ssh_on_master(master, timeout=10):
    """Given a master, attempt to ssh to the master and run a simple command
    with sudo to verify that ssh and sudo work properly. Return a tuple of the
    success status (True or False) and any output from attempting the check.
    """
    check_command = "ssh -A -n -o StrictHostKeyChecking=no %s /bin/true" % master
    rc, output = _run(check_command, timeout=timeout)
    if rc == 0:
        return (True, None)
    if rc == 255:  # ssh error
        reason = "Return code was %d which probably means an ssh failure." % rc
        hint = "HINT: Are you allowed to ssh to this machine %s?" % master
    if rc == 1:  # sudo error
        reason = "Return code was %d which probably means a sudo failure." % rc
        hint = "HINT: Is your ssh agent forwarded? (ssh-add -l)"
    if rc == -9:  # timeout error
        reason = (
            "Return code was %d which probably means ssh took too long and timed out."
            % rc
        )
        hint = "HINT: Is there network latency? Try running somewhere closer to the cluster."
    else:  # unknown error
        reason = "Return code was %d which is an unknown failure." % rc
        hint = "HINT: Talk to #paasta and pastebin this output"
    output = (
        "ERROR cannot run check command %(check_command)s\n"
        "%(reason)s\n"
        "%(hint)s\n"
        "Output from check command: %(output)s"
        % {
            "check_command": check_command,
            "reason": reason,
            "hint": hint,
            "output": output,
        }
    )
    return (False, output)
示例#40
0
def run_on_master(cluster,
                  system_paasta_config,
                  cmd_parts,
                  timeout=None,
                  shell=False,
                  dry=False,
                  err_code=-1):
    """Find connectable master for :cluster: and :system_paasta_config: args and
    invoke command from :cmd_parts:, wrapping it in ssh call.

    :returns (exit code, output)

    :param cluster: cluster to find master in
    :param system_paasta_config: system configuration to lookup master data
    :param cmd_parts: passed into paasta_tools.utils._run as command along with
        ssh bits
    :param timeout: see paasta_tools.utils._run documentation (default: None)
    :param shell: prepend :cmd_parts: with 'sh -c' (default: False)
    :param err_code: code to return along with error message when something goes
        wrong (default: -1)
    """
    try:
        master = connectable_master(cluster, system_paasta_config)
    except NoMasterError as e:
        return (err_code, str(e))

    ssh_parts = ['ssh', '-A', '-n', master]

    if shell:
        ssh_parts.extend('sh -c "%s"' % quote(' '.join(cmd_parts)))
    else:
        ssh_parts.append(' '.join(cmd_parts))

    if dry:
        return (0, "Would have run: %s" % ' '.join(ssh_parts))
    else:
        return _run(ssh_parts, timeout=timeout)
示例#41
0
def perform_security_check(args):
    """It runs a few security tests, checks the return code and prints output that should help in fixing failures.
    If you are at Yelp, please visit https://confluence.yelpcorp.com/display/PAASTA/PaaSTA+security-check+explained
    to learn more.
    :param args: service - the name of the service; commit - upstream git commit.
    :return: 0 if the security-check passed, non-zero if it failed.
    """
    security_check_command = load_system_paasta_config(
    ).get_security_check_command()
    if not security_check_command:
        paasta_print("Nothing to be executed during the security-check step")
        return 0

    command = "{} {} {}".format(security_check_command, args.service,
                                args.commit)

    ret_code, output = _run(command, timeout=300, stream=True)
    if ret_code != 0:
        paasta_print(
            "The security-check failed. Please visit y/security-check-runbook to learn how to fix it ("
            "including whitelisting safe versions of packages and docker images).",
        )

    sensu_status = pysensu_yelp.Status.CRITICAL if ret_code != 0 else pysensu_yelp.Status.OK
    send_event(
        service=args.service,
        check_name='%s.security_check' % args.service,
        overrides={
            'page': False,
            'ticket': True
        },
        status=sensu_status,
        output=output,
        soa_dir=DEFAULT_SOA_DIR,
    )

    return ret_code
示例#42
0
def paasta_sysdig(args):
    if not args.local:
        mesos_master = get_any_mesos_master(cluster=args.cluster)
        ssh_cmd = ('ssh -At -o StrictHostKeyChecking=no -o LogLevel=QUIET {0} '
                   '"sudo paasta {1} --local"').format(mesos_master,
                                                       ' '.join(sys.argv[1:]))
        return_code, output = _run(ssh_cmd)
        if return_code != 0:
            paasta_print(output)
            sys.exit(return_code)
        slave, command = output.split(':', 1)
        subprocess.call(
            shlex.split("ssh -tA {} '{}'".format(slave, command.strip())))
        return
    status = get_status_for_instance(
        cluster=args.cluster,
        service=args.service,
        instance=args.instance,
    )
    slave = pick_slave_from_status(
        status=status,
        host=args.host,
    )
    marathon_config = load_marathon_config()
    marathon_url = marathon_config.get_url()[0]
    marathon_user = marathon_config.get_username()
    marathon_pass = marathon_config.get_password()
    mesos_url = get_mesos_master().host
    marathon_parsed_url = urlparse(marathon_url)
    marathon_creds_url = marathon_parsed_url._replace(netloc="{}:{}@{}".format(
        marathon_user,
        marathon_pass,
        marathon_parsed_url.netloc,
    ))
    paasta_print(
        format_mesos_command(slave, status.marathon.app_id, mesos_url,
                             marathon_creds_url.geturl()))
示例#43
0
文件: utils.py 项目: xcorail/paasta
def run_paasta_metastatus(
    master: str,
    groupings: Sequence[str],
    verbose: int = 0,
    autoscaling_info: bool = False,
    use_mesos_cache: bool = False,
) -> Tuple[int, str]:
    if verbose > 0:
        verbose_flag = "-%s" % ('v' * verbose)
        timeout = 120
    else:
        verbose_flag = ''
        timeout = 20
    autoscaling_flag = "-a" if autoscaling_info else ""
    if autoscaling_flag and verbose < 2:
        verbose_flag = '-vv'
    groupings_flag = "-g %s" % " ".join(groupings) if groupings else ''
    cache_flag = "--use-mesos-cache" if use_mesos_cache else ''
    cmd_args = " ".join(
        filter(
            None,
            [
                verbose_flag,
                groupings_flag,
                autoscaling_flag,
                cache_flag,
            ],
        ), )
    command = (
        'ssh -A -n -o StrictHostKeyChecking=no {} sudo paasta_metastatus {}'.
        format(
            master,
            cmd_args,
        )).strip()
    return_code, output = _run(command, timeout=timeout)
    return return_code, output
示例#44
0
def mark_for_deployment(git_url, cluster, instance, service, commit):
    """Mark a docker image for deployment"""
    cmd = build_command(git_url, commit, cluster=cluster, instance=instance)
    # Clusterinstance should be in cluster.instance format
    returncode, output = _run(
        cmd,
        timeout=30,
    )
    loglines = get_loglines(returncode=returncode,
                            cmd=cmd,
                            output=output,
                            commit=commit,
                            cluster=cluster,
                            instance=instance)
    for logline in loglines:
        _log(
            service=service,
            line=logline,
            component='deploy',
            level='event',
            cluster=cluster,
            instance=instance,
        )
    return returncode
def run_setup_chronos_job(context, service_instance):
    cmd = (
        f"../paasta_tools/setup_chronos_job.py {service_instance} -d {context.soa_dir}"
    )
    exit_code, output = _run(cmd)
    context.exit_code, context.output = exit_code, output
def test_run_returns_when_popen_fails():
    fake_exception = OSError(1234, 'fake error')
    with mock.patch('paasta_tools.utils.Popen', autospec=True, side_effect=fake_exception):
        return_code, output = utils._run('nonexistant command', timeout=10)
    assert return_code == 1234
    assert 'fake error' in output
def run_command_in_container(context, code, task_id):
    cmd = f'../paasta_tools/paasta_execute_docker_command.py -i {task_id} -c "exit {code}"'
    paasta_print("Running cmd %s" % cmd)
    exit_code, output = _run(cmd)
    paasta_print(f"Got exitcode {exit_code} with output:\n{output}")
    context.return_code = exit_code
示例#48
0
def paasta_spark_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 local-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')

    # Use the default spark:client instance configs if not provided
    try:
        instance_config = get_instance_config(
            service=args.service,
            instance=args.instance,
            cluster=args.cluster,
            load_deployments=args.build is False,
            soa_dir=args.yelpsoa_config_root,
        )
    except NoConfigurationForServiceError as e:
        paasta_print(str(e), file=sys.stderr)
        return 1
    except NoDeploymentsAvailable:
        paasta_print(
            PaastaColors.red(
                "Error: No deployments.json found in %(soa_dir)s/%(service)s."
                "You can generate this by running:"
                "generate_deployments_for_service -d %(soa_dir)s -s %(service)s"
                % {
                    'soa_dir': args.yelpsoa_config_root,
                    'service': args.service,
                }, ),
            sep='\n',
            file=sys.stderr,
        )
        return 1

    if args.build:
        docker_url = build_and_push_docker_image(args)
        if docker_url is None:
            return 1
    else:
        try:
            docker_url = instance_config.get_docker_url()
        except NoDockerImageError:
            paasta_print(
                PaastaColors.red(
                    "Error: No sha has been marked for deployment for the %s deploy group.\n"
                    "Please ensure this service has either run through a jenkins pipeline "
                    "or paasta mark-for-deployment has been run for %s\n" % (
                        instance_config.get_deploy_group(),
                        args.service,
                    ), ),
                sep='',
                file=sys.stderr,
            )
            return 1
        paasta_print(
            "Please wait while the image (%s) is pulled (times out after 5m)..."
            % docker_url,
            file=sys.stderr,
        )
        retcode, _ = _run('sudo -H docker pull %s' % docker_url,
                          stream=True,
                          timeout=300)
        if retcode != 0:
            paasta_print(
                "\nPull failed. Are you authorized to run docker commands?",
                file=sys.stderr,
            )
            return 1

    return configure_and_run_docker_container(
        args,
        docker_img=docker_url,
        instance_config=instance_config,
        system_paasta_config=system_paasta_config,
    )
示例#49
0
def run_paasta_validate(context):
    validate_cmd = ("paasta validate "
                    "--yelpsoa-config-root %s "
                    "--service %s " % (context.soa_dir, context.service))
    context.validate_return_code, context.validate_output = _run(command=validate_cmd)
示例#50
0
def run_setup_chronos_job(context, service_instance):
    cmd = "../paasta_tools/setup_chronos_job.py %s -d %s" % (service_instance,
                                                             context.soa_dir)
    exit_code, output = _run(cmd)
    context.exit_code, context.output = exit_code, output
示例#51
0
def step_run_paasta_setup_tron_namespace_dry_run(context):
    cmd = (
        f"paasta_setup_tron_namespace --dry-run -a --soa-dir {context.soa_dir}"
        f" --cluster test-cluster")
    context.return_code, context.output = _run(command=cmd)
示例#52
0
def run_chronos_rerun_with_args(context, service_instance, cli_args):
    cmd = ("python ../paasta_tools/chronos_rerun.py -d %s %s '%s' "
           "2016-03-13T04:50:31") % (context.soa_dir, cli_args,
                                     service_instance)
    exit_code, output = _run(cmd)
    context.exit_code, context.output = exit_code, output
示例#53
0
def run_docker_container(docker_client,
                         service,
                         instance,
                         docker_hash,
                         volumes,
                         interactive,
                         command,
                         hostname,
                         healthcheck,
                         healthcheck_only,
                         instance_config,
                         soa_dir=DEFAULT_SOA_DIR,
                         dry_run=False,
                         json_dict=False):
    """docker-py has issues running a container with a TTY attached, so for
    consistency we execute 'docker run' directly in both interactive and
    non-interactive modes.

    In non-interactive mode when the run is complete, stop the container and
    remove it (with docker-py).
    """
    if interactive:
        sys.stderr.write(
            PaastaColors.yellow(
                "Warning! You're running a container in interactive mode.\n"
                "This is *NOT* how Mesos runs containers.\n"
                "To run the container exactly as Mesos does, omit the -I flag.\n\n"
            ))
    else:
        sys.stderr.write(
            PaastaColors.yellow(
                "You're running a container in non-interactive mode.\n"
                "This is how Mesos runs containers.\n"
                "Note that some programs behave differently when running with no\n"
                "tty attached (as your program is about to run).\n\n"))
    environment = instance_config.get_env_dictionary()
    net = instance_config.get_net()
    memory = instance_config.get_mem()
    random_port = pick_random_port()
    container_name = get_container_name()
    docker_params = instance_config.format_docker_parameters()
    docker_run_args = dict(
        memory=memory,
        random_port=random_port,
        container_name=container_name,
        volumes=volumes,
        env=environment,
        interactive=interactive,
        docker_hash=docker_hash,
        command=command,
        hostname=hostname,
        net=net,
        docker_params=docker_params,
    )
    docker_run_cmd = get_docker_run_cmd(**docker_run_args)
    joined_docker_run_cmd = ' '.join(docker_run_cmd)
    healthcheck_mode, healthcheck_data = get_healthcheck_for_instance(
        service, instance, instance_config, random_port, soa_dir=soa_dir)

    if dry_run:
        if json_dict:
            sys.stdout.write(json.dumps(docker_run_args) + '\n')
        else:
            sys.stdout.write(json.dumps(docker_run_cmd) + '\n')
        sys.exit(0)
    else:
        sys.stdout.write('Running docker command:\n%s\n' %
                         PaastaColors.grey(joined_docker_run_cmd))

    if interactive:
        # NOTE: This immediately replaces us with the docker run cmd. Docker
        # run knows how to clean up the running container in this situation.
        execlp('docker', *docker_run_cmd)
        # For testing, when execlp is patched out and doesn't replace us, we
        # still want to bail out.
        return

    container_started = False
    container_id = None
    try:
        (returncode, output) = _run(joined_docker_run_cmd)
        if returncode != 0:
            sys.stdout.write('Failure trying to start your container!\n'
                             'Returncode: %d\n'
                             'Output:\n'
                             '%s\n'
                             '\n'
                             'Fix that problem and try again.\n'
                             'http://y/paasta-troubleshooting\n' %
                             (returncode, output))
            # Container failed to start so no need to cleanup; just bail.
            sys.exit(1)
        container_started = True
        container_id = get_container_id(docker_client, container_name)
        sys.stdout.write('Found our container running with CID %s\n' %
                         container_id)

        # If the service has a healthcheck, simulate it
        if healthcheck_mode:
            status, _ = simulate_healthcheck_on_service(
                instance_config, docker_client, container_id, healthcheck_mode,
                healthcheck_data, healthcheck)
        else:
            status = True

        def _output_on_failure():
            sys.stdout.write(
                'Your service failed to start, here is the stdout and stderr\n'
            )
            sys.stdout.write(
                PaastaColors.grey(
                    docker_client.attach(container_id,
                                         stderr=True,
                                         stream=False,
                                         logs=True)))

        if healthcheck_only:
            sys.stdout.write(
                'Detected --healthcheck-only flag, exiting now.\n')
            if container_started:
                _cleanup_container(docker_client, container_id)
            if status:
                sys.exit(0)
            else:
                _output_on_failure()
                sys.exit(1)

        running = docker_client.inspect_container(
            container_id)['State']['Running']
        if running:
            sys.stdout.write(
                'Your service is now running! Tailing stdout and stderr:\n')
            for line in docker_client.attach(container_id,
                                             stderr=True,
                                             stream=True,
                                             logs=True):
                sys.stdout.write(PaastaColors.grey(line))
        else:
            _output_on_failure()
            returncode = 3

    except KeyboardInterrupt:
        returncode = 3

    # Cleanup if the container exits on its own or interrupted.
    if container_started:
        returncode = docker_client.inspect_container(
            container_id)['State']['ExitCode']
        _cleanup_container(docker_client, container_id)
    sys.exit(returncode)
示例#54
0
def run_command(context, timeout):
    fake_cmd = 'sleep 1'
    context.rc, context.output = _run(fake_cmd, timeout=float(timeout))
示例#55
0
def run_on_master(
    cluster,
    system_paasta_config,
    cmd_parts,
    timeout=None,
    err_code=-1,
    graceful_exit=False,
    stdin=None,
):
    """Find connectable master for :cluster: and :system_paasta_config: args and
    invoke command from :cmd_parts:, wrapping it in ssh call.

    :returns (exit code, output)

    :param cluster: cluster to find master in
    :param system_paasta_config: system configuration to lookup master data
    :param cmd_parts: passed into paasta_tools.utils._run as command along with
        ssh bits
    :param timeout: see paasta_tools.utils._run documentation (default: None)
    :param err_code: code to return along with error message when something goes
        wrong (default: -1)
    :param graceful_exit: wrap command in a bash script that waits for input and
        kills the original command; trap SIGINT and send newline into stdin
    """
    try:
        master = connectable_master(cluster, system_paasta_config)
    except NoMasterError as e:
        return (err_code, str(e))

    if graceful_exit:
        # Signals don't travel over ssh, kill process when anything lands on stdin instead
        # The procedure here is:
        # 1. send process to background and capture it's pid
        # 2. wait for stdin with timeout in a loop, exit when original process finished
        # 3. kill original process if loop finished (something on stdin)
        cmd_parts.append(
            "& p=$!; " +
            "while ! read -t1; do ! kill -0 $p 2>/dev/null && kill $$; done; "
            + "kill $p; wait")
        stdin = subprocess.PIPE
        stdin_interrupt = True
        popen_kwargs = {"preexec_fn": os.setsid}
    else:
        stdin_interrupt = False
        popen_kwargs = {}

    cmd_parts = [
        "ssh",
        "-q",
        "-t",
        "-t",
        "-A",
        master,
        "sudo /bin/bash -c %s" % quote(" ".join(cmd_parts)),
    ]

    log.debug("Running %s" % " ".join(cmd_parts))

    return _run(
        cmd_parts,
        timeout=timeout,
        stream=True,
        stdin=stdin,
        stdin_interrupt=stdin_interrupt,
        popen_kwargs=popen_kwargs,
    )
def run_command_in_container(context, code, task_id):
    cmd = '../paasta_tools/paasta_execute_docker_command.py -i %s -c "exit %s"' % (task_id, code)
    print 'Running cmd %s' % cmd
    exit_code, output = _run(cmd)
    print 'Got exitcode %s with output:\n%s' % (exit_code, output)
    context.return_code = exit_code
示例#57
0
def run_docker_container(
    docker_client,
    service,
    instance,
    docker_url,
    volumes,
    interactive,
    command,
    healthcheck,
    healthcheck_only,
    user_port,
    instance_config,
    secret_provider_name,
    soa_dir=DEFAULT_SOA_DIR,
    dry_run=False,
    json_dict=False,
    framework=None,
    secret_provider_kwargs={},
    skip_secrets=False,
):
    """docker-py has issues running a container with a TTY attached, so for
    consistency we execute 'docker run' directly in both interactive and
    non-interactive modes.

    In non-interactive mode when the run is complete, stop the container and
    remove it (with docker-py).
    """
    if user_port:
        if check_if_port_free(user_port):
            chosen_port = user_port
        else:
            paasta_print(
                PaastaColors.red(
                    "The chosen port is already in use!\n"
                    "Try specifying another one, or omit (--port|-o) and paasta will find a free one for you"
                ),
                file=sys.stderr,
            )
            sys.exit(1)
    else:
        chosen_port = pick_random_port(service)
    environment = instance_config.get_env_dictionary()
    if not skip_secrets:
        secret_environment = decrypt_secret_environment_variables(
            secret_provider_name=secret_provider_name,
            environment=environment,
            soa_dir=soa_dir,
            service_name=service,
            cluster_name=instance_config.cluster,
            secret_provider_kwargs=secret_provider_kwargs,
        )
        environment.update(secret_environment)
    local_run_environment = get_local_run_environment_vars(
        instance_config=instance_config, port0=chosen_port, framework=framework
    )
    environment.update(local_run_environment)
    net = instance_config.get_net()
    memory = instance_config.get_mem()
    container_name = get_container_name()
    docker_params = instance_config.format_docker_parameters()

    healthcheck_mode, healthcheck_data = get_healthcheck_for_instance(
        service, instance, instance_config, chosen_port, soa_dir=soa_dir
    )
    if healthcheck_mode is None:
        container_port = None
        interactive = True
    elif not user_port and not healthcheck and not healthcheck_only:
        container_port = None
    else:
        try:
            container_port = instance_config.get_container_port()
        except AttributeError:
            container_port = None

    simulate_healthcheck = (
        healthcheck_only or healthcheck
    ) and healthcheck_mode is not None

    docker_run_args = dict(
        memory=memory,
        chosen_port=chosen_port,
        container_port=container_port,
        container_name=container_name,
        volumes=volumes,
        env=environment,
        interactive=interactive,
        detach=simulate_healthcheck,
        docker_hash=docker_url,
        command=command,
        net=net,
        docker_params=docker_params,
    )
    docker_run_cmd = get_docker_run_cmd(**docker_run_args)
    joined_docker_run_cmd = " ".join(docker_run_cmd)

    if dry_run:
        if json_dict:
            paasta_print(json.dumps(docker_run_args))
        else:
            paasta_print(json.dumps(docker_run_cmd))
        return 0
    else:
        paasta_print(
            "Running docker command:\n%s" % PaastaColors.grey(joined_docker_run_cmd)
        )

    merged_env = {**os.environ, **environment}

    if interactive or not simulate_healthcheck:
        # NOTE: This immediately replaces us with the docker run cmd. Docker
        # run knows how to clean up the running container in this situation.
        wrapper_path = shutil.which("paasta_docker_wrapper")
        # To properly simulate mesos, we pop the PATH, which is not available to
        # The executor
        merged_env.pop("PATH")
        execlpe(wrapper_path, *docker_run_cmd, merged_env)
        # For testing, when execlpe is patched out and doesn't replace us, we
        # still want to bail out.
        return 0

    container_started = False
    container_id = None
    try:
        (returncode, output) = _run(docker_run_cmd, env=merged_env)
        if returncode != 0:
            paasta_print(
                "Failure trying to start your container!"
                "Returncode: %d"
                "Output:"
                "%s"
                ""
                "Fix that problem and try again."
                "http://y/paasta-troubleshooting" % (returncode, output),
                sep="\n",
            )
            # Container failed to start so no need to cleanup; just bail.
            sys.exit(1)
        container_started = True
        container_id = get_container_id(docker_client, container_name)
        paasta_print("Found our container running with CID %s" % container_id)

        if simulate_healthcheck:
            healthcheck_result = simulate_healthcheck_on_service(
                instance_config=instance_config,
                docker_client=docker_client,
                container_id=container_id,
                healthcheck_mode=healthcheck_mode,
                healthcheck_data=healthcheck_data,
                healthcheck_enabled=healthcheck,
            )

        def _output_exit_code():
            returncode = docker_client.inspect_container(container_id)["State"][
                "ExitCode"
            ]
            paasta_print(f"Container exited: {returncode})")

        if healthcheck_only:
            if container_started:
                _output_exit_code()
                _cleanup_container(docker_client, container_id)
            if healthcheck_mode is None:
                paasta_print(
                    "--healthcheck-only, but no healthcheck is defined for this instance!"
                )
                sys.exit(1)
            elif healthcheck_result is True:
                sys.exit(0)
            else:
                sys.exit(1)

        running = docker_client.inspect_container(container_id)["State"]["Running"]
        if running:
            paasta_print("Your service is now running! Tailing stdout and stderr:")
            for line in docker_client.attach(
                container_id, stderr=True, stream=True, logs=True
            ):
                paasta_print(line)
        else:
            _output_exit_code()
            returncode = 3

    except KeyboardInterrupt:
        returncode = 3

    # Cleanup if the container exits on its own or interrupted.
    if container_started:
        returncode = docker_client.inspect_container(container_id)["State"]["ExitCode"]
        _cleanup_container(docker_client, container_id)
    return returncode
示例#58
0
def paasta_spark_run(args):
    # argparse does not work as expected with both default and
    # type=validate_work_dir.
    validate_work_dir(args.work_dir)

    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 local-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")

    # Use the default spark:client instance configs if not provided
    try:
        instance_config = get_instance_config(
            service=args.service,
            instance=args.instance,
            cluster=args.cluster,
            load_deployments=args.build is False and args.image is None,
            soa_dir=args.yelpsoa_config_root,
        )
    except NoConfigurationForServiceError as e:
        paasta_print(str(e), file=sys.stderr)
        return 1
    except NoDeploymentsAvailable:
        paasta_print(
            PaastaColors.red(
                "Error: No deployments.json found in %(soa_dir)s/%(service)s."
                "You can generate this by running:"
                "generate_deployments_for_service -d %(soa_dir)s -s %(service)s"
                % {
                    "soa_dir": args.yelpsoa_config_root,
                    "service": args.service
                }),
            sep="\n",
            file=sys.stderr,
        )
        return 1

    if not args.cmd and not instance_config.get_cmd():
        paasta_print(
            "A command is required, pyspark, spark-shell, spark-submit or jupyter",
            file=sys.stderr,
        )
        return 1

    if args.build:
        docker_url = build_and_push_docker_image(args)
        if docker_url is None:
            return 1
    elif args.image:
        docker_url = args.image
    else:
        if args.cmd == "jupyter-lab":
            paasta_print(
                PaastaColors.red(
                    "The jupyter-lab command requires a prebuilt image with -I or --image."
                ),
                file=sys.stderr,
            )
            return 1

        try:
            docker_url = instance_config.get_docker_url()
        except NoDockerImageError:
            paasta_print(
                PaastaColors.red(
                    "Error: No sha has been marked for deployment for the %s deploy group.\n"
                    "Please ensure this service has either run through a jenkins pipeline "
                    "or paasta mark-for-deployment has been run for %s\n" %
                    (instance_config.get_deploy_group(), args.service)),
                sep="",
                file=sys.stderr,
            )
            return 1
        paasta_print(
            "Please wait while the image (%s) is pulled (times out after 5m)..."
            % docker_url,
            file=sys.stderr,
        )
        retcode, _ = _run("sudo -H docker pull %s" % docker_url,
                          stream=True,
                          timeout=300)
        if retcode != 0:
            paasta_print(
                "\nPull failed. Are you authorized to run docker commands?",
                file=sys.stderr,
            )
            return 1

    return configure_and_run_docker_container(
        args,
        docker_img=docker_url,
        instance_config=instance_config,
        system_paasta_config=system_paasta_config,
    )
示例#59
0
def run_docker_container(
    docker_client,
    service,
    instance,
    docker_hash,
    volumes,
    interactive,
    command,
    healthcheck,
    healthcheck_only,
    user_port,
    instance_config,
    soa_dir=DEFAULT_SOA_DIR,
    dry_run=False,
    json_dict=False,
    framework=None,
):
    """docker-py has issues running a container with a TTY attached, so for
    consistency we execute 'docker run' directly in both interactive and
    non-interactive modes.

    In non-interactive mode when the run is complete, stop the container and
    remove it (with docker-py).
    """
    if user_port:
        if check_if_port_free(user_port):
            chosen_port = user_port
        else:
            paasta_print(
                PaastaColors.red(
                    "The chosen port is already in use!\n"
                    "Try specifying another one, or omit (--port|-o) and paasta will find a free one for you"
                ),
                file=sys.stderr,
            )
            sys.exit(1)
    else:
        chosen_port = pick_random_port()
    environment = instance_config.get_env_dictionary()
    local_run_environment = get_local_run_environment_vars(
        instance_config=instance_config,
        port0=chosen_port,
        framework=framework,
    )
    environment.update(local_run_environment)
    net = instance_config.get_net()
    memory = instance_config.get_mem()
    container_name = get_container_name()
    docker_params = instance_config.format_docker_parameters()

    try:
        container_port = instance_config.get_container_port()
    except AttributeError:
        container_port = None

    docker_run_args = dict(
        memory=memory,
        chosen_port=chosen_port,
        container_port=container_port,
        container_name=container_name,
        volumes=volumes,
        env=environment,
        interactive=interactive,
        docker_hash=docker_hash,
        command=command,
        net=net,
        docker_params=docker_params,
    )
    docker_run_cmd = get_docker_run_cmd(**docker_run_args)
    joined_docker_run_cmd = ' '.join(docker_run_cmd)
    healthcheck_mode, healthcheck_data = get_healthcheck_for_instance(
        service, instance, instance_config, chosen_port, soa_dir=soa_dir)

    if dry_run:
        if json_dict:
            paasta_print(json.dumps(docker_run_args))
        else:
            paasta_print(json.dumps(docker_run_cmd))
        return 0
    else:
        paasta_print('Running docker command:\n%s' % PaastaColors.grey(joined_docker_run_cmd))

    if interactive:
        # NOTE: This immediately replaces us with the docker run cmd. Docker
        # run knows how to clean up the running container in this situation.
        execlp('paasta_docker_wrapper', *docker_run_cmd)
        # For testing, when execlp is patched out and doesn't replace us, we
        # still want to bail out.
        return 0

    container_started = False
    container_id = None
    try:
        (returncode, output) = _run(docker_run_cmd)
        if returncode != 0:
            paasta_print(
                'Failure trying to start your container!'
                'Returncode: %d'
                'Output:'
                '%s'
                ''
                'Fix that problem and try again.'
                'http://y/paasta-troubleshooting'
                % (returncode, output),
                sep='\n',
            )
            # Container failed to start so no need to cleanup; just bail.
            sys.exit(1)
        container_started = True
        container_id = get_container_id(docker_client, container_name)
        paasta_print('Found our container running with CID %s' % container_id)

        # If the service has a healthcheck, simulate it
        if healthcheck_mode is not None:
            healthcheck_result = simulate_healthcheck_on_service(
                instance_config=instance_config,
                docker_client=docker_client,
                container_id=container_id,
                healthcheck_mode=healthcheck_mode,
                healthcheck_data=healthcheck_data,
                healthcheck_enabled=healthcheck,
            )

        def _output_stdout_and_exit_code():
            returncode = docker_client.inspect_container(container_id)['State']['ExitCode']
            paasta_print('Container exited: %d)' % returncode)
            paasta_print('Here is the stdout and stderr:\n\n')
            paasta_print(
                docker_client.attach(container_id, stderr=True, stream=False, logs=True)
            )

        if healthcheck_only:
            if container_started:
                _output_stdout_and_exit_code()
                _cleanup_container(docker_client, container_id)
            if healthcheck_mode is None:
                paasta_print('--healthcheck-only, but no healthcheck is defined for this instance!')
                sys.exit(1)
            elif healthcheck_result is True:
                sys.exit(0)
            else:
                sys.exit(1)

        running = docker_client.inspect_container(container_id)['State']['Running']
        if running:
            paasta_print('Your service is now running! Tailing stdout and stderr:')
            for line in docker_client.attach(container_id, stderr=True, stream=True, logs=True):
                paasta_print(line)
        else:
            _output_stdout_and_exit_code()
            returncode = 3

    except KeyboardInterrupt:
        returncode = 3

    # Cleanup if the container exits on its own or interrupted.
    if container_started:
        returncode = docker_client.inspect_container(container_id)['State']['ExitCode']
        _cleanup_container(docker_client, container_id)
    return returncode
示例#60
0
def run_cleanup_chronos_jobs(context):
    cmd = '../paasta_tools/cleanup_chronos_jobs.py --soa-dir %s' % context.soa_dir
    context.exit_code, context.output = _run(cmd)
    paasta_print(context.output)