示例#1
0
def start_infra_in_docker_detached(console):
    """
    An alternative to start_infra_in_docker where the terminal is not blocked by the follow on the logfile.
    """
    console.log("preparing environment")
    try:
        prepare_docker_start()
    except ContainerExists as e:
        console.print(str(e))
        return

    # create and prepare container
    console.log("configuring container")
    container = LocalstackContainer()
    configure_container(container)
    container.truncate_log()

    # start the Localstack container as a Server
    console.log("starting container")
    server = LocalstackContainerServer(container)
    server.start()
    server.wait_is_container_running()
    console.log("detaching")
示例#2
0
def validate_localstack_config(name):
    # TODO: separate functionality from CLI output
    #  (use exceptions to communicate errors, and return list of warnings)
    from subprocess import CalledProcessError

    from localstack.cli import console

    dirname = os.getcwd()
    compose_file_name = name if os.path.isabs(name) else os.path.join(
        dirname, name)
    warns = []

    # validating docker-compose file
    cmd = ["docker-compose", "-f", compose_file_name, "config"]
    try:
        run(cmd, shell=False, print_error=False)
    except CalledProcessError as e:
        msg = f"{e}\n{to_str(e.output)}".strip()
        raise ValueError(msg)

    # validating docker-compose variable
    import yaml  # keep import here to avoid issues in test Lambdas

    with open(compose_file_name) as file:
        compose_content = yaml.full_load(file)
    services_config = compose_content.get("services", {})
    ls_service_name = [
        name for name, svc in services_config.items()
        if "localstack" in svc.get("image", "")
    ]
    if not ls_service_name:
        raise Exception(
            'No LocalStack service found in config (looking for image names containing "localstack")'
        )
    if len(ls_service_name) > 1:
        warns.append(
            f"Multiple candidates found for LocalStack service: {ls_service_name}"
        )
    ls_service_name = ls_service_name[0]
    ls_service_details = services_config[ls_service_name]
    image_name = ls_service_details.get("image", "")
    if image_name.split(":")[0] not in constants.OFFICIAL_IMAGES:
        warns.append(
            'Using custom image "%s", we recommend using an official image: %s'
            % (image_name, constants.OFFICIAL_IMAGES))

    # prepare config options
    network_mode = ls_service_details.get("network_mode")
    image_name = ls_service_details.get("image")
    container_name = ls_service_details.get("container_name") or ""
    docker_ports = (port.split(":")[-2]
                    for port in ls_service_details.get("ports", []))
    docker_env = dict((env.split("=")[0], env.split("=")[1])
                      for env in ls_service_details.get("environment", {}))
    edge_port = str(docker_env.get("EDGE_PORT") or config.EDGE_PORT)
    main_container = config.MAIN_CONTAINER_NAME

    # docker-compose file validation cases

    if (docker_env.get("PORT_WEB_UI") not in ["${PORT_WEB_UI- }", None, ""]
            and image_name == "localstack/localstack"):
        warns.append(
            '"PORT_WEB_UI" Web UI is now deprecated, '
            'and requires to use the "localstack/localstack-full" image.')

    if not docker_env.get("HOST_TMP_FOLDER"):
        warns.append(
            'Please configure the "HOST_TMP_FOLDER" environment variable to point to the '
            +
            "absolute path of a temp folder on your host system (e.g., HOST_TMP_FOLDER=${TMPDIR})"
        )

    if (main_container not in container_name
        ) and not docker_env.get("MAIN_CONTAINER_NAME"):
        warns.append(
            'Please use "container_name: %s" or add "MAIN_CONTAINER_NAME" in "environment".'
            % main_container)

    def port_exposed(port):
        for exposed in docker_ports:
            if re.match(r"^([0-9]+-)?%s(-[0-9]+)?$" % port, exposed):
                return True

    if not port_exposed(edge_port):
        warns.append(
            ("Edge port %s is not exposed. You may have to add the entry "
             'to the "ports" section of the docker-compose file.') % edge_port)

    if network_mode != "bridge" and not docker_env.get(
            "LAMBDA_DOCKER_NETWORK"):
        warns.append(
            'Network mode is not set to "bridge" which may cause networking issues in Lambda containers. '
            'Consider adding "network_mode: bridge" to your docker-compose file, or configure '
            "LAMBDA_DOCKER_NETWORK with the name of the Docker network of your compose stack."
        )

    # print warning/info messages
    for warning in warns:
        console.print("[yellow]:warning:[/yellow]", warning)
    if not warns:
        return True
    return False