Create uninstaller.py
diff --git a/uninstaller.py b/uninstaller.py
new file mode 100644
index 0000000..01d0b84
--- /dev/null
+++ b/uninstaller.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+"""ASF Infra App uninstaller"""
+import sys
+import os
+import subprocess
+import typing
+
+programs_to_remove = ["kif", "loggy", "blocky"]
+
+debug_mode = len(sys.argv) == 2 and sys.argv[1] == "debug"
+systemctl = "/bin/systemctl"
+default_install_dir = "/usr/local/etc"
+
+systemd_paths = [
+ "/etc/systemd/system/",
+ "/usr/lib/systemd/system/",
+ "/lib/systemd/system/",
+ "/etc/init.d/",
+]
+
+
+def find_systemd_files(svcname: str) -> typing.List[str]:
+ """Finds all systemd/upstart files pertaining to a service and returns as a list"""
+ found_files = []
+ for path in systemd_paths:
+ upath = os.path.join(path, svcname)
+ dpath = os.path.join(path, svcname + ".service")
+ if os.path.exists(upath):
+ found_files.append(upath)
+ if os.path.exists(dpath):
+ found_files.append(dpath)
+ return found_files
+
+
+def print_line(txt: str):
+ sys.stdout.write("%-64s" % txt)
+ sys.stdout.flush()
+
+
+def uninstall_service(svcname: str):
+ """Uninstalls a service"""
+ print("-" * 64)
+ print("Uninstalling application %s..." % svcname)
+ print("-" * 64)
+ print_line("Stopping systemd service %s." % svcname)
+ if not debug_mode:
+ subprocess.check_call((systemctl, "stop", svcname))
+ print("[DONE]")
+
+ print_line("Disabling systemd service %s." % svcname)
+ if not debug_mode:
+ subprocess.check_call((systemctl, "disable", svcname))
+ print("[DONE]")
+
+ for filepath in find_systemd_files(svcname):
+ print_line("Removing init file %s" % filepath)
+ if not debug_mode:
+ os.unlink(filepath)
+ print("[DONE]")
+
+ print_line("Reloading systemd modules")
+ if not debug_mode:
+ subprocess.check_call((systemctl, "daemon-reload"))
+ print("[DONE]")
+
+ print_line("Resetting failed systemd paths")
+ if not debug_mode:
+ subprocess.check_call((systemctl, "reset-failed"))
+ print("[DONE]")
+
+ print("Removing application files")
+ installroot = os.path.join(default_install_dir, svcname)
+ if os.path.isdir(installroot):
+ print("Entering %s" % installroot)
+ for file in os.listdir(installroot):
+ fpath = os.path.join(installroot, file)
+ print_line("Removing %s" % fpath)
+ if not debug_mode:
+ os.unlink(fpath)
+ print("[DONE]")
+ print_line("Removing parent install dir %s" % installroot)
+ if not debug_mode:
+ os.rmdir(installroot)
+ print("[DONE]")
+ print("Service %s has been fully removed!" % svcname)
+ print("-" * 64)
+
+
+def main():
+ if debug_mode:
+ print("Debug mode enabled, not removing applications, just pretending.")
+ for program in programs_to_remove:
+ try:
+ subprocess.check_output(
+ (systemctl, "--no-pager", "status", program), stderr=subprocess.PIPE
+ )
+ has_service = True
+ except subprocess.CalledProcessError as e:
+ if e.returncode == 4: # No such service
+ has_service = False
+ else:
+ has_service = True
+ if has_service:
+ print("- %s is installed as systemd service, removing" % program)
+ uninstall_service(program)
+ else:
+ print("- %s is not installed as systemd service" % program)
+
+
+if __name__ == "__main__":
+ main()