"""Utility functions. While mostly a vague concept and sometimes a bad idea, the utilities module is somewhere where reusable system related, data processing and other general functions can live. This codebase seems to have a few of those, so it seems like a necessary module. Let us be critical of our requirements when adding things here. """ from os import chdir from subprocess import check_output from psutil import process_iter from autonomic.logger import log from autonomic.yaml import yaml def run(cmd, cwd=None, **kwargs): """Run a system command. Please note, all **kwargs will be passed into the check_output command so that system call customisation can happen. Please name your keyword arguments (like `cwd`) if you intend that they are used for other logic. """ try: if cwd: chdir(cwd) log.info("Changed directory to {}".format(cwd)) log.info("Running {}".format(" ".join(cmd))) return check_output(cmd, **kwargs) except Exception as exception: msg = "{} failed! Saw {}".format(" ".join(cmd), str(exception)) exit(msg) def exit(msg, code=1): """Exit and log appropriate level.""" if code != 0: log.critical(msg) else: log.info(msg) exit(code) def qlist(name, message, choices): """A question in list format.""" return [ { "type": "list", "name": name, "message": message, "choices": choices, "filter": lambda answer: answer.lower(), } ] def yaml_load(fpath): """Load a YAML file.""" try: with open(fpath, "r") as handle: return yaml.load(handle.read()) except Exception as exception: log.error(str(exception)) def yaml_dump(fpath, data): """Dump a YAML file.""" try: with open(fpath, "w") as handle: yaml.dump(data, handle) except Exception as exception: log.error(str(exception)) def is_proc(name): """Determine if a process is running or not.""" for process in process_iter(): try: if name.lower() in process.name().lower(): return True except Exception: pass return False def git_status(fpath): """Check if Git reports changes to be committed.""" cmd = ["git", "status", "--porcelain"] output = run(cmd, cwd=fpath) if output is not None: msg = "warning: git reports uncommitted changes in {}".format(fpath) log.warning(msg) log.warning(output)