#!/usr/bin/python3 # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab import sys import os import re import pwd import grp import subprocess import json import jinja2 SETTINGS_PATH = "settings.json" SYSTEMD_TEMPLATE = "systemd/webtemplate.service.jinja2" FLASK_TEMPLATE = "flask/main.py.jinja2" REPOSITORY_WEBROOT = "webroot" def read_settings(): """Read the SETTINGS_PATH File and return a Dictionary with its Content""" with open(SETTINGS_PATH, "r") as settings: settings = settings.read() settings = json.loads(settings) # check for valid project name if not re.match(r"\A[a-z]+\Z", settings["project_name"]): print("Please provide a project_name in settings.json containing only characters from a to z in lower case") sys.exit(1) # check for valid project description if not re.match(r"\A[a-z|A-Z|0-9| ]+\Z", settings["project_description"]): print("Please provide a project description in settings.json containing only characters from a to z and numbers") sys.exit(1) # check for valid webroot path if not re.match(r"\A(/[a-z|A-Z|0-9|_|-|\.]*)+\Z", settings["webroot"]): print("Please select an absolute and valid path as webroot in settings.json") sys.exit(1) # check for valid framework selection if not settings["framework"] in [None, "flask", "actix"]: print("Unknown framework in settings.json") sys.exit(1) # check for valid framework port if not int(settings["framework_port"]) >= 1: print("Please select a valid framework_port in settings.json") sys.exit(1) # check for valid framework bind address if not re.match(r"\A([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])(\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])){3}\Z", settings["framework_bind"]): print("Please provide a valid IP address as framework_bind in settings.json") sys.exit(1) # check for valid user users = [] for user in pwd.getpwall(): users.append(user[0]) # append just the name if not settings["user"] in users: print("User '{}' does not exist on this system. Please select a valid user in settings.json".format(settings["user"])) sys.exit(1) # check for valid group groups = [] for group in grp.getgrall(): groups.append(group[0]) # append just the name if not settings["group"] in groups: print("Group '{}' does not exist on this system. Please select a valid group in settings.json".format(settings["group"])) sys.exit(1) return settings def build_systemd_file(settings): """Generate Systemd Unit File with Settings from SETTINGS_PATH""" with open(SYSTEMD_TEMPLATE, "r") as template: template = template.read() template = jinja2.Template(template) systemd_file = template.render(settings) subprocess.call("mkdir -p systemd/build", shell=True) file_path = "systemd/build/{}.service".format(settings["project_name"]) with open(file_path, "w") as _file: _file.write(systemd_file) def build_flask(settings): """Generate Python Flask File with Settings from SETTINGS_PATH""" with open(FLASK_TEMPLATE, "r") as template: template = template.read() template = jinja2.Template(template) flask_file = template.render(settings) subprocess.call("mkdir -p flask/build", shell=True) file_path = "flask/build/{}".format(settings["project_name"]) with open(file_path, "w") as _file: _file.write(flask_file) def install_webroot(settings): """Install every File from the Repositories Webroot to the Systems Webroot""" for directory, subdirs, files in os.walk(REPOSITORY_WEBROOT, topdown=False): for _file in files: path_to_file = os.path.join(directory, _file) relative_path = os.path.relpath(path_to_file, REPOSITORY_WEBROOT) target_path = os.path.join(settings["webroot"], relative_path) subprocess.run("install -Dm 644 {} {}".format(path_to_file, target_path), shell=True) def uninstall_webroot(settings): """Uninstalls every File from the Systems Webroot""" path_to_delete = os.path.join(settings["webroot"], "*") subprocess.run("rm -rf {}".format(path_to_delete), shell=True) def install_flask(settings): """Install the Executable for the Dynamic Web Server""" subprocess.call("sudo mkdir -p /opt/{}".format(settings["project_name"]), shell=True) subprocess.call("sudo install -Dm 744 flask/build/{0} /opt/{0}/{0}".format(settings["project_name"]), shell=True) order = "sudo find /opt/{0} -exec chown -R {1}:{2}".format( settings["project_name"], settings["user"], settings["group"] ) order += " {} \;" subprocess.call(order, shell=True) def uninstall_flask(settings): """Uninstall the Executable for the Dynamic Web Server""" subprocess.call("sudo rm -rf /opt/{}".format(settings["project_name"]), shell=True) def install_systemd_file(settings): """Install the Systemd Unit for launching the dynamic Web Server""" if settings["framework"] != None: subprocess.call("sudo install -Dm 644 systemd/build/{0}.service /etc/systemd/system/{0}.service".format(settings["project_name"]), shell=True) subprocess.call("sudo systemctl daemon-reload", shell=True) def uninstall_systemd_file(settings): """Uninstall the Systemd Unit for launching the dynamic Web Server""" if settings["framework"] != None: subprocess.call("sudo rm /etc/systemd/system/{0}.service".format(settings["project_name"]), shell=True) def main(): """The main Function""" settings = read_settings() # get settings from SETTINGS_PATH # just one argument is allowed: if len(sys.argv) != 2: print("Provide exactly one parameter") sys.exit(1) # execute given command command = sys.argv[1] if command == "build_systemd_file": build_systemd_file(settings) elif command == "build_framework": if settings["framework"] == "flask": build_flask(settings) elif settings["framework"] == "actix-web": print("actix-web is not yet implemented ...") sys.exit(1) elif settings["framework"] == None: pass else: print("Unknown web framework selected") sys.exit(1) elif command == "install_webroot": install_webroot(settings) elif command == "uninstall_webroot": uninstall_webroot(settings) elif command == "install_framework": if settings["framework"] == "flask": install_flask(settings) elif settings["framework"] == "actix-web": print("actix-web is not yet implemented ...") sys.exit(1) elif settings["framework"] == None: pass else: print("Unknown web framework selected") sys.exit(1) elif command == "uninstall_framework": if settings["framework"] == "flask": uninstall_flask(settings) elif settings["framework"] == "actix-web": print("actix-web is not yet implemented ...") sys.exit(1) elif settings["framework"] == None: pass else: print("Unknown web framework selected") sys.exit(1) elif command == "install_systemd_file": install_systemd_file(settings) elif command == "uninstall_systemd_file": uninstall_systemd_file(settings) else: print("Unknown command") sys.exit(1) if __name__ == "__main__": main()