Пример #1
0
    def deploy_image(self, image_name, oc_new_app_args, project, name=None):
        """
        Deploy image in OpenShift cluster using 'oc new-app'
        :param image_name: image name with tag
        :param oc_new_app_args: additional parameters for the `oc new-app`, env variables etc.
        :param project: project where app should be created
        :param name:str, name of application, if None random name is generated
        :return: str, name of the app
        """
        self.project = project

        # app name is generated randomly
        name = name or 'app-{random_string}'.format(
            random_string=random_str(5))

        oc_new_app_args = oc_new_app_args or []

        new_image = self.import_image(image_name.split('/')[-1], image_name)

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

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

        try:
            run_cmd(c)
        except subprocess.CalledProcessError as ex:
            raise ConuException("oc new-app failed: %s" % ex)

        return name
Пример #2
0
    def run_via_binary(self, command=None, foreground=False, volumes=None,
            additional_opts=None, default_options=None, name=None, *args, **kwargs):
        """
        Create new instance NspawnContianer in case of not running at foreground, in case foreground run, return process
        object

        :param command: list - command to run
        :param foreground: bool - run process at foreground
        :param volumes: list - put additional bind mounts
        :param additional_opts: list of more boot options for systemd-nspawn command
        :param default_options: default boot option (-b)
        :param name: str - name of running instance
        :param args: pass thru params to subprocess.Popen
        :param kwargs: pass thru params to subprocess.Popen
        :return: process or NspawnContianer instance
        """
        command = deepcopy(command) or []
        volumes = deepcopy(volumes) or []
        additional_opts = deepcopy(additional_opts) or []
        internalkw = deepcopy(kwargs) or {}
        inernalargs = deepcopy(args) or []
        if default_options is None:
            default_options = ["-b"]
        # TODO: reconsile parameters (changed from API definition)
        logger.info("run container via binary in background")
        machine_name = constants.CONU_ARTIFACT_TAG
        if name:
            machine_name += name
        else:
            machine_name += random_str()

        if not foreground:
            # WARN: avoid to run boot without stderr and stdout to terminal, it breaks terminal,
            # it systemd-nspawn does some magic with console
            # TODO: is able to avoid this behaviour in better way?
            internalkw["stdout"] = subprocess.PIPE
            internalkw["stderr"] = subprocess.PIPE
        additional_opts += default_options
        if volumes:
            additional_opts += self.get_volume_options(volumes=volumes)
        logger.debug("starting NSPAWN")
        systemd_command = [
            "systemd-nspawn",
            "--machine",
            machine_name,
            "-i",
            self.local_location] + additional_opts + command
        logger.debug("Start command: %s" % " ".join(systemd_command))
        callback_method = (subprocess.Popen, systemd_command, inernalargs, internalkw)
        self.container_process = NspawnContainer.internal_run_container(
            name=machine_name,
            callback_method=callback_method,
            foreground=foreground
        )
        if foreground:
            return self.container_process
        else:
            return NspawnContainer(self, None, name=machine_name,
                                   start_process=self.container_process, start_action=callback_method)
Пример #3
0
    def create_new_app_from_source(self,
                                   image,
                                   project,
                                   source=None,
                                   oc_new_app_args=None):
        """
        Deploy app using source-to-image 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 oc_new_app_args: additional parameters for the `oc new-app`
        :return: str, name of the app
        """

        # app name is generated randomly
        name = 'app-{random_string}'.format(random_string=random_str(5))

        oc_new_app_args = oc_new_app_args or []

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

        c = self._oc_command(["new-app"] + [new_image.name + "~" + source] +
                             oc_new_app_args + ["-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)

        # build from local source
        if os.path.isdir(source):
            self.start_build(name, ["-n", project, "--from-dir=%s" % source])

        return name
Пример #4
0
    def create_namespace(self):
        """
        Create namespace with random name
        :return: name of new created namespace
        """
        name = 'namespace-{random_string}'.format(random_string=random_str(5))

        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
Пример #5
0
    def run_systemdrun(self,
                       command,
                       internal_background=False,
                       return_full_dict=False,
                       **kwargs):
        """
        execute command via systemd-run inside container

        :param command: list of command params
        :param internal_background: not used now
        :param kwargs: pass params to subprocess
        :return: dict with result
        """
        internalkw = deepcopy(kwargs) or {}
        original_ignore_st = internalkw.get("ignore_status", False)
        original_return_st = internalkw.get("return_output", False)
        internalkw["ignore_status"] = True
        internalkw["return_output"] = False
        unit_name = constants.CONU_ARTIFACT_TAG + "unit_" + random_str()
        opts = ["-M", self.name, "--unit", unit_name]
        lpath = "/var/tmp/{}".format(unit_name)
        comout = {}
        if self._run_systemdrun_decide():
            add_wait_var = "--wait"
        else:
            # keep service exist after it finish, to be able to read exit code
            add_wait_var = "-r"
        if internal_background:
            add_wait_var = ""
        if add_wait_var:
            opts.append(add_wait_var)
        # TODO: behave move similar to run_cmd function, unable to work with clean subprocess objects because systemd-run
        # does not support return stderr, stdout, and return code directly
        # find way how to do this in better way, machinectl shell is not possible
        # https://github.com/systemd/systemd/issues/5879
        # https://github.com/systemd/systemd/issues/5878
        bashworkaround = [
            "/bin/bash", "-c", "({comm})>{path}.stdout 2>{path}.stderr".format(
                comm=" ".join(command), path=lpath)
        ]
        whole_cmd = ["systemd-run"] + opts + bashworkaround
        comout['command'] = command
        comout['return_code'] = run_cmd(whole_cmd, **internalkw) or 0
        if not internal_background:
            if not self._run_systemdrun_decide():
                comout['return_code'] = self._systemctl_wait_until_finish(
                    self.name, unit_name)
            if self.is_running():
                self.copy_from("{pin}.stdout".format(pin=lpath),
                               "{pin}.stdout".format(pin=lpath))
                with open("{pin}.stdout".format(pin=lpath)) as f:
                    comout['stdout'] = f.read()
                self.copy_from("{pin}.stderr".format(pin=lpath),
                               "{pin}.stderr".format(pin=lpath))
                with open("{pin}.stderr".format(pin=lpath)) as f:
                    comout['stderr'] = f.read()
            logger.debug(comout)
        if not original_ignore_st and comout['return_code'] != 0:
            raise subprocess.CalledProcessError(comout['command'], comout)
        if return_full_dict:
            return comout
        if original_return_st:
            return comout['stdout']
        else:
            return comout['return_code']