diff options
author | André Erdmann <dywi@mailerd.de> | 2013-06-25 23:08:01 +0200 |
---|---|---|
committer | André Erdmann <dywi@mailerd.de> | 2013-06-25 23:08:01 +0200 |
commit | df58d07cbadab7bdd5f6a494355c8dac9f840d09 (patch) | |
tree | 54754683a6c95edfe4a9c8a4bc9a339dc6d1e34e /roverlay/hook.py | |
parent | files/shlib/functions.sh: correct typo (diff) | |
download | R_overlay-df58d07cbadab7bdd5f6a494355c8dac9f840d09.tar.gz R_overlay-df58d07cbadab7bdd5f6a494355c8dac9f840d09.tar.bz2 R_overlay-df58d07cbadab7bdd5f6a494355c8dac9f840d09.zip |
EVENT_HOOK_RESTRICT, roverlay.hook
Diffstat (limited to 'roverlay/hook.py')
-rw-r--r-- | roverlay/hook.py | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/roverlay/hook.py b/roverlay/hook.py new file mode 100644 index 0000000..3b13315 --- /dev/null +++ b/roverlay/hook.py @@ -0,0 +1,169 @@ +# R overlay -- run roverlay hooks (shell scripts) +# -*- coding: utf-8 -*- +# Copyright (C) 2013 André Erdmann <dywi@mailerd.de> +# Distributed under the terms of the GNU General Public License; +# either version 2 of the License, or (at your option) any later version. + +import os.path +import logging + +import roverlay.config +import roverlay.tools.shenv + +__all__ = [ 'run_hook', 'phase_allowed', ] + +LOGGER = logging.getLogger ( 'event_hook' ) + + +_EVENT_SCRIPT = None + +# None|iterable _EVENT_RESTRICT +_EVENT_RESTRICT = None + +# int _EVENT_POLICY +# -1: no policy (allow all) +# 0: not configured +# 1: allow unless in _EVENT_RESTRICT (blacklist) +# 2: deny unless in _EVENT_RESTRICT (whitelist) +# 4: deny all +_EVENT_POLICY = 0 + +def setup(): + global _EVENT_SCRIPT + global _EVENT_POLICY + global _EVENT_RESTRICT + + _EVENT_SCRIPT = roverlay.config.get ( 'EVENT_HOOK.exe', False ) + if _EVENT_SCRIPT is False: + a_dir = roverlay.config.get ( 'OVERLAY.additions_dir', None ) + if a_dir: + s = os.path.join ( + a_dir, + *roverlay.config.get_or_fail ( 'EVENT_HOOK.default_exe_relpath' ) + ) + if os.path.isfile ( s ): + _EVENT_SCRIPT = s + # -- end if _EVENT_SCRIPT + + conf_restrict = roverlay.config.get ( 'EVENT_HOOK.restrict', False ) + + if conf_restrict: + # tristate None,False,True + is_whitelist = None + allow = set() + deny = set() + for p in conf_restrict: + if p == '*': + # "allow all" + is_whitelist = False + elif p == '-*': + # "deny all" + is_whitelist = True + elif p == '-' or p == '+': + # empty + pass + elif p[0] == '-': + # deny <k> + k = p[1:].lower() + deny.add ( k ) + try: + allow.remove ( k ) + except KeyError: + pass + else: + # allow <k> + k = ( p[1:] if p[0] == '+' else p ).lower() + allow.add ( k ) + try: + deny.remove ( k ) + except KeyError: + pass + # -- end for; + + if is_whitelist is None: + # allow is set => is whitelist + # neither allow nor deny are set => deny allow + is_whitelist = bool ( allow or not deny ) + # -- end if is_whitelist #1 + + if is_whitelist: + if allow: + _EVENT_RESTRICT = frozenset ( allow ) + _EVENT_POLICY = 2 + else: + _EVENT_POLICY = 4 + elif deny: + _EVENT_RESTRICT = frozenset ( deny ) + _EVENT_POLICY = 1 + else: + _EVENT_POLICY = -1 + # -- end if is_whitelist #2 + else: + _EVENT_POLICY = -1 + # -- end if conf_restrict +# --- end of setup (...) --- + +def phase_allowed ( phase ): + if _EVENT_POLICY == -1: + return True + elif _EVENT_POLICY == 1: + # allow unless in restrict + if phase not in _EVENT_RESTRICT: + return True + else: + LOGGER.debug ( + "phase {!r} denied by blacklist policy.".format ( phase ) + ) + elif _EVENT_POLICY == 2: + # deny unless in restrict + if phase in _EVENT_RESTRICT: + return True + else: + LOGGER.debug ( + "phase {!r} denied by whitelist policy.".format ( phase ) + ) + elif _EVENT_POLICY == 4: + LOGGER.debug ( + "phase {!r} denied by 'deny all' policy".format ( phase ) + ) + else: + LOGGER.warning ( + "phase {!r} denied by undefined policy {} (fix this)".format ( + phase, _EVENT_POLICY + ) + ) + # -- end if _EVENT_POLICY + + # default return + return False +# --- end of phase_allowed (...) --- + +def phase_allowed_nolog ( phase ): + return ( + _EVENT_POLICY == -1 + ) or ( + _EVENT_POLICY == 1 and phase not in _EVENT_RESTRICT + ) or ( + _EVENT_POLICY == 2 and phase in _EVENT_RESTRICT + ) +# --- end of phase_allowed_nolog (...) --- + +def run ( phase ): + if _EVENT_SCRIPT is None: + LOGGER.warning ( + "hook module not initialized - doing that now (FIXME!)" + ) + setup() + + + + if _EVENT_SCRIPT and phase_allowed ( phase ): + return roverlay.tools.shenv.run_script ( + _EVENT_SCRIPT, phase, return_success=True + ) + else: + # nop + return True +# --- end of run (...) --- + +run_hook = run |