From 6b82838ed4a0e2ef587c8da35ef07e9b3895c6fc Mon Sep 17 00:00:00 2001 From: Roque <roqueporchetto@gmail.com> Date: Mon, 14 May 2018 13:53:37 +0200 Subject: [PATCH] Automatic restart of services when configuration changes The main idea is to rename the service wrapper using a hash of the corresponding configuration files. In that way, if the config files are updated, the corresponding script file, section in supervisor.conf and service process will be updated accordingly. - the file name in wrapper_path contains a hash of the corresponding config files - when config files change, and therefore the hash, the wrapper will be re-created and the corresponding service restarted - the config files paths will be a parameter in the corresponding buildout section, if it isn't set there won't be hash-check /reviewed-on https://lab.nexedi.com/nexedi/slapos/merge_requests/326 --- slapos/recipe/wrapper.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/slapos/recipe/wrapper.py b/slapos/recipe/wrapper.py index bca25bd28..42ac56659 100644 --- a/slapos/recipe/wrapper.py +++ b/slapos/recipe/wrapper.py @@ -36,6 +36,7 @@ class Recipe(GenericBaseRecipe): :param str wrapper-path: absolute path to file's destination :param lines wait-for-files: list of files to wait for + :param lines hash-files: list of files to be checked by hash :param str pidfile: path to pidfile ensure exclusivity for the process :param str private-dev-shm: size of private /dev/shm, using user namespaces :param bool reserve-cpu: command will ask for an exclusive CPU core @@ -44,6 +45,7 @@ class Recipe(GenericBaseRecipe): args = shlex.split(self.options['command-line']) wrapper_path = self.options['wrapper-path'] wait_files = self.options.get('wait-for-files') + hash_files = self.options.get('hash-files') pidfile = self.options.get('pidfile') private_dev_shm = self.options.get('private-dev-shm') @@ -63,5 +65,20 @@ class Recipe(GenericBaseRecipe): kw['private_dev_shm'] = private_dev_shm if self.isTrueValue(self.options.get('reserve-cpu')): kw['reserve_cpu'] = True + if hash_files: + hash_file_list = hash_files.split() + hash = self.generateHashFromFiles(hash_file_list) + wrapper_path = "%s-%s" % (wrapper_path, hash) return self.createWrapper(wrapper_path, args, environment, **kw) + + def generateHashFromFiles(self, file_list): + import hashlib + hasher = hashlib.md5() + for path in file_list: + with open(path, 'r') as afile: + buf = afile.read() + hasher.update("%s\n" % len(buf)) + hasher.update(buf) + hash = hasher.hexdigest() + return hash -- 2.30.9