Example #1
0
def getenvdict(reader: SectionReader, key: str) -> Mapping[str, str]:
    environment = {}
    for value in reader.getlist(key):
        envvar, _, value = value.partition("=")
        environment[envvar] = value
    return environment
Example #2
0
def parse_container_config(
    config: Config, container_name: str, all_container_names: Container[str]
) -> ContainerConfig:
    inipath = str(config.toxinipath)
    iniparser = py.iniconfig.IniConfig(inipath)

    reader = SectionReader(f"docker:{container_name}", iniparser)
    reader.addsubstitutions(
        distdir=config.distdir,
        homedir=config.homedir,
        toxinidir=config.toxinidir,
        toxworkdir=config.toxworkdir,
    )

    kwargs = {
        "name": container_name,
        "image": Image(reader.getstring("image")),
        "stop": container_name not in config.option.docker_dont_stop,
    }

    environment = None
    if reader.getstring("environment"):
        environment = getenvdict(reader, "environment")

    hc_cmd = hc_interval = hc_timeout = hc_start_period = hc_retries = None
    if reader.getstring("healthcheck_cmd"):
        hc_cmd = reader.getstring("healthcheck_cmd")
    if reader.getstring("healthcheck_interval"):
        hc_interval = gettime(reader, "healthcheck_interval")
    if reader.getstring("healthcheck_timeout"):
        hc_timeout = gettime(reader, "healthcheck_timeout")
    if reader.getstring("healthcheck_start_period"):
        hc_start_period = gettime(reader, "healthcheck_start_period")
    if reader.getstring("healthcheck_retries"):
        hc_retries = getint(reader, "healthcheck_retries")

    ports = None
    if reader.getstring("ports"):
        ports = [Port(line) for line in reader.getlist("ports")]

    links = None
    if reader.getstring("links"):
        links = [Link(line) for line in reader.getlist("links")]

    volumes = None
    if reader.getstring("volumes"):
        volumes = [Volume(line) for line in reader.getlist("volumes")]

    return ContainerConfig(
        name=container_name,
        image=Image(reader.getstring("image")),
        stop=container_name not in config.option.docker_dont_stop,
        environment=environment,
        healthcheck_cmd=hc_cmd,
        healthcheck_interval=hc_interval,
        healthcheck_timeout=hc_timeout,
        healthcheck_start_period=hc_start_period,
        healthcheck_retries=hc_retries,
        ports=ports,
        links=links,
        volumes=volumes,
    )
Example #3
0
def tox_configure(config):  # noqa: C901
    def getfloat(reader, key):
        val = reader.getstring(key)
        if val is None:
            return None

        try:
            return float(val)
        except ValueError:
            msg = f"{val!r} is not a number (for {key} in [{reader.section_name}])"
            raise ValueError(msg)

    def gettime(reader, key):
        return int(getfloat(reader, key) * SECOND)

    def getint(reader, key):
        raw = getfloat(reader, key)
        val = int(raw)
        if val != raw:
            msg = f"{val!r} is not an int (for {key} in [{reader.section_name}])"
            raise ValueError(msg)
        return val

    def getenvdict(reader, key):
        environment = {}
        for value in reader.getlist(key):
            envvar, _, value = value.partition("=")
            environment[envvar] = value
        return environment

    # discover container configs
    inipath = str(config.toxinipath)
    iniparser = py.iniconfig.IniConfig(inipath)

    container_configs = {}
    for section in iniparser.sections:
        if not section.startswith("docker:"):
            continue

        _, _, container_name = section.partition(":")
        if not re.match(r"^[a-zA-Z][-_.a-zA-Z0-9]+$", container_name):
            raise ValueError(
                f"{container_name!r} is not a valid container name")

        # populated in the next loop
        container_configs[container_name] = {}

    # validate command line options
    for container_name in config.option.docker_dont_stop:
        if container_name not in container_configs:
            raise ValueError(
                f"Container {container_name!r} not found (from --docker-dont-stop)"
            )

    # validate tox.ini
    for section in iniparser.sections:
        if not section.startswith("docker:"):
            continue
        reader = SectionReader(section, iniparser)
        reader.addsubstitutions(
            distdir=config.distdir,
            homedir=config.homedir,
            toxinidir=config.toxinidir,
            toxworkdir=config.toxworkdir,
        )
        _, _, container_name = section.partition(":")

        container_configs[container_name].update({
            "image":
            reader.getstring("image"),
            "stop":
            container_name not in config.option.docker_dont_stop,
        })

        if reader.getstring("environment"):
            env = getenvdict(reader, "environment")
            container_configs[container_name]["environment"] = env

        if reader.getstring("healthcheck_cmd"):
            container_configs[container_name][
                "healthcheck_cmd"] = reader.getstring("healthcheck_cmd")
        if reader.getstring("healthcheck_interval"):
            container_configs[container_name][
                "healthcheck_interval"] = gettime(reader,
                                                  "healthcheck_interval")
        if reader.getstring("healthcheck_timeout"):
            container_configs[container_name]["healthcheck_timeout"] = gettime(
                reader, "healthcheck_timeout")
        if reader.getstring("healthcheck_start_period"):
            container_configs[container_name][
                "healthcheck_start_period"] = gettime(
                    reader, "healthcheck_start_period")
        if reader.getstring("healthcheck_retries"):
            container_configs[container_name]["healthcheck_retries"] = getint(
                reader, "healthcheck_retries")

        if reader.getstring("ports"):
            container_configs[container_name]["ports"] = reader.getlist(
                "ports")

        if reader.getstring("links"):
            container_configs[container_name]["links"] = dict(
                _validate_link_line(link_line, container_configs.keys())
                for link_line in reader.getlist("links") if link_line.strip())

        if reader.getstring("volumes"):
            container_configs[container_name]["mounts"] = [
                _validate_volume_line(volume_line)
                for volume_line in reader.getlist("volumes")
                if volume_line.strip()
            ]

    config._docker_container_configs = container_configs