Skip to content

Instantly share code, notes, and snippets.

@andreasf
Last active July 8, 2022 02:07
Show Gist options
  • Save andreasf/10551864 to your computer and use it in GitHub Desktop.
Save andreasf/10551864 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""
sctl -- a systemctl wrapper that provides instant feedback
"""
import sys
import subprocess
import os
import time
NUM_LOG_LINES = 5
SHOW_DESCRIPTION = True
WAIT_FOR_ERROR_SECONDS = 0.2
EXPECT_ACTIVE = ("start", "reload", "restart")
EXPECT_INACTIVE = ("stop", "kill")
SUPPORTS_COLOR = ("xterm", "xterm-256color", "vt100", "vt102")
def run_verbose(cmd, unit):
pre_status = get_status(unit)
ret = subprocess.call(["systemctl"] + sys.argv[1:])
if ret != 0:
sys.exit(ret)
time.sleep(WAIT_FOR_ERROR_SECONDS)
post_status = get_status(unit)
active = post_status["ActiveState"] == "active"
failed = post_status["ActiveState"] == "failed"
expect_active = cmd in EXPECT_ACTIVE
ok = (not failed and active == expect_active)
if SHOW_DESCRIPTION:
print "%s %s: %s" % (cmd, pre_status["Id"], pre_status["Description"])
print "%s %s (%s) -> %s (%s)" % (ok_fail(ok), pre_status["ActiveState"],
pre_status["SubState"], post_status["ActiveState"],
post_status["SubState"])
if not ok:
subprocess.call(["journalctl", "--quiet", "--lines",
str(NUM_LOG_LINES),
"_SYSTEMD_UNIT=%s" % pre_status["Id"]])
sys.exit(1)
def ok_fail(some_bool):
color = False
if "TERM" in os.environ and os.environ["TERM"] in SUPPORTS_COLOR:
color = True
if some_bool and color:
return "[ \033[92mOK\033[0m ]"
elif some_bool:
return "[ OK ]"
elif color:
return "[ \033[91mFAIL\033[0m ]"
else:
return "[ FAIL ]"
def get_status(unit):
show = subprocess.check_output(["systemctl", "show", unit]).splitlines()
show = map(lambda x: x.rsplit("=", 1), show)
return dict(show)
def main():
cmds = EXPECT_ACTIVE + EXPECT_INACTIVE
for i in range(1, len(sys.argv)):
if sys.argv[i] in cmds:
run_verbose(sys.argv[i], sys.argv[i+1])
return
subprocess.call(["systemctl"] + sys.argv[1:])
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment