Esempio n. 1
0
    def reload_process(self):
        """
        Execute the reload_cmd command.

        Sometimes a daemon might watch its own config file for changes and
        reload on its own, so reload_cmd is not mandatory.

        Users of supervisord can use a "reload_cmd" value of:
            supervisordctl reload haproxy
        .. but the default is to kill haproxy and start a new process (killing
        all of the existing connections), so be warned about that.

        Also of note to supervisord users::

            Unfortunately supervisor doesn't offer a way to provide a custom
            restart command, so doing an uninterrupted haproxy restart via
            supervisor isn't possible. Instead make sure you have autorestart
            set to unexpected (the default) rather than true (which is what I
            usually do) - that way if you want a clean haproxy restart you can
            just do it yourself at the commandline using the -sf option as
            normal.

        from http://mark.aufflick.com/blog/2012/03/25/supervisord-supervisorctl-cheat-sheet
        """
        # maybe it watches its own config and reloads voluntarily
        if self.reload_cmd is not None and self.reload_cmd is not "":
            log.debug("Running reload_cmd: {}".format(self.reload_cmd))
            args = shlex.split(self.reload_cmd)
            process = subprocess.Popen(args)
            log.debug("Okay, done launching reload_cmd.")
Esempio n. 2
0
 def write_config(self, config):
     """
     Write the config file with the given content.
     """
     log.debug("Writing config to {}".format(self.dest))
     with open(self.dest, "w") as config_fh:
         config_fh.write(config)
Esempio n. 3
0
    def sleep(self):
        """
        Sleep before checking again. The better way to do this would be to
        implement in consul some concept of event-based notification hooks that
        would call a script. And then pyconfd wouldn't have to be a daemon.
        """
        seconds = 5

        log.debug("Sleeping for {} seconds".format(seconds))

        # seconds to sleep (fractional values are okay)
        gevent.sleep(seconds)

        log.debug("Done sleeping for {} seconds.".format(seconds))
Esempio n. 4
0
    def generate(self, template_input):
        """
        Populate the template from the given input.
        """
        log.debug("Reading the template.")

        template_content = self._get_template_content()

        # populate the template
        log.debug("Populating the template.")
        template = jinja2.Template(template_content)
        populated = template.render(**template_input)

        return populated
Esempio n. 5
0
    def loop(self):
        """
        Executes this plugin. Waits an interval amount of time before checking
        the config. Updates config files when necessary. Restarts programs.
        """
        executing = True
        while executing:
            try:
                # in case self.get() fails
                data = None

                # determines if config is new
                skip = False

                # grab config data via custom method
                log.debug("Getting the data.")
                data = self.get()
            except Exception as exc:
                log.error("Error getting data: {}".format(exc))
            else:  # didn't fail
                # somehow i doubt jinja responds well to None
                if data is None:
                    data = {}

                # never skip the first time (it's None)
                if self._last_config is not None:
                    # skip when new config same as old config
                    if self._last_config == data:
                        skip = True

                # don't skip if the template has changed, even if data is old
                if skip:
                    # never skip if the template last time was None (initial loop)
                    if self._last_template is None:
                        skip = False
                    else:
                        # don't skip if the template content is new
                        content = self._get_template_content()
                        if content != self._last_template:
                            skip = False

                if not skip:
                    try:
                        # populate the template
                        populated = self.generate(data)
                    except Exception as exc:
                        # TODO: log error, don't bail
                        log.error("Failed to populate the template: {}".format(exc))
                    else:
                        self.write_config(populated)
                        self.reload_process()
                        self._last_template = self._get_template_content()
                else:
                    log.debug("No new data. Skipping.")
            finally:
                # only set latest config if it was actually used
                if not skip:
                    self._last_config = data

                # wait predefined time
                self.sleep()