def get_file_creation_date(self, file_path, as_user=None): code, out, err = self.run(['stat', '--printf=%W', file_path], as_user=as_user) if code != 0 or not type_util.ll_int(out.strip()): raise IOError("Unable to read the file size: " + str(out) + ", " + str(err)) if int(out.strip()) == 0: code, out, err = self.run(['stat', '--printf=%Y', file_path], as_user=as_user) if code != 0 or not type_util.ll_int(out.strip()): raise IOError("Unable to read the file size: " + str(out) + ", " + str(err)) return datetime.datetime.utcfromtimestamp(int(out.strip()))
def ensure_stop_proc(proc, timeout=30): """ Ask gracefully a process to stop. If it doesn't we kill it and all it's children (vengeance !!!!) If timeout is 0 or None, we wait forever :param proc: The process to stop, a pid or a subprocess :type proc: subprocess.Popen|int :param timeout: The amount of time (in second) we wait before killing the process. Optional, default 30 :type timeout: int|float|datetime.timedelta|None :return: True if the process stopped gracefully, False if we had to kill it :rtype: bool """ if type_util.ll_int(proc): try: os.kill(int(proc), signal.SIGINT) os.kill(int(proc), signal.SIGTERM) except OSError: return True # The process should have stopped else: proc.terminate() try: wait_for_proc(proc, timeout) return True except OSError: return True except util.TimeoutError: ensure_kill_proc(proc) return False
def get_file_size(self, file_path, as_user=None): code, out, err = self.run(['stat', '--printf=%s', file_path], as_user=as_user) if code != 0 or not type_util.ll_int(out.strip()): raise IOError("Unable to read the file size: " + str(out) + ", " + str(err)) return int(out.strip())
def to_dt(var): if var is None: return None if isinstance(var, datetime.datetime): if var.tzinfo is None or var.tzinfo.utcoffset(var) is None: return var.replace(tzinfo=None) return var if type_util.ll_int(var) or type_util.ll_float(var): return dt_to_timestamp(var) return dateutil.parser.parse(str(var))
def is_zombie(proc): """ Check a process if it's a zombie (and try to clean it :param proc: The process to stop, a pid or a subprocess :type proc: subprocess.Popen|int :return: True if the process is a zombie :rtype: bool """ pid = int(proc) if type_util.ll_int(proc) else proc.pid try: dead = os.waitpid(pid, os.WNOHANG)[0] except OSError: return False return bool(dead)
def is_process_running(proc): """ Check for the existence of a unix process :param proc: The process to stop, a pid or a subprocess :type proc: subprocess.Popen|int :return: True if the process is still running :rtype: bool """ if hasattr(proc, "is_running"): return proc.is_running() pid = int(proc) if type_util.ll_int(proc) else proc.pid try: os.kill(int(pid), 0) return not is_zombie(proc) except OSError as e: if e.errno == 3: # process is dead return False else: raise
def wait_for_proc(proc, timeout): """ Wait for a process to finish with a timeout. If timeout is reached before the process stopped, it raise a TimeoutError If timeout is 0 or None, we wait forever :param proc: The process we are waiting for, a pid or a subprocess :type proc: subprocess.Popen|int :param timeout: The number of seconds we wait before throwing the exception :type timeout: float|int|datetime.timedelta|None """ with util.using_timeout(timeout): if type_util.ll_int(proc): try: os.waitpid(int(proc), 0) except OSError: return else: proc.wait() if is_process_running(proc): raise util.TimeoutError()
def ensure_kill_proc(proc): """ Kill a processus and all it's children :param proc: The process to stop, a pid or a subprocess :type proc: subprocess.Popen|int """ if type_util.ll_int(proc): proc_pid = int(proc) else: proc_pid = proc.pid if proc.poll() is None: proc.kill() if is_process_running(proc): try: if hasattr(proc, "is_distant") and proc.is_distant(): proc.kill() else: os.killpg(proc_pid, signal.SIGKILL) except OSError: pass # The process may stopped between the two calls