from shlex import quote from bundlewrap.exceptions import BundleError from bundlewrap.items import Item def svc_start(node, svcname): return node.run("supervisorctl start {}".format(quote(svcname)), may_fail=True) def svc_running(node, svcname): result = node.run("supervisorctl status {}".format(quote(svcname)), may_fail=True) return result.return_code == 0 def svc_stop(node, svcname): return node.run("supervisorctl stop {}".format(quote(svcname)), may_fail=True) class SvcSystemd(Item): """ A service managed by supervisord in uberspace. """ BUNDLE_ATTRIBUTE_NAME = "svc_uberspace_supervisord" ITEM_ATTRIBUTES = { 'running': True, } ITEM_TYPE_NAME = "svc_uberspace_supervisord" def __repr__(self): return "".format( self.name, self.attributes['running'], ) def cdict(self): cdict = {} for option, value in self.attributes.items(): if value is not None: cdict[option] = value return cdict def fix(self, status): if 'running' in status.keys_to_fix: if self.attributes['running']: svc_start(self.node, self.name) else: svc_stop(self.node, self.name) def get_canned_actions(self): return { 'stop': { 'command': "supervisorctl stop {}".format(self.name), 'needed_by': {self.id}, }, 'restart': { 'command': "supervisorctl restart {}".format(self.name), 'needs': {self.id}, }, 'update': { 'command': "supervisorctl update {}".format(self.name), 'needs': {self.id}, }, } def sdict(self): return { 'running': svc_running(self.node, self.name), } @classmethod def validate_attributes(cls, bundle, item_id, attributes): for attribute in ('running'): if attributes.get(attribute, None) not in (True, False, None): raise BundleError(_( "expected boolean or None for '{attribute}' on {item} in bundle '{bundle}'" ).format( attribute=attribute, bundle=bundle.name, item=item_id, ))