Example #1
0
File: db.py Project: sitedata/bodhi
def db_container(docker_backend, docker_network):
    """Fixture preparing and yielding a PostgreSQL container.

    This container can be used by other apps to store data.

    Args:
        docker_backend (conu.DockerBackend): The Docker backend (fixture).
        docker_network (dict): The Docker network ID (fixture).

    Yields:
        conu.DockerContainer: The PostgreSQL container.
    """
    image = docker_backend.ImageClass(os.environ.get(
        "BODHI_INTEGRATION_POSTGRESQL_IMAGE", "postgres"),
                                      tag="latest")
    params = DockerContainerParameters(
        env_variables={"POSTGRES_HOST_AUTH_METHOD": "trust"})
    container = image.run_via_api(params)
    container.start()
    docker_backend.d.connect_container_to_network(
        container.get_id(),
        docker_network["Id"],
        aliases=["db", "db.ci"],
    )
    container.wait_for_port(5432, timeout=64)
    container.execute(["/usr/bin/pg_isready", "-q", "-t", "64"])
    yield container
    try:
        container.kill()
    except docker.errors.APIError:
        # If the container isn't running, this will get raised. It's fine, we wanted the container
        # stopped and it is, so pass.
        pass
    container.delete()
Example #2
0
    def run_via_api(self, container_params=None):
        """
        create a container using this image and run it in background via Docker-py API.
        https://docker-py.readthedocs.io/en/stable/api.html
        Note: If you are using Healthchecks, be aware that support of some options were introduced
        just with version of Docker-py API 1.29
        :param container_params: DockerContainerParameters
        :return: instance of DockerContainer
        """

        if not container_params:
            container_params = DockerContainerParameters()

        # Host-specific configuration
        host_config = self.d.create_host_config(
            auto_remove=container_params.remove,
            cap_add=container_params.cap_add,
            cap_drop=container_params.cap_drop,
            devices=container_params.devices,
            dns=container_params.dns,
            group_add=container_params.group_add,
            init=container_params.init,
            ipc_mode=container_params.ipc_mode,
            isolation=container_params.isolation,
            mem_limit=container_params.mem_limit,
            mounts=container_params.mounts,
            pids_limit=container_params.pids_limit,
            privileged=container_params.privileged,
            publish_all_ports=container_params.publish_all_ports,
            port_bindings=container_params.port_mappings,
            read_only=container_params.read_only)

        container = self.d.create_container(
            self.get_id(),
            command=container_params.command,
            detach=True,
            hostname=container_params.hostname,
            user=container_params.user,
            stdin_open=container_params.stdin_open,
            tty=container_params.tty,
            ports=container_params.exposed_ports,
            environment=container_params.env_variables,
            volumes=container_params.volumes,
            name=container_params.name,
            entrypoint=container_params.entrypoint,
            working_dir=container_params.working_dir,
            host_config=host_config,
            mac_address=container_params.mac_address,
            labels=container_params.labels,
            stop_signal=container_params.stop_signal,
            healthcheck=container_params.healthcheck,
            runtime=container_params.runtime)

        return DockerContainer(self,
                               container['Id'],
                               name=container_params.name)
Example #3
0
    def get_parameters(self):
        """
        Parse DockerRunBuilder options and create object with properties for docker-py run command
        :return: DockerContainerParameters
        """
        import argparse
        parser = argparse.ArgumentParser(add_help=False)

        # without parameter
        parser.add_argument("-i",
                            "--interactive",
                            action="store_true",
                            dest="stdin_open")
        parser.add_argument("-d",
                            "--detach",
                            action="store_true",
                            dest="detach")
        parser.add_argument("-t", "--tty", action="store_true", dest="tty")
        parser.add_argument("--init", action="store_true", dest="init")
        parser.add_argument("--privileged",
                            action="store_true",
                            dest="privileged")
        parser.add_argument("-P",
                            "--publish-all",
                            action="store_true",
                            dest="publish_all_ports")
        parser.add_argument("--read-only",
                            action="store_true",
                            dest="read_only")
        parser.add_argument("--rm", action="store_true", dest="remove")

        # string parameter
        parser.add_argument("--entrypoint", action="store", dest="entrypoint")
        parser.add_argument("-h",
                            "--hostname",
                            action="store",
                            dest="hostname")
        parser.add_argument("--name", action="store", dest="name")
        parser.add_argument("--ipc", action="store", dest="ipc_mode")
        parser.add_argument("--isolation", action="store", dest="isolation")
        parser.add_argument("--mac-address",
                            action="store",
                            dest="mac_address")
        parser.add_argument("-m", "--memory", action="store", dest="mem_limit")
        parser.add_argument("--network", action="store", dest="network")
        parser.add_argument("--platform", action="store", dest="platform")
        parser.add_argument("--runtime", action="store", dest="runtime")
        parser.add_argument("--stop-signal",
                            action="store",
                            dest="stop_signal")
        parser.add_argument("-u", "--user", action="store", dest="user")
        parser.add_argument("-w",
                            "--workdir",
                            action="store",
                            dest="working_dir")

        # int parameter
        parser.add_argument("--pids-limit",
                            action="store",
                            dest="pids_limit",
                            type=int)

        # list parameter
        parser.add_argument("-e",
                            "--env",
                            action="append",
                            dest="env_variables")
        parser.add_argument("--cap-add", action="append", dest="cap_add")
        parser.add_argument("--cap-drop", action="append", dest="cap_drop")
        parser.add_argument("--device", action="append", dest="devices")
        parser.add_argument("--dns", action="append", dest="dns")
        parser.add_argument("--group-add", action="append", dest="group_add")
        parser.add_argument("--mount", action="append", dest="mounts")
        parser.add_argument("-v", "--volume", action="append", dest="volumes")

        # dict parameter
        parser.add_argument("-l", "--label", action="append", dest="labels")
        parser.add_argument("-p",
                            "--publish",
                            action="append",
                            dest="port_mappings")

        # health
        parser.add_argument("--health-cmd", action="store", dest="health_cmd")
        parser.add_argument("--health-interval",
                            action="store",
                            dest="health_interval",
                            type=int)
        parser.add_argument("--health-retries",
                            action="store",
                            dest="health_retries",
                            type=int)
        parser.add_argument("--health-timeout",
                            action="store",
                            dest="health_timeout",
                            type=int)
        parser.add_argument("--no-healthcheck",
                            action="store_true",
                            dest="no_healthcheck")

        args, _ = parser.parse_known_args(args=self.options)
        command = self.arguments

        options_dict = vars(args)

        # create Healthcheck object
        if not options_dict.pop("no_healthcheck", None):
            options_dict["healthcheck"] = Healthcheck(
                test=options_dict.pop("health_cmd", None),
                interval=options_dict.pop("health_interval", None),
                timeout=options_dict.pop("health_timeout", None),
                retries=options_dict.pop("health_retries", None))
        else:
            options_dict['healthcheck'] = None

        # parse dictionary
        # {'name': 'separator'}
        with_dictionary_parameter = {'labels': '='}
        for name, separator in with_dictionary_parameter.items():
            if options_dict[name] is not None:
                dictionary = {}
                for item in options_dict[name]:
                    try:
                        key, value = item.split(separator)
                        dictionary[key] = value
                    except ValueError:
                        dictionary = options_dict[name]
                        raise ConuException(
                            'Wrong format of dictionary: {name}'.format(
                                name=name))
                        break
                options_dict[name] = dictionary

        # parse ports
        # create dictionary according to https://docker-py.readthedocs.io/en/stable/containers.html
        if options_dict['port_mappings'] is not None:
            dictionary = {}
            for port_string in options_dict['port_mappings']:
                colon_count = port_string.count(':')
                if colon_count == 2:
                    split_array = port_string.split(':')
                    if split_array[1] == '':
                        # format - ip::containerPort
                        # create dictionary - {'1111/tcp': ('127.0.0.1', None)}
                        dictionary[split_array[2]] = (split_array[0], None)
                    else:
                        # format - ip:hostPort:containerPort
                        # create dictionary - {'1111/tcp': ('127.0.0.1', 1111)}
                        dictionary[split_array[2]] = (split_array[0],
                                                      int(split_array[1]))
                elif colon_count == 1:
                    # format - hostPort:containerPort
                    # create dictionary - {'2222/tcp': 3333}
                    split_array = port_string.split(':')
                    dictionary[split_array[1]] = int(split_array[0])
                elif colon_count == 0:
                    # format - containerPort
                    # create dictionary - {'2222/tcp': None}
                    dictionary[port_string] = None
                else:
                    raise ConuException('Wrong format of port mappings')

            options_dict['port_mappings'] = dictionary

        container_parameters = DockerContainerParameters(
            cap_add=options_dict['cap_add'],
            cap_drop=options_dict['cap_drop'],
            command=command,
            detach=options_dict['detach'],
            devices=options_dict['devices'],
            dns=options_dict['dns'],
            entrypoint=options_dict['entrypoint'],
            env_variables=options_dict['env_variables'],
            group_add=options_dict['group_add'],
            healthcheck=options_dict['healthcheck'],
            hostname=options_dict['hostname'],
            init=options_dict['init'],
            ipc_mode=options_dict['ipc_mode'],
            isolation=options_dict['isolation'],
            labels=options_dict['labels'],
            mac_address=options_dict['mac_address'],
            mem_limit=options_dict['mem_limit'],
            mounts=options_dict['mounts'],
            name=options_dict['name'],
            network=options_dict['network'],
            pids_limit=options_dict['pids_limit'],
            platform=options_dict['platform'],
            port_mappings=options_dict['port_mappings'],
            privileged=options_dict['privileged'],
            publish_all_ports=options_dict['publish_all_ports'],
            read_only=options_dict['read_only'],
            remove=options_dict['remove'],
            runtime=options_dict['runtime'],
            stdin_open=options_dict['stdin_open'],
            stop_signal=options_dict['stop_signal'],
            tty=options_dict['tty'],
            user=options_dict['user'],
            volumes=options_dict['volumes'],
            working_dir=options_dict['working_dir'])

        return container_parameters