2020-04-11 19:10:29 +00:00
|
|
|
"""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
|
2020-04-11 21:18:50 +00:00
|
|
|
from subprocess import call, check_output
|
2020-04-11 19:10:29 +00:00
|
|
|
|
2020-04-11 19:25:49 +00:00
|
|
|
from psutil import process_iter
|
|
|
|
|
2020-04-11 21:18:50 +00:00
|
|
|
from autonomic.config import INFRA_DIR
|
2020-04-11 19:10:29 +00:00
|
|
|
from autonomic.logger import log
|
|
|
|
from autonomic.yaml import yaml
|
|
|
|
|
|
|
|
|
2020-04-11 21:07:20 +00:00
|
|
|
def run(cmd, cwd=None, interactive=False, **kwargs):
|
2020-04-11 19:10:29 +00:00
|
|
|
"""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))
|
2020-04-11 21:07:20 +00:00
|
|
|
|
2020-04-11 19:10:29 +00:00
|
|
|
log.info("Running {}".format(" ".join(cmd)))
|
2020-04-11 21:07:20 +00:00
|
|
|
|
|
|
|
if interactive:
|
|
|
|
return call(cmd, **kwargs)
|
2020-04-11 21:18:50 +00:00
|
|
|
|
|
|
|
output = check_output(cmd, **kwargs)
|
|
|
|
return output.decode("utf-8")
|
2020-04-11 20:47:16 +00:00
|
|
|
except Exception as exception:
|
2020-04-11 19:10:29 +00:00
|
|
|
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))
|
2020-04-11 19:25:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
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
|
2020-04-11 20:47:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
def git_status(fpath):
|
|
|
|
"""Check if Git reports changes to be committed."""
|
|
|
|
cmd = ["git", "status", "--porcelain"]
|
|
|
|
output = run(cmd, cwd=fpath)
|
2020-04-11 21:07:20 +00:00
|
|
|
|
2020-04-11 21:19:00 +00:00
|
|
|
if output:
|
2020-04-11 20:47:16 +00:00
|
|
|
msg = "warning: git reports uncommitted changes in {}".format(fpath)
|
|
|
|
log.warning(msg)
|
|
|
|
log.warning(output)
|
2020-04-11 21:19:00 +00:00
|
|
|
else:
|
|
|
|
msg = "No unstaged changes found in {}".format(INFRA_DIR)
|
|
|
|
log.info(msg)
|