From 39a8bfc296c465694e851c7ca227d50754324617 Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Tue, 24 Apr 2012 13:57:51 +1000 Subject: [PATCH] more work on cfn-hup - correct the default config files - seperate out the monitoring of services Signed-off-by: Angus Salkeld --- heat/cfntools/cfn-hup | 24 +++++++++++------- heat/cfntools/cfn_helper.py | 50 ++++++++++++++++++++++++------------- heat/tests/test_cfn.py | 9 ++++--- 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/heat/cfntools/cfn-hup b/heat/cfntools/cfn-hup index 7889ed22..978f8fa5 100755 --- a/heat/cfntools/cfn-hup +++ b/heat/cfntools/cfn-hup @@ -28,17 +28,13 @@ if os.path.exists('/opt/aws/bin'): else: from heat.cfntools.cfn_helper import * -log_format = '%(levelname)s [%(asctime)s] %(message)s' -# setup stdout logging -logging.basicConfig(format=log_format, level=logging.INFO) - description = " " parser = argparse.ArgumentParser(description=description) parser.add_argument('-c', '--config', dest="config_dir", help="Hook Config Directory", required=False, - default=None) + default='/etc/cfn/hooks.d') parser.add_argument('-f', '--no-daemon', dest="no_deamon", help="Do not run as a deamon", @@ -50,12 +46,23 @@ parser.add_argument('-v', '--verbose', args = parser.parse_args() # FIXME: implement real arg +log_format = '%(levelname)s [%(asctime)s] %(message)s' +# setup stdout logging +if args.verbose: + logging.basicConfig(format=log_format, level=logging.DEBUG) +else: + logging.basicConfig(format=log_format, level=logging.INFO) + config_files = [] try: - config_files.append(open(os.path.join('/etc', 'cfn-hup.conf'))) -except OSError as exc: + config_files.append(open('/etc/cfn/cfn-hup.conf')) +except IOError as exc: + logging.exception(exc) + +try: + config_files.append(open('/etc/cfn/hooks.conf')) +except IOError as exc: logging.exception(exc) - pass if args.config_dir: try: @@ -64,7 +71,6 @@ if args.config_dir: except OSError as exc: logging.exception(exc) - pass mainconfig = HupConfig(config_files) diff --git a/heat/cfntools/cfn_helper.py b/heat/cfntools/cfn_helper.py index b9b62624..51a65be8 100644 --- a/heat/cfntools/cfn_helper.py +++ b/heat/cfntools/cfn_helper.py @@ -103,13 +103,12 @@ class Hook(object): return sp[1] def event(self, ev_name, ev_object, ev_resource): - if self.resource_name_get() != ev_resource: - return - if ev_name in self.triggers: - print 'su %s -c %s' % (self.runas, self.action) - #CommandRunner(self.action).run() + if self.resource_name_get() == ev_resource and \ + ev_name in self.triggers: + CommandRunner(self.action).run(user=self.runas) else: - print 'miss: %s %s' % (ev_name, ev_object) + logging.debug('event: {%s, %s, %s} did not match %s' % \ + (ev_name, ev_object, ev_resource, self.__str__())) def __str__(self): return '{%s, %s, %s, %s, %s}' % \ @@ -142,7 +141,7 @@ class CommandRunner(object): s += "\n\tstderr: %s" % self._stderr return s - def run(self): + def run(self, user='root'): """ Run the Command and return the output. @@ -500,7 +499,7 @@ class ServicesHandler(object): command.run() return command - def _handle_service(self, handler, service, properties): + def _initialize_service(self, handler, service, properties): if "enabled" in properties: enable = to_boolean(properties["enabled"]) if enable: @@ -517,17 +516,25 @@ class ServicesHandler(object): if ensure_running and not running: logging.info("Starting service %s" % service) handler(self, service, "start") - for h in self.hooks: - self.hooks[h].event('service.restarted', - service, self.resource) elif not ensure_running and running: logging.info("Stopping service %s" % service) handler(self, service, "stop") + def _monitor_service(self, handler, service, properties): + if "ensureRunning" in properties: + ensure_running = to_boolean(properties["ensureRunning"]) + command = handler(self, service, "status") + running = command.status == 0 + if ensure_running and not running: + logging.info("Restarting service %s" % service) + handler(self, service, "start") + for h in self.hooks: + self.hooks[h].event('service.restarted', + service, self.resource) - def _handle_services(self, handler, services): + def _monitor_services(self, handler, services): for service, properties in services.iteritems(): - self._handle_service(handler, service, properties) + self._monitor_service(handler, service, properties) def _initialize_services(self, handler, services): for service, properties in services.iteritems(): @@ -539,14 +546,12 @@ class ServicesHandler(object): "systemd": _handle_systemd_command } - def _service_handler(self, manager_name): handler = None if manager_name in self._service_handlers: handler = self._service_handlers[manager_name] return handler - def apply_services(self): """ Starts, stops, enables, disables services @@ -556,7 +561,18 @@ class ServicesHandler(object): if not handler: logging.warn("Skipping invalid service type: %s" % manager) else: - self._handle_services(handler, service_entries) + self._initialize_services(handler, service_entries) + + def monitor_services(self): + """ + Restarts failed services, and runs hooks. + """ + for manager, service_entries in self._services.iteritems(): + handler = self._service_handler(manager) + if not handler: + logging.warn("Skipping invalid service type: %s" % manager) + else: + self._monitor_services(handler, service_entries) class Metadata(object): @@ -644,4 +660,4 @@ class Metadata(object): self._config = self._metadata["config"] s = self._config.get("services") sh = ServicesHandler(s, resource=self.resource, hooks=hooks) - sh.apply_services() + sh.monitor_services() diff --git a/heat/tests/test_cfn.py b/heat/tests/test_cfn.py index 41df2d28..6f0a08c7 100644 --- a/heat/tests/test_cfn.py +++ b/heat/tests/test_cfn.py @@ -13,7 +13,7 @@ from nose import with_setup from heat.cfntools.cfn_helper import * -@attr(tag=['cfn_helper']) +@attr(tag=['unit', 'cfn_helper']) @attr(speed='fast') def test_boolean(): @@ -39,7 +39,7 @@ def test_boolean(): assert(not to_boolean(56)) -@attr(tag=['cfn-hup']) +@attr(tag=['unit', 'cfn-hup']) @attr(speed='fast') def test_hup_conf1(): good= """ @@ -56,7 +56,7 @@ interval=3 assert(c.interval == 3) -@attr(tag=['cfn-hup']) +@attr(tag=['unit', 'cfn-hup']) @attr(speed='fast') def test_hup_default(): good= """ @@ -71,7 +71,7 @@ credential-file=/path/to/creds_file assert(c.interval == 10) -@attr(tag=['cfn-hup']) +@attr(tag=['unit', 'cfn-hup']) @attr(speed='fast') def test_hup_hook(): good= """ @@ -96,6 +96,7 @@ runas=root assert(c.hooks['bla'].action == 'systemctl reload httpd.service') assert(c.hooks['bla'].runas == 'root') + if __name__ == '__main__': sys.argv.append(__file__) nose.main() -- 2.45.2