Ejemplo n.º 1
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)
Ejemplo n.º 2
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
):
    """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_cmd = get_docker_run_cmd(
        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,
    )
    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:
        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)
Ejemplo n.º 3
0
def run_docker_container(
    docker_client,
    service,
    instance,
    docker_hash,
    volumes,
    interactive,
    command,
    healthcheck,
    healthcheck_only,
    instance_config,
    soa_dir=service_configuration_lib.DEFAULT_SOA_DIR,
):
    """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_unformatted_env()
    memory = instance_config.get_mem()
    random_port = pick_random_port()
    container_name = get_container_name()
    docker_run_cmd = get_docker_run_cmd(
        memory=memory,
        random_port=random_port,
        container_name=container_name,
        volumes=volumes,
        env=environment,
        interactive=interactive,
        docker_hash=docker_hash,
        command=command,
    )
    # http://stackoverflow.com/questions/4748344/whats-the-reverse-of-shlex-split
    joined_docker_run_cmd = " ".join(pipes.quote(word) for word in docker_run_cmd)
    healthcheck_mode, healthcheck_data = get_healthcheck_for_instance(
        service, instance, instance_config, random_port, soa_dir=soa_dir
    )

    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

        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:
                sys.exit(1)

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

    except KeyboardInterrupt:
        returncode = 3
        pass

    # 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)