Exemple #1
0
def test_list_containers(podman_backend):
    l = len(podman_backend.list_containers())
    assert l >= 0
    image = podman_backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                      tag=FEDORA_MINIMAL_REPOSITORY_TAG,
                                      pull_policy=PodmanImagePullPolicy.NEVER)
    prb = PodmanRunBuilder(command=["sleep", "1"],
                           additional_opts=[
                               "-e",
                               "FOO=BAR",
                           ])
    container = image.run_via_binary(run_command_instance=prb)
    try:
        container_list = podman_backend.list_containers()
        l = len(container_list)
        assert l >= 1
        print(container_list[0].metadata.identifier)
        cont_under_test = [
            x for x in container_list
            if x.metadata.identifier == container.get_id()
        ][0]
        assert cont_under_test.metadata.image
        assert cont_under_test.metadata.command
        assert cont_under_test.metadata.env_variables["FOO"] == "BAR"
        assert cont_under_test.get_IPv4s()
    finally:
        container.delete(force=True)
Exemple #2
0
def podman_run_builder():
    prb = PodmanRunBuilder()
    # there is no journal in a container:
    #   ERRO[0001] unable to write pod event:
    #   "write unixgram @00120->/run/systemd/journal/socket:
    #     sendmsg: no such file or directory"
    # prb.global_options = ["--events-backend=none"]
    # alternatively, do this in /etc/containers/libpod.conf
    return prb
Exemple #3
0
def test_container_create_failed(podman_backend):
    """
    Test podman run with execution non-existing command
    """
    # FIXME: Cleanup containers after run
    image = podman_backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                      tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    # should raise an exc, there is no such command: waldo; we need to find waldo first
    with pytest.raises(ConuException):
        image.run_via_binary(command=["waldo"])
    c = image.run_via_binary_in_foreground(PodmanRunBuilder(command=["waldo"]))
    c.popen_instance.communicate()
    try:
        assert c.popen_instance.returncode > 0
    finally:
        c.delete(force=True)
Exemple #4
0
def test_container_metadata(podman_backend):
    image = podman_backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                      tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    # TODO: add port bindings to the mix once they are supported in rootless mode
    c = image.run_via_binary(
        PodmanRunBuilder(
            command=["cat"],
            additional_opts=[
                '-i',
                '-t',
                '--name',
                'mycontainer',
                # '-p', '1234:12345',
                # '-p', '123:12345',
                # '-p', '8080',
                '--hostname',
                'my_hostname',
                '-e',
                'ENV1=my_env',
                '-e',
                'ASD=',
                '-e',
                'A=B=C=D',
                '--label',
                'testlabel1=testvalue1'
            ]))

    try:
        container_metadata = c.get_metadata()

        assert container_metadata.command == ["cat"]
        assert container_metadata.name == "mycontainer"
        assert container_metadata.env_variables["ENV1"] == "my_env"
        assert container_metadata.env_variables["ASD"] == ""
        assert container_metadata.env_variables["A"] == "B=C=D"
        assert container_metadata.hostname == "my_hostname"

        # FIXME: podman raise an error when you send option  '-e XYZ': no such env variable
        # assert "XYZ" not in list(container_metadata.env_variables.keys())
        # assert 12345 in container_metadata.port_mappings
        # assert container_metadata.port_mappings[12345] == [1234, 123]
        # assert 8080 in container_metadata.port_mappings
        # assert set(container_metadata.exposed_ports) == {8080, 12345}
        assert container_metadata.labels["testlabel1"] == "testvalue1"
        assert container_metadata.status == ContainerStatus.RUNNING
    finally:
        c.delete(force=True)
Exemple #5
0
def test_container(podman_backend):
    """
    Basic tests of interacting with a podman container
    """
    image = podman_backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                      tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    c = image.run_via_binary(
        PodmanRunBuilder(command=["cat"], additional_opts=["-i", "-t"]))
    try:
        assert c.is_running()
        assert "Config" in c.inspect()
        assert "Config" in c.inspect()
        assert c.get_id() == str(c)
        assert repr(c)
        assert isinstance(c.get_id(), string_types)
    finally:
        c.delete(force=True)
Exemple #6
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 PodmanRunBuilder
        :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 PodmanContainer
        """
        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 = PodmanRunBuilder(
                    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 PodmanRunBuilder()
            if not isinstance(run_command_instance, PodmanRunBuilder):
                raise ConuException("run_command_instance needs to be an "
                                    "instance of PodmanRunBuilder")

        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 = graceful_get(self._inspect(container_id), "Name")

        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 PodmanContainer(self,
                               container_id,
                               popen_instance=popen_instance,
                               name=container_name)
Exemple #7
0
    def run_via_binary(self,
                       run_command_instance=None,
                       command=None,
                       volumes=None,
                       additional_opts=None,
                       **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 PodmanRunBuilder
        :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 `podman run`
        :return: instance of PodmanContainer
        """

        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 = PodmanRunBuilder(
                    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 PodmanRunBuilder()
            if not isinstance(run_command_instance, PodmanRunBuilder):
                raise ConuException(
                    "run_command_instance needs to be an instance of PodmanRunBuilder"
                )

        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 = graceful_get(self._inspect(container_id), "Name")

        return PodmanContainer(self, container_id, name=container_name)