Beispiel #1
0
def _create_dasd_part(dev, size):
    """
    This method creates a DASD partition
    :param dev: name of DASD device for creation of partition
    :param size: block size
    :return:
    """
    devname = '/dev/' + dev
    device = PDevice(devname)
    disk = PDisk(device)
    num_parts = len(disk.partitions)
    if num_parts == 3:
        raise OperationFailed("GINDASDPAR0016E")

    def kill_proc(proc, timeout_flag):
        try:
            parent = psutil.Process(proc.pid)
            for child in parent.get_children(recursive=True):
                child.kill()
            # kill the process after no children is left
            proc.kill()
        except OSError:
            pass
        else:
            timeout_flag[0] = True

    dasd_devs = _get_dasd_names()
    if dev not in dasd_devs:
        raise NotFoundError("GINDASDPAR0012E", {'name': dev})
    p_str = _form_part_str(size)
    try:
        p1_out = subprocess.Popen(["echo", "-e", "\'", p_str, "\'"],
                                  stdout=subprocess.PIPE)
        p2_out = subprocess.Popen(["fdasd", devname],
                                  stdin=p1_out.stdout,
                                  stderr=subprocess.PIPE,
                                  stdout=subprocess.PIPE)
        p1_out.stdout.close()
        timeout = 2.0
        timeout_flag = [False]
        timer = Timer(timeout, kill_proc, [p2_out, timeout_flag])
        timer.setDaemon(True)
        timer.start()
        out, err = p2_out.communicate()
        if timeout_flag[0]:
            msg_args = {'cmd': "fdasd " + devname, 'seconds': str(timeout)}
            raise TimeoutExpired("WOKUTILS0002E", msg_args)
        if p2_out.returncode != 0:
            if 'error while rereading partition table' in err.lower():
                run_command(["partprobe", devname, "-s"])
            else:
                raise OperationFailed("GINDASDPAR0007E", {
                    'name': devname,
                    'err': err
                })
    except TimeoutExpired:
        raise
    finally:
        if timer and not timeout_flag[0]:
            timer.cancel()
Beispiel #2
0
    def wait(self, id, timeout=10):
        """Wait for a task until it stops running (successfully or due to
        an error). If the Task finishes its execution before <timeout>, this
        function returns normally; otherwise an exception is raised.

        Parameters:
        id -- The Task ID.
        timeout -- The maximum time, in seconds, that this function should wait
            for the Task. If the Task runs for more than <timeout>,
            "TimeoutExpired" is raised.
        """
        for i in range(0, timeout):
            with self.objstore as session:
                task = session.get('task', str(id))

            if task['status'] != 'running':
                return

            time.sleep(1)

        raise TimeoutExpired('WOKASYNC0003E', {'seconds': timeout,
                                               'task': task['target_uri']})
Beispiel #3
0
def run_command(cmd, timeout=None, silent=False):
    """
    cmd is a sequence of command arguments.
    timeout is a float number in seconds.
    timeout default value is None, means command run without timeout.
    silent is bool, it will log errors using debug handler not error.
    silent default value is False.
    """

    # subprocess.kill() can leave descendants running
    # and halting the execution. Using psutil to
    # get all descendants from the subprocess and
    # kill them recursively.
    def kill_proc(proc, timeout_flag):
        try:
            parent = psutil.Process(proc.pid)
            for child in parent.get_children(recursive=True):
                child.kill()
            # kill the process after no children is left
            proc.kill()
        except OSError:
            pass
        else:
            timeout_flag[0] = True

    proc = None
    timer = None
    timeout_flag = [False]

    try:
        proc = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        if timeout is not None:
            timer = Timer(timeout, kill_proc, [proc, timeout_flag])
            timer.setDaemon(True)
            timer.start()

        out, error = proc.communicate()
        wok_log.debug("Run command: '%s'", " ".join(cmd))

        if out:
            wok_log.debug("out:\n%s", out)

        if proc.returncode != 0:
            msg = "rc: %s error: %s returned from cmd: %s" %\
                  (proc.returncode, error, ' '.join(cmd))

            if silent:
                wok_log.debug(msg)

            else:
                wok_log.error(msg)
        elif error:
            wok_log.debug("error: %s returned from cmd: %s", error,
                          ' '.join(cmd))

        if timeout_flag[0]:
            msg = ("subprocess is killed by signal.SIGKILL for "
                   "timeout %s seconds" % timeout)
            wok_log.error(msg)

            msg_args = {'cmd': " ".join(cmd), 'seconds': str(timeout)}
            raise TimeoutExpired("WOKUTILS0002E", msg_args)

        return out, error, proc.returncode
    except TimeoutExpired:
        raise
    except OSError as e:
        msg = "Impossible to execute '%s'" % ' '.join(cmd)
        wok_log.debug("%s", msg)

        return None, "%s %s" % (msg, e), -1
    except Exception as e:
        msg = "Failed to run command: %s." % " ".join(cmd)
        msg = msg if proc is None else msg + "\n  error code: %s."
        wok_log.error("%s %s", msg, e)

        if proc:
            return out, error, proc.returncode
        else:
            return None, msg, -1
    finally:
        if timer and not timeout_flag[0]:
            timer.cancel()
Beispiel #4
0
def run_command(cmd, timeout=None, silent=False, tee=None,
                env_vars=None):
    """
    cmd is a sequence of command arguments.
    timeout is a float number in seconds.
    timeout default value is None, means command run without timeout.
    silent is bool, it will log errors using debug handler not error.
    silent default value is False.
    tee is a file path to store the output of the command, like 'tee' command.
    tee default value is None, means output will not be logged.
    """
    # subprocess.kill() can leave descendants running
    # and halting the execution. Using psutil to
    # get all descendants from the subprocess and
    # kill them recursively.
    def kill_proc(proc, timeout_flag):
        try:
            parent = psutil.Process(proc.pid)
            for child in parent.get_children(recursive=True):
                child.kill()
            # kill the process after no children is left
            proc.kill()
        except OSError:
            pass
        else:
            timeout_flag[0] = True

    # function to append the given msg into the log_file
    def tee_log(msg=None, log_file=None):
        if (msg is None) or (log_file is None):
            return

        try:
            f = open(log_file, 'a')
        except IOError as e:
            msg = "Failed to open file %s: " % log_file
            wok_log.error("%s %s", msg, e)
            return
        msg += '\n'
        try:
            f.write(msg)
        except TypeError:
            f.write(msg.encode('utf_8'))
        f.close()

    proc = None
    timer = None
    timeout_flag = [False]

    if env_vars is None:
        env_vars = os.environ.copy()
        env_vars['LC_ALL'] = 'C'
    elif env_vars.get('LC_ALL') is None:
        env_vars['LC_ALL'] = 'C'

    try:
        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE, env=env_vars)
        if timeout is not None:
            timer = Timer(timeout, kill_proc, [proc, timeout_flag])
            timer.setDaemon(True)
            timer.start()

        wok_log.debug("Run command: '%s'", " ".join(cmd))
        if tee is not None:
            if os.path.exists(tee):
                os.remove(tee)
            output = []
            while True:
                line = ""
                try:
                    line = proc.stdout.readline()
                    line = line.decode('utf_8')
                except Exception:
                    type, e, tb = sys.exc_info()
                    wok_log.error(e)
                    wok_log.error("The output of the command could not be "
                                  "decoded as %s\ncmd: %s\n line ignored: %s" %
                                  ('utf_8', cmd, repr(line)))
                    pass

                output.append(line)
                if not line:
                    break
                line = line.rstrip('\n\r')
                tee_log(line, tee)
            out = ''.join(output)
            error = proc.stderr.read()
            returncode = proc.poll()
        else:
            out, error = proc.communicate()

        if out:
            wok_log.debug("out:\n%s", out)

        returncode = proc.returncode
        if returncode != 0:
            msg = "rc: %s error: %s returned from cmd: %s" %\
                  (returncode, error, ' '.join(cmd))

            if silent:
                wok_log.debug(msg)

            else:
                wok_log.error(msg)
        elif error:
            wok_log.debug("error: %s returned from cmd: %s",
                          error, ' '.join(cmd))

        if timeout_flag[0]:
            msg = ("subprocess is killed by signal.SIGKILL for "
                   "timeout %s seconds" % timeout)
            wok_log.error(msg)

            msg_args = {'cmd': " ".join(cmd), 'seconds': str(timeout)}
            raise TimeoutExpired("WOKUTILS0002E", msg_args)

        return out, error, returncode
    except TimeoutExpired:
        raise
    except OSError as e:
        msg = "Impossible to execute '%s'" % ' '.join(cmd)
        wok_log.debug("%s", msg)

        return None, "%s %s" % (msg, e), -1
    except Exception as e:
        msg = "Failed to run command: %s." % " ".join(cmd)
        msg = msg if proc is None else msg + "\n  error code: %s."
        wok_log.error("%s %s", msg, e)

        if proc:
            return out, error, proc.returncode
        else:
            return None, msg, -1
    finally:
        if timer and not timeout_flag[0]:
            timer.cancel()
Beispiel #5
0
def run_command(cmd, timeout=None, silent=False, out_cb=None, env_vars=None):
    """
    cmd is a sequence of command arguments.
    timeout is a float number in seconds.
    timeout default value is None, means command run without timeout.
    silent is bool, it will log errors using debug handler not error.
    silent default value is False.
    out_cb is a callback that receives the whole command output every time a
    new line is thrown by command. Default value is None, meaning that whole
    output will be returned at the end of execution.

    Returns a tuple (out, error, returncode) where:
    out is the output thrown by command
    error is an error message if applicable
    returncode is an integer equal to the result of command execution
    """
    proc = None
    timer = None
    timeout_flag = [False]

    if env_vars is None:
        env_vars = os.environ.copy()
        env_vars['LC_ALL'] = 'en_US.UTF-8'
    elif env_vars.get('LC_ALL') is None:
        env_vars['LC_ALL'] = 'en_US.UTF-8'

    try:
        proc = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                env=env_vars)
        if timeout is not None:
            timer = _set_timer(proc, timeout, timeout_flag)

        wok_log.debug(f"Run command: {' '.join(cmd)}")
        if out_cb is not None:
            output = _get_cmd_output(proc, out_cb)
            out = ''.join(output)
            error = proc.stderr.read()
            returncode = proc.poll()
        else:
            out, error = proc.communicate()
            returncode = proc.returncode

        if out:
            wok_log.debug(f'out:\n{out}')

        if returncode != 0:
            msg = (f'rc: {returncode} error: {decode_value(error)} returned '
                   f"from cmd: {decode_value(' '.join(cmd))}")

            if silent:
                wok_log.debug(msg)

            else:
                wok_log.error(msg)
                if out_cb is not None:
                    out_cb(msg)
        elif error:
            wok_log.debug(f'error: {decode_value(error)} returned from cmd: '
                          f"{decode_value(' '.join(cmd))}")

        if timeout_flag[0]:
            msg = (f'subprocess is killed by signal.SIGKILL for '
                   f'timeout {timeout} seconds')
            wok_log.error(msg)

            msg_args = {'cmd': ' '.join(cmd), 'seconds': str(timeout)}
            raise TimeoutExpired('WOKUTILS0002E', msg_args)

        return out.decode('utf-8'), error, returncode
    except TimeoutExpired:
        raise
    except OSError as e:
        msg = f"Impossible to execute {' '.join(cmd)}"
        wok_log.debug(msg)

        return None, f'{msg} {e}', -1
    except Exception as e:
        msg = f"Failed to run command: {b' '.join(cmd)}."
        msg = msg if proc is None else msg + f'\n  error code: {e}.'
        wok_log.error(msg)

        if proc:
            return out.decode('utf-8'), error, proc.returncode
        else:
            return None, msg, -1
    finally:
        if timer and not timeout_flag[0]:
            timer.cancel()
Beispiel #6
0
def run_command(cmd, timeout=None, silent=False, out_cb=None, env_vars=None):
    """
    cmd is a sequence of command arguments.
    timeout is a float number in seconds.
    timeout default value is None, means command run without timeout.
    silent is bool, it will log errors using debug handler not error.
    silent default value is False.
    out_cb is a callback that receives the whole command output every time a
    new line is thrown by command. Default value is None, meaning that whole
    output will be returned at the end of execution.

    Returns a tuple (out, error, returncode) where:
    out is the output thrown by command
    error is an error message if applicable
    returncode is an integer equal to the result of command execution
    """

    # subprocess.kill() can leave descendants running
    # and halting the execution. Using psutil to
    # get all descendants from the subprocess and
    # kill them recursively.
    def kill_proc(proc, timeout_flag):
        try:
            parent = psutil.Process(proc.pid)
            for child in parent.get_children(recursive=True):
                child.kill()
            # kill the process after no children is left
            proc.kill()
        except OSError:
            pass
        else:
            timeout_flag[0] = True

    proc = None
    timer = None
    timeout_flag = [False]

    if env_vars is None:
        env_vars = os.environ.copy()
        env_vars['LC_ALL'] = 'en_US.UTF-8'
    elif env_vars.get('LC_ALL') is None:
        env_vars['LC_ALL'] = 'en_US.UTF-8'

    try:
        proc = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                env=env_vars)
        if timeout is not None:
            timer = Timer(timeout, kill_proc, [proc, timeout_flag])
            timer.setDaemon(True)
            timer.start()

        wok_log.debug("Run command: '%s'", " ".join(cmd))
        if out_cb is not None:
            output = []
            while True:
                line = ""
                try:
                    line = proc.stdout.readline()
                    line = line.decode('utf_8')
                except Exception:
                    type, e, tb = sys.exc_info()
                    wok_log.error(e)
                    wok_log.error("The output of the command could not be "
                                  "decoded as %s\ncmd: %s\n line ignored: %s" %
                                  ('utf_8', cmd, repr(line)))
                    pass

                output.append(line)
                if not line:
                    break
                out_cb(''.join(output))
            out = ''.join(output)
            error = proc.stderr.read()
            returncode = proc.poll()
        else:
            out, error = proc.communicate()

        if out:
            wok_log.debug("out:\n%s", out)

        returncode = proc.returncode
        if returncode != 0:
            msg = "rc: %s error: %s returned from cmd: %s" %\
                  (returncode, decode_value(error),
                   decode_value(' '.join(cmd)))

            if silent:
                wok_log.debug(msg)

            else:
                wok_log.error(msg)
                if out_cb is not None:
                    out_cb(msg)
        elif error:
            wok_log.debug("error: %s returned from cmd: %s",
                          decode_value(error), decode_value(' '.join(cmd)))

        if timeout_flag[0]:
            msg = ("subprocess is killed by signal.SIGKILL for "
                   "timeout %s seconds" % timeout)
            wok_log.error(msg)

            msg_args = {'cmd': " ".join(cmd), 'seconds': str(timeout)}
            raise TimeoutExpired("WOKUTILS0002E", msg_args)

        return out, error, returncode
    except TimeoutExpired:
        raise
    except OSError as e:
        msg = "Impossible to execute '%s'" % ' '.join(cmd)
        wok_log.debug("%s", msg)

        return None, "%s %s" % (msg, e), -1
    except Exception as e:
        msg = "Failed to run command: %s." % " ".join(cmd)
        msg = msg if proc is None else msg + "\n  error code: %s."
        wok_log.error("%s %s", msg, e)

        if proc:
            return out, error, proc.returncode
        else:
            return None, msg, -1
    finally:
        if timer and not timeout_flag[0]:
            timer.cancel()