From cf7dda816cdff4aa7ce21a884b091b0ab2ce0beb Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Thu, 16 Jan 2020 17:14:42 -0800 Subject: [PATCH] improvements to config services, start/stop/validate basics, abc levergae to enforce definitions for custom services --- daemon/core/configservice/base.py | 89 ++++++++++++++----- .../configservices/defaultroute/service.py | 5 +- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/daemon/core/configservice/base.py b/daemon/core/configservice/base.py index 46990333..dd0ceb60 100644 --- a/daemon/core/configservice/base.py +++ b/daemon/core/configservice/base.py @@ -37,12 +37,17 @@ class ConfigService(abc.ABC): @property @abc.abstractmethod - def name(self): + def name(self) -> str: raise NotImplementedError @property @abc.abstractmethod - def group(self): + def group(self) -> str: + raise NotImplementedError + + @property + @abc.abstractmethod + def directories(self) -> List[str]: raise NotImplementedError @property @@ -76,8 +81,49 @@ class ConfigService(abc.ABC): raise NotImplementedError def start(self) -> None: - if not self.startup: - return + self.create_dirs() + self.create_files() + self.run_startup() + self.run_validation() + + def stop(self) -> None: + for cmd in self.shutdown: + try: + self.node.cmd(cmd) + except CoreCommandError: + logging.exception( + f"node({self.node.name}) service({self.name}) " + f"failed shutdown: {cmd}" + ) + + def restart(self) -> None: + self.stop() + self.start() + + def create_dirs(self) -> None: + for directory in self.directories: + try: + self.node.privatedir(directory) + except (CoreCommandError, ValueError): + raise CoreError( + f"node({self.node.name}) service({self.name}) " + f"failure to create service directory: {directory}" + ) + + def create_files(self) -> None: + raise NotImplementedError + + def run_startup(self) -> None: + for cmd in self.startup: + try: + self.node.cmd(cmd) + except CoreCommandError: + raise CoreError( + f"node({self.node.name}) service({self.name}) " + f"failed startup: {cmd}" + ) + + def run_validation(self) -> None: wait = self.validation_mode == ConfigServiceMode.BLOCKING start = time.monotonic() index = 0 @@ -89,40 +135,35 @@ class ConfigService(abc.ABC): del cmds[index] index += 1 except CoreCommandError: - logging.exception("error starting command") + logging.debug( + f"node({self.node.name}) service({self.name}) " + f"validate command failed: {cmd}" + ) time.sleep(self.validation_period) if time.monotonic() - start > 0: raise CoreError( - f"node({self.node.name}) service({self.name()}) failed to start" + f"node({self.node.name}) service({self.name}) " + f"failed to validate" ) - def stop(self) -> None: - if not self.shutdown: - return - for cmd in self.shutdown: - self.node.cmd(cmd, wait=False) - - def restart(self): - self.stop() - self.start() - - def run(self, cmd: str, wait: bool = True): - self.node.cmd(cmd, wait) - - def create_files(self) -> None: - raise NotImplementedError - def render(self, name: str, data: Dict[str, Any] = None) -> None: if data is None: data = {} try: template = self.templates.get_template(name) rendered = template.render_unicode(node=self.node, **data) - print(rendered) + logging.info( + "node(%s) service(%s) template(%s): \n%s", + self.node.name, + self.name, + name, + rendered, + ) # self.node.nodefile(name, rendered) except Exception: raise CoreError( - f"error rendering template: {name}" + f"node({self.node.name}) service({self.name}) " + f"error rendering template({name}): " f"{exceptions.text_error_template().render()}" ) diff --git a/daemon/core/configservices/defaultroute/service.py b/daemon/core/configservices/defaultroute/service.py index dab779a0..445899c9 100644 --- a/daemon/core/configservices/defaultroute/service.py +++ b/daemon/core/configservices/defaultroute/service.py @@ -11,6 +11,7 @@ from core.nodes.interface import Veth class DefaultRoute(ConfigService): name = "DefaultRoute" group = "Utility" + directories = [] executables = [] dependencies = [] startup = [] @@ -42,6 +43,4 @@ if __name__ == "__main__": netif.addaddr("10.0.0.1/24") node.addnetif(netif, 0) service = DefaultRoute(node) - service.create_files() - # data = service.render(node, "defaultroute.sh", dict(addresses=[])) - # print(data) + service.start()