Example #1
0
    def load_from_config(cls, config):
        if config.get("family") == "AF_UNIX" and not hasattr(socket, "AF_UNIX"):
            raise NotImplementedError("AF_UNIX not supported on this" "platform")

        params = {
            "name": config["name"],
            "host": config.get("host", "localhost"),
            "port": int(config.get("port", "8080")),
            "path": config.get("path"),
            "interface": config.get("interface", None),
            "family": _FAMILY[config.get("family", "AF_INET").upper()],
            "type": _TYPE[config.get("type", "SOCK_STREAM").upper()],
            "backlog": int(config.get("backlog", 2048)),
            "so_reuseport": to_bool(config.get("so_reuseport")),
            "umask": int(config.get("umask", 8)),
            "replace": config.get("replace"),
            "blocking": to_bool(config.get("blocking")),
        }
        use_papa = to_bool(config.get("use_papa")) and papa is not None
        proto_name = config.get("proto")
        if proto_name is not None:
            params["proto"] = socket.getprotobyname(proto_name)
        socket_class = PapaSocketProxy if use_papa else cls
        s = socket_class(**params)

        # store the config for later checking if config has changed
        s._cfg = config.copy()

        return s
Example #2
0
    def load_from_config(cls, config):
        if (config.get('family') == 'AF_UNIX' and
                not hasattr(socket, 'AF_UNIX')):
            raise NotImplementedError("AF_UNIX not supported on this"
                                      "platform")

        params = {'name': config['name'],
                  'host': config.get('host', 'localhost'),
                  'port': int(config.get('port', '8080')),
                  'path': config.get('path'),
                  'interface': config.get('interface', None),
                  'family': _FAMILY[config.get('family', 'AF_INET').upper()],
                  'type': _TYPE[config.get('type', 'SOCK_STREAM').upper()],
                  'backlog': int(config.get('backlog', 2048)),
                  'so_reuseport': to_bool(config.get('so_reuseport')),
                  'umask': int(config.get('umask', 8)),
                  'replace': config.get('replace')}
        use_papa = to_bool(config.get('use_papa')) and papa is not None
        proto_name = config.get('proto')
        if proto_name is not None:
            params['proto'] = socket.getprotobyname(proto_name)
        socket_class = PapaSocketProxy if use_papa else cls
        s = socket_class(**params)

        # store the config for later checking if config has changed
        s._cfg = config.copy()

        return s
Example #3
0
def convert_option(key, val):
    if key == "numprocesses":
        return int(val)
    elif key == "warmup_delay":
        return float(val)
    elif key == "working_dir":
        return val
    elif key == "uid":
        return val
    elif key == "gid":
        return val
    elif key == "send_hup":
        return util.to_bool(val)
    elif key == "shell":
        return util.to_bool(val)
    elif key == "env":
        return util.parse_env(val)
    elif key == "cmd":
        return val
    elif key == "flapping_attempts":
        return int(val)
    elif key == "flapping_window":
        return float(val)
    elif key == "retry_in":
        return float(val)
    elif key == "max_retry":
        return int(val)
    elif key == "graceful_timeout":
        return float(val)
    elif key == 'max_age':
        return int(val)
    elif key == 'max_age_variance':
        return int(val)

    raise ArgumentError("unknown key %r" % key)
Example #4
0
File: set.py Project: cyberj/circus
 def _convert_opt(self, key, val):
     if key == "numprocesses":
         return int(val)
     elif key == "warmup_delay":
         return float(val)
     elif key == "working_dir":
         return val
     elif key == "uid":
         return val
     elif key == "gid":
         return val
     elif key == "send_hup":
         return util.to_bool(val)
     elif key == "shell":
         return util.to_bool(val)
     elif key == "env":
         return util.parse_env(val)
     elif key == "cmd":
         return  val
     elif key == "times":
         return int(val)
     elif key == "within":
         return float(val)
     elif key == "retry_in":
         return float(val)
     elif key == "max_retry":
         return int(val)
     elif key == "graceful_timeout":
         return float(val)
     raise ArgumentError("unkown key %r" % key)
Example #5
0
    def test_tobool(self):
        for value in ('True ', '1', 'true'):
            self.assertTrue(to_bool(value))

        for value in ('False', '0', 'false'):
            self.assertFalse(to_bool(value))

        for value in ('Fal', '344', ''):
            self.assertRaises(ValueError, to_bool, value)
Example #6
0
    def test_tobool(self):
        for value in ("True ", "1", "true"):
            self.assertTrue(to_bool(value))

        for value in ("False", "0", "false"):
            self.assertFalse(to_bool(value))

        for value in ("Fal", "344", ""):
            self.assertRaises(ValueError, to_bool, value)
Example #7
0
def convert_option(key, val):
    if key == "numprocesses":
        return int(val)
    elif key == "warmup_delay":
        return float(val)
    elif key == "working_dir":
        return val
    elif key == "uid":
        return val
    elif key == "gid":
        return val
    elif key == "send_hup":
        return util.to_bool(val)
    elif key == "shell":
        return util.to_bool(val)
    elif key == "copy_env":
        return util.to_bool(val)
    elif key == "env":
        return util.parse_env_dict(val)
    elif key == "cmd":
        return val
    elif key == "flapping_attempts":
        return int(val)
    elif key == "flapping_window":
        return float(val)
    elif key == "retry_in":
        return float(val)
    elif key == "max_retry":
        return int(val)
    elif key == "graceful_timeout":
        return float(val)
    elif key == 'max_age':
        return int(val)
    elif key == 'max_age_variance':
        return int(val)
    elif key == 'respawn':
        return util.to_bool(val)
    elif key.startswith('stderr_stream.') or key.startswith('stdout_stream.'):
        subkey = key.split('.', 1)[-1]

        if subkey in ('class', 'filename'):
            return val
        elif subkey in ('max_bytes', 'backup_count'):
            return int(val)
        elif subkey == 'refresh_time':
            # Deprecated but warning below
            return
    elif key.startswith('hooks.'):
        subkey = key.split('.', 1)[-1]

        if subkey in ('before_start', 'after_start', 'before_stop',
                      'after_stop', 'before_spawn'):
            return val

    raise ArgumentError("unknown key %r" % key)
Example #8
0
File: show.py Project: atdt/circus
    def set_opt(self, key, val):
        """ set a show option

        This function set the show options. unknown keys are ignored.
        This function return an action number:

        - 0: trigger the process management
        - 1: trigger a graceful reload of the flies;
        """

        action = 0
        if key == "numflies":
            self.numflies = int(val)
        elif key == "warmup_delay":
            self.warmup_delay = float(val)
        elif key == "working_dir":
            self.working_dir = val
            action = 1
        elif key == "uid":
            self.uid = util.to_uid(val)
            action = 1
        elif key == "gid":
            self.gid = util.to_gid(val)
            action = 1
        elif key == "send_hup":
            self.send_hup = util.to_bool(val)
        elif key == "shell":
            self.shell = util.to_bool(val)
            action = 1
        elif key == "env":
            self.env = util.parse_env(val)
            action = 1
        elif key == "cmd":
            self.cmd = val
            action = 1
        elif key == "times":
            self.times = int(val)
            action = -1
        elif key == "within":
             self.within = float(val)
        elif key == "retry_in":
            self.retry_in = float(val)
        elif key == "max_retry":
            self.max_retry = int(val)
        elif key == "graceful_timeout":
            self.graceful_timeout = float(val)
            action = -1
        self.send_msg("updated", {"time": time.time()})
        return action
Example #9
0
 def __init__(self, endpoint, pubsub_endpoint, check_delay,
              **config):
     self.daemon = True
     self.config = config
     self.active = to_bool(config.get('active', True))
     self.context = zmq.Context()
     self.pubsub_endpoint = pubsub_endpoint
     self.endpoint = endpoint
     self.check_delay = check_delay
     self.loop = ioloop.IOLoop()
     self._id = uuid.uuid4().hex    # XXX os.getpid()+thread id is enough...
     self.running = False
Example #10
0
 def __init__(self, endpoint, pubsub_endpoint, check_delay, ssh_server=None, **config):
     self.daemon = True
     self.config = config
     self.active = to_bool(config.get("active", True))
     self.context = zmq.Context()
     self.pubsub_endpoint = pubsub_endpoint
     self.endpoint = endpoint
     self.check_delay = check_delay
     self.ssh_server = ssh_server
     self.loop = ioloop.IOLoop()
     self._id = b(uuid.uuid4().hex)
     self.running = False
    def __init__(self, *args, **config):
        super(ResourceWatcher, self).__init__(*args, **config)
        self.watcher = config.get("watcher", None)
        self.service = config.get("service", None)
        if self.service is not None:
            warnings.warn("ResourceWatcher.service is deprecated "
                          "please use ResourceWatcher.watcher instead.",
                          category=DeprecationWarning)
            if self.watcher is None:
                self.watcher = self.service
        if self.watcher is None:
            self.statsd.stop()
            self.loop.close()
            raise NotImplementedError('watcher is mandatory for now.')

        self.max_cpu = float(config.get("max_cpu", 90))     # in %
        self.max_mem = config.get("max_mem")

        if self.max_mem is None:
            self.max_mem = 90.
            self._max_percent = True
        else:
            try:
                self.max_mem = float(self.max_mem)          # float -> %
                self._max_percent = True
            except ValueError:
                self.max_mem = human2bytes(self.max_mem)    # int -> absolute
                self._max_percent = False

        self.min_cpu = config.get("min_cpu")
        if self.min_cpu is not None:
            self.min_cpu = float(self.min_cpu)              # in %
        self.min_mem = config.get("min_mem")
        if self.min_mem is not None:
            try:
                self.min_mem = float(self.min_mem)          # float -> %
                self._min_percent = True
            except ValueError:
                self.min_mem = human2bytes(self.min_mem)    # int -> absolute
                self._min_percent = True
        self.health_threshold = float(config.get("health_threshold",
                                      75))  # in %
        self.max_count = int(config.get("max_count", 3))

        self.process_children = to_bool(config.get("process_children", '0'))
        self.child_signal = int(config.get("child_signal", signal.SIGTERM))

        self._count_over_cpu = {}
        self._count_over_mem = {}
        self._count_under_cpu = {}
        self._count_under_mem = {}
        self._count_health = {}
    def dget(self, section, option, default=None, type=str):
        if not self.has_option(section, option):
            return default

        value = self.get(section, option)

        if type is int:
            value = int(value)
        elif type is bool:
            value = to_bool(value)
        elif type is float:
            value = float(value)
        elif type is not str:
            raise NotImplementedError()

        return value
Example #13
0
    def check(self, watcher_name):
        timeline = self.timelines[watcher_name]
        if watcher_name in self.configs:
            conf = self.configs[watcher_name]
        else:
            conf = self.update_conf(watcher_name)

        # if the watcher is not activated, we skip it
        if not to_bool(self._get_conf(conf, 'active')):
            # nothing to do here
            return

        tries = self.tries.get(watcher_name, 0)

        if len(timeline) == self._get_conf(conf, 'attempts'):
            duration = timeline[-1] - timeline[0] - self.check_delay

            if duration <= self._get_conf(conf, 'window'):
                max_retry = self._get_conf(conf, 'max_retry')
                if tries < max_retry or max_retry == INFINITE_RETRY:
                    next_tries = tries + 1
                    logger.info("%s: flapping detected: retry in %2ds "
                                "(attempt number %s)", watcher_name,
                                self._get_conf(conf, 'retry_in'), next_tries)

                    self.cast("stop", name=watcher_name)
                    self.timelines[watcher_name] = []
                    self.tries[watcher_name] = next_tries

                    def _start():
                        self.cast("start", name=watcher_name)

                    timer = Timer(self._get_conf(conf, 'retry_in'), _start)
                    timer.start()
                    self.timers[watcher_name] = timer
                else:
                    logger.info(
                        "%s: flapping detected: reached max retry limit",
                        watcher_name)
                    self.timelines[watcher_name] = []
                    self.tries[watcher_name] = 0
                    self.cast("stop", name=watcher_name)
            else:
                self.timelines[watcher_name] = []
                self.tries[watcher_name] = 0
def get_config(config_file):
    if not os.path.exists(config_file):
        raise IOError("the configuration file %r does not exist\n" %
                      config_file)

    cfg, cfg_files_read = read_config(config_file)
    dget = cfg.dget
    config = {}

    # reading the global environ first
    global_env = dict(os.environ.items())
    local_env = dict()

    # update environments with [env] section
    if 'env' in cfg.sections():
        local_env.update(dict(cfg.items('env')))
        global_env.update(local_env)

    # always set the cfg environment
    cfg.set_env(global_env)

    # main circus options
    config['check_delay'] = dget('circus', 'check_delay', 5., float)
    config['endpoint'] = dget('circus', 'endpoint', DEFAULT_ENDPOINT_DEALER)
    config['endpoint_owner'] = dget('circus', 'endpoint_owner', None, str)
    config['pubsub_endpoint'] = dget('circus', 'pubsub_endpoint',
                                     DEFAULT_ENDPOINT_SUB)
    config['multicast_endpoint'] = dget('circus', 'multicast_endpoint',
                                        DEFAULT_ENDPOINT_MULTICAST)
    config['stats_endpoint'] = dget('circus', 'stats_endpoint', None)
    config['statsd'] = dget('circus', 'statsd', False, bool)
    config['umask'] = dget('circus', 'umask', None)
    if config['umask']:
        config['umask'] = int(config['umask'], 8)

    if config['stats_endpoint'] is None:
        config['stats_endpoint'] = DEFAULT_ENDPOINT_STATS
    elif not config['statsd']:
        warnings.warn("You defined a stats_endpoint without "
                      "setting up statsd to True.",
                      DeprecationWarning)
        config['statsd'] = True

    config['warmup_delay'] = dget('circus', 'warmup_delay', 0, int)
    config['httpd'] = dget('circus', 'httpd', False, bool)
    config['httpd_host'] = dget('circus', 'httpd_host', 'localhost', str)
    config['httpd_port'] = dget('circus', 'httpd_port', 8080, int)
    config['debug'] = dget('circus', 'debug', False, bool)
    config['debug_gc'] = dget('circus', 'debug_gc', False, bool)
    config['pidfile'] = dget('circus', 'pidfile')
    config['loglevel'] = dget('circus', 'loglevel')
    config['logoutput'] = dget('circus', 'logoutput')
    config['loggerconfig'] = dget('circus', 'loggerconfig', None)
    config['fqdn_prefix'] = dget('circus', 'fqdn_prefix', None, str)

    # Initialize watchers, plugins & sockets to manage
    watchers = []
    plugins = []
    sockets = []

    for section in cfg.sections():
        if section.startswith("socket:"):
            sock = dict(cfg.items(section))
            sock['name'] = section.split("socket:")[-1].lower()
            sock['so_reuseport'] = dget(section, "so_reuseport", False, bool)
            sock['replace'] = dget(section, "replace", False, bool)
            sockets.append(sock)

        if section.startswith("plugin:"):
            plugin = dict(cfg.items(section))
            plugin['name'] = section
            if 'priority' in plugin:
                plugin['priority'] = int(plugin['priority'])
            plugins.append(plugin)

        if section.startswith("watcher:"):
            watcher = watcher_defaults()
            watcher['name'] = section.split("watcher:", 1)[1]

            # create watcher options
            for opt, val in cfg.items(section, noreplace=True):
                if opt in ('cmd', 'args', 'working_dir', 'uid', 'gid'):
                    watcher[opt] = val
                elif opt == 'numprocesses':
                    watcher['numprocesses'] = dget(section, 'numprocesses', 1,
                                                   int)
                elif opt == 'warmup_delay':
                    watcher['warmup_delay'] = dget(section, 'warmup_delay', 0,
                                                   int)
                elif opt == 'executable':
                    watcher['executable'] = dget(section, 'executable', None,
                                                 str)
                # default bool to False
                elif opt in ('shell', 'send_hup', 'stop_children',
                             'close_child_stderr', 'use_sockets', 'singleton',
                             'copy_env', 'copy_path', 'close_child_stdout'):
                    watcher[opt] = dget(section, opt, False, bool)
                elif opt == 'stop_signal':
                    watcher['stop_signal'] = to_signum(val)
                elif opt == 'max_retry':
                    watcher['max_retry'] = dget(section, "max_retry", 5, int)
                elif opt == 'graceful_timeout':
                    watcher['graceful_timeout'] = dget(
                        section, "graceful_timeout", 30, int)
                elif opt.startswith('stderr_stream') or \
                        opt.startswith('stdout_stream'):
                    stream_name, stream_opt = opt.split(".", 1)
                    watcher[stream_name][stream_opt] = val
                elif opt.startswith('rlimit_'):
                    limit = opt[7:]
                    watcher['rlimits'][limit] = int(val)
                elif opt == 'priority':
                    watcher['priority'] = dget(section, "priority", 0, int)
                elif opt.startswith('hooks.'):
                    hook_name = opt[len('hooks.'):]
                    val = [elmt.strip() for elmt in val.split(',', 1)]
                    if len(val) == 1:
                        val.append(False)
                    else:
                        val[1] = to_bool(val[1])

                    watcher['hooks'][hook_name] = val
                # default bool to True
                elif opt in ('check_flapping', 'respawn', 'autostart'):
                    watcher[opt] = dget(section, opt, True, bool)
                else:
                    # freeform
                    watcher[opt] = val

            if watcher['copy_env']:
                watcher['env'] = dict(global_env)
            else:
                watcher['env'] = dict(local_env)

            watchers.append(watcher)

    # making sure we return consistent lists
    sort_by_field(watchers)
    sort_by_field(plugins)
    sort_by_field(sockets)

    # Second pass to make sure env sections apply to all watchers.

    def _extend(target, source):
        for name, value in source:
            if name in target:
                continue
            target[name] = value

    def _expand_vars(target, key, env):
        if isinstance(target[key], str):
            target[key] = replace_gnu_args(target[key], env=env)
        elif isinstance(target[key], dict):
            for k in target[key].keys():
                _expand_vars(target[key], k, env)

    def _expand_section(section, env, exclude=None):
        if exclude is None:
            exclude = ('name', 'env')

        for option in section.keys():
            if option in exclude:
                continue
            _expand_vars(section, option, env)

    # build environment for watcher sections
    for section in cfg.sections():
        if section.startswith('env:'):
            section_elements = section.split("env:", 1)[1]
            watcher_patterns = [s.strip() for s in section_elements.split(',')]
            env_items = dict(cfg.items(section, noreplace=True))

            for pattern in watcher_patterns:
                match = [w for w in watchers if fnmatch(w['name'], pattern)]

                for watcher in match:
                    watcher['env'].update(env_items)

    # expand environment for watcher sections
    for watcher in watchers:
        env = dict(global_env)
        env.update(watcher['env'])
        _expand_section(watcher, env)

    config['watchers'] = watchers
    config['plugins'] = plugins
    config['sockets'] = sockets
    return config
Example #15
0
def get_config(config_file):
    if not os.path.exists(config_file):
        raise IOError("the configuration file %r does not exist\n" %
                      config_file)

    cfg, cfg_files_read = read_config(config_file)
    dget = cfg.dget
    config = {}

    # reading the global environ first
    global_env = dict(os.environ.items())
    local_env = dict()

    # update environments with [env] section
    if 'env' in cfg.sections():
        local_env.update(dict(cfg.items('env')))
        global_env.update(local_env)

    # always set the cfg environment
    cfg.set_env(global_env)

    # main circus options
    config['check_delay'] = dget('circus', 'check_delay', 5., float)
    config['endpoint'] = dget('circus', 'endpoint', DEFAULT_ENDPOINT_DEALER)
    config['endpoint_owner'] = dget('circus', 'endpoint_owner', None, str)
    config['pubsub_endpoint'] = dget('circus', 'pubsub_endpoint',
                                     DEFAULT_ENDPOINT_SUB)
    config['multicast_endpoint'] = dget('circus', 'multicast_endpoint',
                                        DEFAULT_ENDPOINT_MULTICAST)
    config['stats_endpoint'] = dget('circus', 'stats_endpoint', None)
    config['statsd'] = dget('circus', 'statsd', False, bool)
    config['umask'] = dget('circus', 'umask', None)
    if config['umask']:
        config['umask'] = int(config['umask'], 8)

    if config['stats_endpoint'] is None:
        config['stats_endpoint'] = DEFAULT_ENDPOINT_STATS
    elif not config['statsd']:
        warnings.warn(
            "You defined a stats_endpoint without "
            "setting up statsd to True.", DeprecationWarning)
        config['statsd'] = True

    config['warmup_delay'] = dget('circus', 'warmup_delay', 0, int)
    config['httpd'] = dget('circus', 'httpd', False, bool)
    config['httpd_host'] = dget('circus', 'httpd_host', 'localhost', str)
    config['httpd_port'] = dget('circus', 'httpd_port', 8080, int)
    config['debug'] = dget('circus', 'debug', False, bool)
    config['debug_gc'] = dget('circus', 'debug_gc', False, bool)
    config['pidfile'] = dget('circus', 'pidfile')
    config['loglevel'] = dget('circus', 'loglevel')
    config['logoutput'] = dget('circus', 'logoutput')
    config['loggerconfig'] = dget('circus', 'loggerconfig', None)
    config['fqdn_prefix'] = dget('circus', 'fqdn_prefix', None, str)
    config['papa_endpoint'] = dget('circus', 'papa_endpoint', None, str)

    # Initialize watchers, plugins & sockets to manage
    watchers = []
    plugins = []
    sockets = []

    for section in cfg.sections():
        section_items = dict(cfg.items(section))
        if list(section_items.keys()) in [[], ['__name__']]:
            # Skip empty sections
            continue
        if section.startswith("socket:"):
            sock = section_items
            sock['name'] = section.split("socket:")[-1].lower()
            sock['so_reuseport'] = dget(section, "so_reuseport", False, bool)
            sock['replace'] = dget(section, "replace", False, bool)
            sockets.append(sock)

        if section.startswith("plugin:"):
            plugin = section_items
            plugin['name'] = section
            if 'priority' in plugin:
                plugin['priority'] = int(plugin['priority'])
            plugins.append(plugin)

        if section.startswith("watcher:"):
            watcher = watcher_defaults()
            watcher['name'] = section.split("watcher:", 1)[1]

            # create watcher options
            for opt, val in cfg.items(section, noreplace=True):
                if opt in ('cmd', 'args', 'working_dir', 'uid', 'gid'):
                    watcher[opt] = val
                elif opt == 'numprocesses':
                    watcher['numprocesses'] = dget(section, 'numprocesses', 1,
                                                   int)
                elif opt == 'warmup_delay':
                    watcher['warmup_delay'] = dget(section, 'warmup_delay', 0,
                                                   int)
                elif opt == 'executable':
                    watcher['executable'] = dget(section, 'executable', None,
                                                 str)
                # default bool to False
                elif opt in ('on_demand', 'shell', 'send_hup', 'stop_children',
                             'close_child_stderr', 'use_sockets', 'singleton',
                             'copy_env', 'copy_path', 'close_child_stdout'):
                    watcher[opt] = dget(section, opt, False, bool)
                elif opt == 'stop_signal':
                    watcher['stop_signal'] = to_signum(val)
                elif opt == 'max_retry':
                    watcher['max_retry'] = dget(section, "max_retry", 5, int)
                elif opt == 'graceful_timeout':
                    watcher['graceful_timeout'] = dget(section,
                                                       "graceful_timeout", 30,
                                                       int)
                elif opt.startswith('stderr_stream') or \
                        opt.startswith('stdout_stream'):
                    stream_name, stream_opt = opt.split(".", 1)
                    watcher[stream_name][stream_opt] = val
                elif opt.startswith('rlimit_'):
                    limit = opt[7:]
                    watcher['rlimits'][limit] = rlimit_value(val)
                elif opt == 'priority':
                    watcher['priority'] = dget(section, "priority", 0, int)
                elif opt == 'use_papa' and dget(section, 'use_papa', False,
                                                bool):
                    if papa:
                        watcher['use_papa'] = True
                    else:
                        warnings.warn(
                            "Config file says use_papa but the papa "
                            "module is missing.", ImportWarning)
                elif opt.startswith('hooks.'):
                    hook_name = opt[len('hooks.'):]
                    val = [elmt.strip() for elmt in val.split(',', 1)]
                    if len(val) == 1:
                        val.append(False)
                    else:
                        val[1] = to_bool(val[1])

                    watcher['hooks'][hook_name] = val
                # default bool to True
                elif opt in ('check_flapping', 'respawn', 'autostart',
                             'close_child_stdin'):
                    watcher[opt] = dget(section, opt, True, bool)
                else:
                    # freeform
                    watcher[opt] = val

            if watcher['copy_env']:
                watcher['env'] = dict(global_env)
            else:
                watcher['env'] = dict(local_env)

            watchers.append(watcher)

    # making sure we return consistent lists
    sort_by_field(watchers)
    sort_by_field(plugins)
    sort_by_field(sockets)

    # Second pass to make sure env sections apply to all watchers.

    def _extend(target, source):
        for name, value in source:
            if name in target:
                continue
            target[name] = value

    def _expand_vars(target, key, env):
        if isinstance(target[key], six.string_types):
            target[key] = replace_gnu_args(target[key], env=env)
        elif isinstance(target[key], dict):
            for k in target[key].keys():
                _expand_vars(target[key], k, env)

    def _expand_section(section, env, exclude=None):
        if exclude is None:
            exclude = ('name', 'env')

        for option in section.keys():
            if option in exclude:
                continue
            _expand_vars(section, option, env)

    # build environment for watcher sections
    for section in cfg.sections():
        if section.startswith('env:'):
            section_elements = section.split("env:", 1)[1]
            watcher_patterns = [s.strip() for s in section_elements.split(',')]
            env_items = dict(cfg.items(section, noreplace=True))

            for pattern in watcher_patterns:
                match = [w for w in watchers if fnmatch(w['name'], pattern)]

                for watcher in match:
                    watcher['env'].update(env_items)

    # expand environment for watcher sections
    for watcher in watchers:
        env = dict(global_env)
        env.update(watcher['env'])
        _expand_section(watcher, env)

    config['watchers'] = watchers
    config['plugins'] = plugins
    config['sockets'] = sockets
    return config
Example #16
0
    def set_opt(self, key, val):
        """Set a watcher option.

        This function set the watcher options. unknown keys are ignored.
        This function return an action number:

        - 0: trigger the process management
        - 1: trigger a graceful reload of the processes;
        """
        action = 0

        if key in self._options:
            self._options[key] = val
            action = -1    # XXX for now does not trigger a reload
        elif key == "numprocesses":
            val = int(val)
            if val < 0:
                val = 0
            if self.singleton and val > 1:
                raise ValueError('Singleton watcher has a single process')
            self.numprocesses = val
        elif key == "warmup_delay":
            self.warmup_delay = float(val)
        elif key == "working_dir":
            self.working_dir = val
            action = 1
        elif key == "uid":
            self.uid = util.to_uid(val)
            action = 1
        elif key == "gid":
            self.gid = util.to_gid(val)
            action = 1
        elif key == "send_hup":
            self.send_hup = val
        elif key == "stop_signal":
            self.stop_signal = util.to_signum(val)
        elif key == "stop_children":
            self.stop_children = util.to_bool(val)
        elif key == "shell":
            self.shell = val
            action = 1
        elif key == "env":
            if PY2 and IS_WINDOWS:
                # Windows on Python 2 does not accept Unicode values
                # in env dictionary
                self.env = dict((b(k), b(v)) for k, v in val.iteritems())
            else:
                self.env = val
            action = 1
        elif key == "cmd":
            self.cmd = val
            action = 1
        elif key == "args":
            self.args = val
            action = 1
        elif key == "graceful_timeout":
            self.graceful_timeout = float(val)
            action = -1
        elif key == "max_age":
            self.max_age = int(val)
            action = 1
        elif key == "max_age_variance":
            self.max_age_variance = int(val)
            action = 1
        elif (key.startswith('stdout_stream') or
              key.startswith('stderr_stream')):
            action = self._reload_stream(key, val)
        elif key.startswith('hooks'):
            val = val.split(',')
            if len(val) == 2:
                ignore_error = util.to_bool(val[1])
            else:
                ignore_error = False
            hook = val[0]
            self._reload_hook(key, hook, ignore_error)
            action = 0

        # send update event
        self.notify_event("updated", {"time": time.time()})
        return action
Example #17
0
def convert_option(key, val):
    if key == "numprocesses":
        return int(val)
    elif key == "warmup_delay":
        return float(val)
    elif key == "working_dir":
        return val
    elif key == "uid":
        return val
    elif key == "gid":
        return val
    elif key == "send_hup":
        return util.to_bool(val)
    elif key == "stop_signal":
        return util.to_signum(val)
    elif key == "stop_children":
        return util.to_bool(val)
    elif key == "shell":
        return util.to_bool(val)
    elif key == "copy_env":
        return util.to_bool(val)
    elif key == "env":
        return util.parse_env_dict(val)
    elif key == "cmd":
        return val
    elif key == "args":
        return val
    elif key == "retry_in":
        return float(val)
    elif key == "max_retry":
        return int(val)
    elif key == "graceful_timeout":
        return float(val)
    elif key == 'max_age':
        return int(val)
    elif key == 'max_age_variance':
        return int(val)
    elif key == 'respawn':
        return util.to_bool(val)
    elif key.startswith('stderr_stream.') or key.startswith('stdout_stream.'):
        subkey = key.split('.', 1)[-1]
        if subkey in ('max_bytes', 'backup_count'):
            return int(val)
        return val
    elif key == 'hooks':
        res = {}
        for hook in val.split(','):
            if hook == '':
                continue
            hook = hook.split(':')
            if len(hook) != 2:
                raise ArgumentError(hook)

            name, value = hook
            if name not in _HOOKS:
                raise ArgumentError(name)

            res[name] = value

        return res
    elif key.startswith('hooks.'):
        # we can also set a single hook
        name = key.split('.', 1)[-1]
        if name not in _HOOKS:
            raise ArgumentError(name)
        return val
    elif key.startswith('rlimit_'):
        return int(val)

    raise ArgumentError("unknown key %r" % key)
Example #18
0
    def set_opt(self, key, val):
        """Set a watcher option.

        This function set the watcher options. unknown keys are ignored.
        This function return an action number:

        - 0: trigger the process management
        - 1: trigger a graceful reload of the processes;
        """
        action = 0

        if key in self._options:
            self._options[key] = val
            action = -1  # XXX for now does not trigger a reload
        elif key == "numprocesses":
            val = int(val)
            if val < 0:
                val = 0
            if self.singleton and val > 1:
                raise ValueError('Singleton watcher has a single process')
            self.numprocesses = val
        elif key == "warmup_delay":
            self.warmup_delay = float(val)
        elif key == "working_dir":
            self.working_dir = val
            action = 1
        elif key == "uid":
            self.uid = util.to_uid(val)
            action = 1
        elif key == "gid":
            self.gid = util.to_gid(val)
            action = 1
        elif key == "send_hup":
            self.send_hup = val
        elif key == "stop_signal":
            self.stop_signal = util.to_signum(val)
        elif key == "stop_children":
            self.stop_children = util.to_bool(val)
        elif key == "shell":
            self.shell = val
            action = 1
        elif key == "env":
            if PY2 and IS_WINDOWS:
                # Windows on Python 2 does not accept Unicode values
                # in env dictionary
                self.env = dict((b(k), b(v)) for k, v in val.iteritems())
            else:
                self.env = val
            action = 1
        elif key == "cmd":
            self.cmd = val
            action = 1
        elif key == "args":
            self.args = val
            action = 1
        elif key == "graceful_timeout":
            self.graceful_timeout = float(val)
            action = -1
        elif key == "max_age":
            self.max_age = int(val)
            action = 1
        elif key == "max_age_variance":
            self.max_age_variance = int(val)
            action = 1
        elif (key.startswith('stdout_stream')
              or key.startswith('stderr_stream')):
            action = self._reload_stream(key, val)
        elif key.startswith('hooks'):
            val = val.split(',')
            if len(val) == 2:
                ignore_error = util.to_bool(val[1])
            else:
                ignore_error = False
            hook = val[0]
            self._reload_hook(key, hook, ignore_error)
            action = 0

        # send update event
        self.notify_event("updated", {"time": time.time()})
        return action
Example #19
0
    def set_opt(self, key, val):
        """Set a watcher option.

        This function set the watcher options. unknown keys are ignored.
        This function return an action number:

        - 0: trigger the process management
        - 1: trigger a graceful reload of the processes;
        """
        action = 0

        if key in self._options:
            self._options[key] = val
            action = -1  # XXX for now does not trigger a reload
        elif key == "numprocesses":
            val = int(val)
            if val < 0:
                val = 0
            if self.singleton and val > 1:
                raise ValueError("Singleton watcher has a single process")
            self.numprocesses = val
        elif key == "warmup_delay":
            self.warmup_delay = float(val)
        elif key == "working_dir":
            self.working_dir = val
            action = 1
        elif key == "uid":
            self.uid = util.to_uid(val)
            action = 1
        elif key == "gid":
            self.gid = util.to_gid(val)
            action = 1
        elif key == "send_hup":
            self.send_hup = val
        elif key == "shell":
            self.shell = val
            action = 1
        elif key == "env":
            self.env = val
            action = 1
        elif key == "cmd":
            self.cmd = val
            action = 1
        elif key == "graceful_timeout":
            self.graceful_timeout = float(val)
            action = -1
        elif key == "max_age":
            self.max_age = int(val)
            action = 1
        elif key == "max_age_variance":
            self.max_age_variance = int(val)
            action = 1
        elif key.startswith("stdout_stream") or key.startswith("stderr_stream"):
            action = self._reload_stream(key, val)
        elif key.startswith("hook"):
            val = val.split(",")
            if len(val) == 2:
                ignore_error = util.to_bool(val[1])
            else:
                ignore_error = False
            hook = val[0]
            self._reload_hook(key, hook, ignore_error)
            action = 1

        # send update event
        self.notify_event("updated", {"time": time.time()})
        return action
Example #20
0
def convert_option(key, val):
    if key == "numprocesses":
        return int(val)
    elif key == "warmup_delay":
        return float(val)
    elif key == "working_dir":
        return val
    elif key == "uid":
        return val
    elif key == "gid":
        return val
    elif key == "send_hup":
        return util.to_bool(val)
    elif key == "stop_signal":
        return util.to_signum(val)
    elif key == "stop_children":
        return util.to_bool(val)
    elif key == "shell":
        return util.to_bool(val)
    elif key == "copy_env":
        return util.to_bool(val)
    elif key == "env":
        return util.parse_env_dict(val)
    elif key == "cmd":
        return val
    elif key == "args":
        return val
    elif key == "retry_in":
        return float(val)
    elif key == "max_retry":
        return int(val)
    elif key == "graceful_timeout":
        return float(val)
    elif key == 'max_age':
        return int(val)
    elif key == 'max_age_variance':
        return int(val)
    elif key == 'respawn':
        return util.to_bool(val)
    elif key == "singleton":
        return util.to_bool(val)
    elif key.startswith('stderr_stream.') or key.startswith('stdout_stream.'):
        subkey = key.split('.', 1)[-1]
        if subkey in ('max_bytes', 'backup_count'):
            return int(val)
        return val
    elif key == 'hooks':
        res = {}
        for hook in val.split(','):
            if hook == '':
                continue
            hook = hook.split(':')
            if len(hook) != 2:
                raise ArgumentError(hook)

            name, value = hook
            if name not in _HOOKS:
                raise ArgumentError(name)

            res[name] = value

        return res
    elif key.startswith('hooks.'):
        # we can also set a single hook
        name = key.split('.', 1)[-1]
        if name not in _HOOKS:
            raise ArgumentError(name)
        return val
    elif key.startswith('rlimit_'):
        return int(val)

    raise ArgumentError("unknown key %r" % key)
Example #21
0
def convert_option(key, val):
    if key == "numprocesses":
        return int(val)
    elif key == "warmup_delay":
        return float(val)
    elif key == "working_dir":
        return val
    elif key == "uid":
        return val
    elif key == "gid":
        return val
    elif key == "send_hup":
        return util.to_bool(val)
    elif key == "shell":
        return util.to_bool(val)
    elif key == "copy_env":
        return util.to_bool(val)
    elif key == "env":
        return util.parse_env_dict(val)
    elif key == "cmd":
        return val
    elif key == "flapping_attempts":
        return int(val)
    elif key == "flapping_window":
        return float(val)
    elif key == "retry_in":
        return float(val)
    elif key == "max_retry":
        return int(val)
    elif key == "graceful_timeout":
        return float(val)
    elif key == "max_age":
        return int(val)
    elif key == "max_age_variance":
        return int(val)
    elif key == "respawn":
        return util.to_bool(val)
    elif key.startswith("stderr_stream.") or key.startswith("stdout_stream."):
        subkey = key.split(".", 1)[-1]
        if subkey in ("max_bytes", "backup_count"):
            return int(val)
        return val
    elif key == "hooks":
        res = {}
        for hook in val.split(","):
            if hook == "":
                continue
            hook = hook.split(":")
            if len(hook) != 2:
                raise ArgumentError(hook)

            name, value = hook
            if name not in _HOOKS:
                raise ArgumentError(name)

            res[name] = value

        return res
    elif key.startswith("hooks."):
        # we can also set a single hook
        name = key.split(".", 1)[-1]
        if name not in _HOOKS:
            raise ArgumentError(name)
        return val

    raise ArgumentError("unknown key %r" % key)