Ejemplo n.º 1
0
def run_cmd(cmd, **kwargs):
    """
    Run an arbitrary command locally

    Args:
        cmd (str): command to run

    Raises:
        CommandFailed: In case the command execution fails

    Returns:
        (str) Decoded stdout of command

    """
    log.info(f"Executing command: {cmd}")
    if isinstance(cmd, str):
        cmd = shlex.split(cmd)
    r = subprocess.run(cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       stdin=subprocess.PIPE,
                       **kwargs)
    log.debug(f"CMD output: {r.stdout.decode()}")
    if r.stderr:
        log.error(f"CMD error:: {r.stderr.decode()}")
    if r.returncode:
        raise CommandFailed(f"Error during execution of command: {cmd}")
    return r.stdout.decode()
Ejemplo n.º 2
0
    def create(self, yaml_file=None, resource_name='', out_yaml_format=True):
        """
        Creates a new resource

        Args:
            yaml_file (str): Path to a yaml file to use in 'oc create -f
                file.yaml
            resource_name (str): Name of the resource you want to create
            out_yaml_format (bool): Determines if the output should be
                formatted to a yaml like string

        Returns:
            dict: Dictionary represents a returned yaml file
        """
        if not (yaml_file or resource_name):
            raise CommandFailed(
                "At least one of resource_name or yaml_file have to "
                "be provided")
        command = "create "
        if yaml_file:
            command += f"-f {yaml_file}"
        elif resource_name:
            # e.g "oc namespace my-project"
            command += f"{self.kind} {resource_name}"
        if out_yaml_format:
            command += " -o yaml"

        return self.exec_oc_cmd(command)
Ejemplo n.º 3
0
    def exec_ceph_cmd(self, ceph_cmd, format='json-pretty'):
        """
        Execute a Ceph command on the Ceph tools pod

        Args:
            ceph_cmd (str): The Ceph command to execute on the Ceph tools pod
            format (str): The returning output format of the Ceph command

        Returns:
            dict: Ceph command output

        Raises:
            CommandFailed: In case the pod is not a toolbox pod
        """
        if 'rook-ceph-tools' not in self.labels.values():
            raise CommandFailed(
                "Ceph commands can be executed only on toolbox pod"
            )
        ceph_cmd = ceph_cmd
        if format:
            ceph_cmd += f" --format {format}"
        out = self.exec_cmd_on_pod(ceph_cmd)

        # For some commands, like "ceph fs ls", the returned output is a list
        if isinstance(out, list):
            return [item for item in out if item]
        return out
Ejemplo n.º 4
0
    def delete(self, yaml_file=None, resource_name='', wait=True):
        """
        Deletes a resource

        Args:
            yaml_file (str): Path to a yaml file to use in 'oc delete -f
                file.yaml
            resource_name (str): Name of the resource you want to delete
            wait (bool): Determines if the delete command should wait to
                completion

        Returns:
            dict: Dictionary represents a returned yaml file

        Raises:
            CommandFailed: In case yaml_file and resource_name wasn't provided
        """
        if not (yaml_file or resource_name):
            raise CommandFailed(
                "At least one of resource_name or yaml_file have to "
                "be provided")

        command = f"delete "
        if resource_name:
            command += f"{self.kind} {resource_name}"
        else:
            command += f"-f {yaml_file}"
        # oc default for wait is True
        if not wait:
            command += " --wait=false"
        return self.exec_oc_cmd(command)
Ejemplo n.º 5
0
    def run(self, podname, namespace, cmd_obj):
        resp = None
        stdout = None
        stderr = None
        ret = None

        try:
            resp = self.api.read_namespaced_pod(name=podname,
                                                namespace=namespace)
            logger.info(resp)
        except ApiException as ex:
            if ex.status != 404:
                logger.error("Unknown error: %s" % ex)

        # run command in bash
        bash = ['/bin/bash']
        resp = stream(self.api.connect_get_namespaced_pod_exec,
                      podname,
                      namespace,
                      command=bash,
                      stderr=True,
                      stdin=True,
                      stdout=True,
                      tty=False,
                      _preload_content=False)
        done = False
        outbuf = ''
        while resp.is_open():
            resp.update(timeout=1)
            if resp.peek_stdout():
                stdout = resp.read_stdout(timeout=cmd_obj.timeout)
                outbuf = outbuf + stdout
                if cmd_obj.long_running:
                    while resp.peek_stdout(timeout=cmd_obj.timeout):
                        stdout = resp.read_stdout(timeout=cmd_obj.timeout)
                        outbuf = outbuf + stdout
            if resp.peek_stderr():
                stderr = resp.read_stderr(timeout=60)
            if not done:
                resp.write_stdin(cmd_obj.cmd)
                resp.write_stdin('\n')
                done = True
            else:
                break
        """
        Couple of glitches in capturing return value.
        Rest api doesn't return ret value of the command
        hence this workaround.
        we can fix this once we have facility to capture err code
        """
        if cmd_obj.check_ec:
            resp.write_stdin("echo $?\n")
            try:
                ret = int(resp.readline_stdout(timeout=5))
            except (ValueError, TypeError):
                logger.error(
                    f"TimeOut: Command timedout after {cmd_obj.timeout}")
                raise CommandFailed(f"Failed to run \"{cmd_obj.cmd}\"")
            finally:
                resp.close()

        if outbuf:
            stdout = outbuf

        return stdout, stderr, ret