Пример #1
0
    def run_via_binary(self, run_command_instance=None, command=None, volumes=None, additional_opts=None, *args, **kwargs):
        """
        create a container using this image and run it in background;
        this method is useful to test real user scenarios when users invoke containers using
        binary

        :param run_command_instance: instance of DockerRunBuilder
        :param command: list of str, command to run in the container, examples:
            - ["ls", "/"]
            - ["bash", "-c", "ls / | grep bin"]
        :param volumes: tuple or list of tuples in the form:

            * `("/path/to/directory", )`
            * `("/host/path", "/container/path")`
            * `("/host/path", "/container/path", "mode")`
            * `(conu.Directory('/host/path'), "/container/path")` (source can be also Directory instance)

        :param additional_opts: list of str, additional options for `docker run`
        :return: instance of DockerContainer
        """

        logger.info("run container via binary in background")

        if (command is not None or additional_opts is not None) and run_command_instance is not None:
            raise ConuException("run_command_instance and command parameters cannot be passed into method at same time")

        if run_command_instance is None:
            command = command or []
            additional_opts = additional_opts or []

            if (isinstance(command, list) or isinstance(command, tuple) and
                isinstance(additional_opts, list) or isinstance(additional_opts, tuple)):
                run_command_instance = DockerRunBuilder(command=command, additional_opts=additional_opts)
            else:
                raise ConuException("command and additional_opts needs to be list of str or None")
        else:
            run_command_instance = run_command_instance or DockerRunBuilder()
            if not isinstance(run_command_instance, DockerRunBuilder):
                raise ConuException("run_command_instance needs to be an instance of DockerRunBuilder")

        run_command_instance.image_name = self.get_id()
        run_command_instance.options += ["-d"]

        if volumes:
            run_command_instance.options += self.get_volume_options(volumes=volumes)

        def callback():
            try:
                # FIXME: catch std{out,err}, print stdout to logger.debug, stderr to logger.error
                run_cmd(run_command_instance.build())
            except subprocess.CalledProcessError as ex:
                raise ConuException("Container exited with an error: %s" % ex.returncode)

        container_id, _ = self._run_container(run_command_instance, callback)

        container_name = self.d.inspect_container(container_id)['Name'][1:]
        return DockerContainer(self, container_id, name=container_name)
Пример #2
0
    def run_via_binary_in_foreground(
            self, run_command_instance=None, command=None, volumes=None,
            additional_opts=None, popen_params=None, container_name=None):
        """
        Create a container using this image and run it in foreground;
        this method is useful to test real user scenarios when users invoke containers using
        binary and pass input into the container via STDIN. You are also responsible for:

         * redirecting STDIN when intending to use container.write_to_stdin afterwards by setting
              popen_params={"stdin": subprocess.PIPE} during run_via_binary_in_foreground

         * checking whether the container exited successfully via:
              container.popen_instance.returncode

        Please consult the documentation for subprocess python module for best practices on
        how you should work with instance of Popen

        :param run_command_instance: instance of DockerRunBuilder
        :param command: list of str, command to run in the container, examples:
            - ["ls", "/"]
            - ["bash", "-c", "ls / | grep bin"]
        :param volumes: tuple or list of tuples in the form:

            * `("/path/to/directory", )`
            * `("/host/path", "/container/path")`
            * `("/host/path", "/container/path", "mode")`
            * `(conu.Directory('/host/path'), "/container/path")` (source can be also
                Directory instance)

        :param additional_opts: list of str, additional options for `docker run`
        :param popen_params: dict, keyword arguments passed to Popen constructor
        :param container_name: str, pretty container identifier
        :return: instance of DockerContainer
        """
        logger.info("run container via binary in foreground")

        if (command is not None or additional_opts is not None) \
                and run_command_instance is not None:
            raise ConuException(
                "run_command_instance and command parameters cannot be "
                "passed into method at same time")

        if run_command_instance is None:
            command = command or []
            additional_opts = additional_opts or []

            if (isinstance(command, list) or isinstance(command, tuple) and
                    isinstance(additional_opts, list) or isinstance(additional_opts, tuple)):
                run_command_instance = DockerRunBuilder(
                    command=command, additional_opts=additional_opts)
            else:
                raise ConuException("command and additional_opts needs to be list of str or None")
        else:
            run_command_instance = run_command_instance or DockerRunBuilder()
            if not isinstance(run_command_instance, DockerRunBuilder):
                raise ConuException("run_command_instance needs to be an "
                                    "instance of DockerRunBuilder")

        popen_params = popen_params or {}

        run_command_instance.image_name = self.get_id()
        if container_name:
            run_command_instance.options += ["--name", container_name]

        if volumes:
            run_command_instance.options += self.get_volume_options(volumes=volumes)

        def callback():
            return subprocess.Popen(run_command_instance.build(), **popen_params)

        container_id, popen_instance = self._run_container(run_command_instance, callback)

        actual_name = self.d.inspect_container(container_id)['Name'][1:]
        if container_name and container_name != actual_name:
            raise ConuException(
                "Unexpected container name value. Expected = "
                + str(container_name) + " Actual = " + str(actual_name))
        if not container_name:
            container_name = actual_name
        return DockerContainer(
            self, container_id, popen_instance=popen_instance, name=container_name)