예제 #1
0
    def wait_for_service(self,
                         app_name,
                         port,
                         expected_output=None,
                         timeout=100):
        """
        Block until service is not ready to accept requests,
        raises an exc ProbeTimeout if timeout is reached
        :param app_name: str, name of the app
        :param port: str or int, port of the service
        :param expected_output: If not None method will check output returned from request
               and try to find matching string.
        :param timeout: int or float (seconds), time to wait for pod to run
        :return: None
        """
        logger.info('Waiting for service to get ready')
        try:

            Probe(timeout=timeout,
                  pause=10,
                  fnc=self.request_service,
                  app_name=app_name,
                  port=port,
                  expected_output=expected_output,
                  expected_retval=True).run()
        except ProbeTimeout:
            logger.warning("Timeout: Request to service unsuccessful.")
            raise ConuException("Timeout: Request to service unsuccessful.")
예제 #2
0
    def start_build(self, build, args=None):
        """
        Start new build, raise exception if build failed
        :param build: str, name of the build
        :param args: list of str, another args of 'oc start-build' commands
        :return: None
        """

        args = args or []

        c = self._oc_command(["start-build"] + [build] + args)

        logger.info("Executing build %s", build)
        logger.info("Build command: %s", " ".join(c))

        try:
            Probe(timeout=-1,
                  pause=5,
                  count=2,
                  expected_exceptions=subprocess.CalledProcessError,
                  expected_retval=None,
                  fnc=run_cmd,
                  cmd=c).run()
        except ProbeTimeout as e:
            raise ConuException("Cannot start build of application: %s" % e)
예제 #3
0
파일: backend.py 프로젝트: fasashen/conu
    def create_namespace(self):
        """
        Create namespace with random name
        :return: name of new created namespace
        """
        random_string = ''.join(
            random.choice(string.ascii_lowercase + string.digits)
            for _ in range(4))

        name = 'namespace-{random_string}'.format(random_string=random_string)

        namespace = client.V1Namespace(metadata=client.V1ObjectMeta(name=name))

        self.core_api.create_namespace(namespace)

        logger.info("Creating namespace: %s", name)

        # save all namespaces created with this backend
        self.managed_namespaces.append(name)

        # wait for namespace to be ready
        Probe(timeout=30,
              pause=5,
              expected_retval=True,
              fnc=self._namespace_ready,
              namespace=name).run()

        return name
예제 #4
0
    def wait(self, timeout=15):
        """
        block until pod is not running, raises an exc ProbeTimeout if timeout is reached
        :param timeout: int or float (seconds), time to wait for pod to run
        :return: None
        """

        Probe(timeout=timeout, fnc=self.get_phase, expected_retval=PodPhase.RUNNING).run()
예제 #5
0
파일: pod.py 프로젝트: rpitonak/conu
    def wait(self, timeout=15):
        """
        block until pod is not ready, raises an exc ProbeTimeout if timeout is reached
        :param timeout: int or float (seconds), time to wait for pod to run
        :return: None
        """

        Probe(timeout=timeout, fnc=self.is_ready, expected_retval=True).run()
예제 #6
0
    def wait_for_port(self, port, timeout=10, **probe_kwargs):
        """
        block until specified port starts accepting connections, raises an exc ProbeTimeout
        if timeout is reached

        :param port: int, port number
        :param timeout: int or float (seconds), time to wait for establishing the connection
        :param probe_kwargs: arguments passed to Probe constructor
        :return: None
        """
        Probe(timeout=timeout, fnc=functools.partial(self.is_port_open, port), **probe_kwargs).run()
예제 #7
0
파일: test_podman.py 프로젝트: palusus/conu
def test_wait_for_status(podman_backend):
    image = podman_backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                      tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    cmd = ['true']
    cont = image.run_via_binary(command=cmd)

    try:
        p = Probe(timeout=6, fnc=cont.is_running, expected_retval=False)
        p.run()  # let's wait for the container to exit
        assert cont.exit_code() == 0  # let's make sure it exited fine
    finally:
        cont.delete(force=True)
예제 #8
0
파일: test_podman.py 프로젝트: palusus/conu
def test_container_logs(podman_backend):
    image = podman_backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                      tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    command = ["bash", "-c", "for x in `seq 1 5`; do echo $x; done"]
    cont = image.run_via_binary(command=command)
    try:
        Probe(timeout=5, fnc=cont.is_running, expected_retval=False).run()
        assert not cont.is_running()
        assert list(cont.logs()) == [
            '1', '\n', '2', '\n', '3', '\n', '4', '\n', '5', '\n'
        ]
    finally:
        cont.delete(force=True)
예제 #9
0
파일: image.py 프로젝트: mateimicu/conu
 def _run_container(self, run_command_instance, callback):
     """ this is internal method """
     tmpfile = os.path.join(get_backend_tmpdir(), random_tmp_filename())
     # the cid file must not exist
     run_command_instance.options += ["--cidfile=%s" % tmpfile]
     logger.debug("docker command: %s" % run_command_instance)
     response = callback()
     # and we need to wait now; inotify would be better but is way more complicated and
     # adds dependency
     Probe(timeout=10, count=10, pause=0.1, fnc=lambda: os.path.exists(tmpfile)).run()
     with open(tmpfile, 'r') as fd:
         container_id = fd.read()
     return container_id, response
예제 #10
0
 def wait_for_service(self, app_name, expected_output=None, timeout=100):
     """
     Block until service is not ready to accept requests,
     raises an exc ProbeTimeout if timeout is reached
     :param app_name: str, name of app
     :param expected_output: If not None method will check output returned from request
            and try to find matching string.
     :param timeout: int or float (seconds), time to wait for pod to run
     :return: None
     """
     logger.info('Waiting for service to get ready')
     Probe(timeout=timeout,
           fnc=self.request_service,
           app_name=app_name,
           expected_output=expected_output,
           expected_retval=True).run()
예제 #11
0
    def run_via_binary(self,
                       run_command_instance=None,
                       command=None,
                       volumes=None,
                       additional_opts=None,
                       **kwargs):
        """
        create a buildah container using this image

        :param run_command_instance: not used
        :param command: not used, please use exec
        :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 `buildah from`
        :return: instance of BuildahContainer
        """
        logger.info("create buildah container")
        if not run_command_instance:
            run_command_instance = BuildahRunBuilder(
                command=command, additional_opts=additional_opts)
        run_command_instance.image_name = self.get_full_name()
        tmpfile = os.path.join(get_backend_tmpdir(), random_tmp_filename())
        run_command_instance.options += ["--cidfile=%s" % tmpfile]

        # TODO: add support for the skopeo transport names

        cmd = run_command_instance.build()

        # TODO: fix this using the run builder
        # if volumes:
        #     cmd += self.get_volume_options(volumes=volumes)

        run_cmd(cmd)

        Probe(timeout=10,
              count=10,
              pause=0.1,
              fnc=lambda: self._file_not_empty(tmpfile)).run()
        with open(tmpfile, 'r') as fd:
            container_id = fd.read()

        return BuildahContainer(self, container_id, image_class=self.__class__)
예제 #12
0
파일: image.py 프로젝트: lslebodn/conu
 def _run_container(self, run_command_instance, callback):
     """ this is internal method """
     tmpfile = os.path.join(get_backend_tmpdir(), random_tmp_filename())
     # the cid file must not exist
     run_command_instance.options += ["--cidfile=%s" % tmpfile]
     logger.debug("podman command: %s" % run_command_instance)
     response = callback()
     # and we need to wait now; inotify would be better but is way more complicated and
     # adds dependency
     try:
         Probe(timeout=10, count=25, pause=0.2, fnc=lambda: self._file_not_empty(tmpfile)).run()
     except (CountExceeded, ProbeTimeout) as ex:
         logger.info("exception while running a container: %s", ex)
         raise ConuException("Container was not created, please see the logs.")
     with open(tmpfile, 'r') as fd:
         container_id = fd.read()
     return container_id, response
예제 #13
0
파일: test_podman.py 프로젝트: palusus/conu
def test_exit_code(podman_backend):
    image = podman_backend.ImageClass(FEDORA_MINIMAL_REPOSITORY,
                                      tag=FEDORA_MINIMAL_REPOSITORY_TAG)
    cmd = ['sleep', '0.3']
    cont = image.run_via_binary(command=cmd)
    try:
        p = Probe(timeout=5, fnc=cont.is_running, expected_retval=False)
        p.run()
        assert not cont.is_running() and cont.exit_code() == 0
    finally:
        cont.delete(force=True)

    cmd = ['bash', '-c', "exit 42"]
    cont = image.run_via_binary(command=cmd)
    try:
        cont.wait()
        assert cont.exit_code() == 42
    finally:
        cont.delete(force=True)
예제 #14
0
    def _run_container(self, run_command_instance, callback):
        """ this is internal method """
        tmpfile = os.path.join(get_backend_tmpdir(), random_tmp_filename())
        # the cid file must not exist
        run_command_instance.options += ["--cidfile=%s" % tmpfile]
        logger.debug("docker command: %s" % run_command_instance)
        response = callback()

        def get_cont_id():
            if not os.path.exists(tmpfile):
                return False
            with open(tmpfile, 'r') as fd:
                content = fd.read()
            return bool(content)

        Probe(timeout=2, count=10, pause=0.1, fnc=get_cont_id).run()

        with open(tmpfile, 'r') as fd:
            container_id = fd.read()

        if not container_id:
            raise ConuException("We could not get container's ID, it probably was not created")
        return container_id, response
예제 #15
0
    def new_app(self,
                image,
                project,
                source=None,
                template=None,
                name_in_template=None,
                other_images=None,
                oc_new_app_args=None):
        """
        Deploy app in OpenShift cluster using 'oc new-app'
        :param image: image to be used as builder image
        :param project: project where app should be created
        :param source: source used to extend the image, can be path or url
        :param template: str, url or local path to a template to use
        :param name_in_template: dict, {repository:tag} image name used in the template
        :param other_images: list of dict, some templates need other image to be pushed into the
               OpenShift registry, specify them in this parameter as list of dict [{<image>:<tag>}],
               where "<image>" is DockerImage and "<tag>" is a tag under which the image should be
               available in the OpenShift registry.
        :param oc_new_app_args: additional parameters for the `oc new-app`
        :return: str, name of app
        """

        if template is not None and source is not None:
            raise ConuException(
                'cannot combine template parameter with source parameter')

        # app name is generated randomly
        random_string = ''.join(
            random.choice(string.ascii_lowercase + string.digits)
            for _ in range(4))
        name = 'app-{random_string}'.format(random_string=random_string)

        oc_new_app_args = oc_new_app_args or []

        if template is not None:
            if name_in_template is None:
                raise ConuException('You need to specify name_in_template')

            self._create_app_from_template(image, name, template,
                                           name_in_template, other_images,
                                           oc_new_app_args, project)

        else:
            new_image = OpenshiftBackend.push_to_registry(
                image,
                image.name.split('/')[-1], image.tag, project)

            c = self._oc_command(["new-app"] + oc_new_app_args +
                                 [new_image.name + "~" + source] + ["-n"] +
                                 [project] + ["--name=%s" % name])

            logger.info("Creating new app in project %s", project)

            try:
                o = run_cmd(c, return_output=True)
                logger.debug(o)
            except subprocess.CalledProcessError as ex:
                raise ConuException("oc new-app failed: %s" % ex)

            if os.path.isdir(source):
                c = self._oc_command(["-n"] + [project] + ["start-build"] +
                                     [name] + ["--from-dir=%s" % source])

                logger.info(
                    "Build application from local source in project %s",
                    project)

                try:
                    Probe(timeout=-1,
                          pause=5,
                          count=2,
                          expected_exceptions=subprocess.CalledProcessError,
                          expected_retval=None,
                          fnc=run_cmd,
                          cmd=c).run()
                except ProbeTimeout as e:
                    raise ConuException(
                        "Cannot start build of application: %s" % e)

        return name
예제 #16
0
    def _create_app_from_template(self, image, name, template,
                                  name_in_template, other_images,
                                  oc_new_app_args, project):
        """
        Helper function to create app from template
        :param image: image to be used as builder image
        :param template: str, url or local path to a template to use
        :param name_in_template: dict, {repository:tag} image name used in the template
        :param other_images: list of dict, some templates need other image to be pushed into the
               OpenShift registry, specify them in this parameter as list of dict [{<image>:<tag>}],
               where "<image>" is DockerImage and "<tag>" is a tag under which the image should be
               available in the OpenShift registry.
        :param oc_new_app_args: additional parameters for the `oc new-app`
        :param project: project where app should be created
        :return: None
        """
        # push images to registry
        repository, tag = list(name_in_template.items())[0]
        OpenshiftBackend.push_to_registry(image, repository, tag, project)

        other_images = other_images or []

        for o in other_images:
            image, tag = list(o.items())[0]
            OpenshiftBackend.push_to_registry(image,
                                              tag.split(':')[0],
                                              tag.split(':')[1], project)

        oc_new_app_args += [
            "-p", "NAME=%s" % name, "-p",
            "NAMESPACE=%s" % project
        ]

        c = self._oc_command(["new-app"] + [template] + oc_new_app_args +
                             ["-n"] + [project] + ["--name=%s" % name])

        logger.info("Creating new app in project %s", project)

        try:
            # ignore status because sometimes oc new-app can fail when image
            # is already pushed in register
            o = run_cmd(c, return_output=True, ignore_status=True)
            logger.debug(o)
        except subprocess.CalledProcessError as ex:
            raise ConuException("oc new-app failed: %s" % ex)

        c = self._oc_command(["start-build"] + [name])

        logger.info("Build application from local source in project %s",
                    project)

        try:
            Probe(timeout=-1,
                  pause=5,
                  count=2,
                  expected_exceptions=subprocess.CalledProcessError,
                  expected_retval=None,
                  fnc=run_cmd,
                  cmd=c).run()
        except ProbeTimeout as e:
            raise ConuException("Cannot start build of application: %s" % e)