Gentoo Archives: gentoo-commits

From: "André Erdmann" <dywi@×××××××.de>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/tools/, roverlay/config/, roverlay/
Date: Sun, 30 Jun 2013 15:58:14
Message-Id: 1372194481.df58d07cbadab7bdd5f6a494355c8dac9f840d09.dywi@gentoo
1 commit: df58d07cbadab7bdd5f6a494355c8dac9f840d09
2 Author: André Erdmann <dywi <AT> mailerd <DOT> de>
3 AuthorDate: Tue Jun 25 21:08:01 2013 +0000
4 Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
5 CommitDate: Tue Jun 25 21:08:01 2013 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=df58d07c
7
8 EVENT_HOOK_RESTRICT, roverlay.hook
9
10 ---
11 roverlay/config/const.py | 4 ++
12 roverlay/config/entrymap.py | 29 +++++---
13 roverlay/hook.py | 169 ++++++++++++++++++++++++++++++++++++++++++++
14 roverlay/main.py | 7 +-
15 roverlay/tools/shenv.py | 22 ++----
16 5 files changed, 204 insertions(+), 27 deletions(-)
17
18 diff --git a/roverlay/config/const.py b/roverlay/config/const.py
19 index 4ee9d45..f9a2e14 100644
20 --- a/roverlay/config/const.py
21 +++ b/roverlay/config/const.py
22 @@ -78,6 +78,10 @@ _CONSTANTS = dict (
23 manifest_implementation = 'default',
24 ),
25
26 + EVENT_HOOK = dict (
27 + default_exe_relpath = [ 'hooks', 'mux.sh' ],
28 + ),
29 +
30 TOOLS = dict (
31 EBUILD = dict (
32 exe = "/usr/bin/ebuild",
33
34 diff --git a/roverlay/config/entrymap.py b/roverlay/config/entrymap.py
35 index 136b4b5..6a282d9 100644
36 --- a/roverlay/config/entrymap.py
37 +++ b/roverlay/config/entrymap.py
38 @@ -306,6 +306,12 @@ CONFIG_ENTRY_MAP = dict (
39 value_type = yesno,
40 ),
41
42 + overlay_distmap_file = dict (
43 + path = [ 'OVERLAY', 'DISTMAP', 'dbfile', ]
44 + value_type = 'fs_file',
45 + description = 'distmap file',
46 + ),
47 +
48 # * alias
49 backup_desc = 'overlay_backup_desc',
50 eclass = 'overlay_eclass',
51 @@ -316,6 +322,7 @@ CONFIG_ENTRY_MAP = dict (
52 distdir_strategy = 'overlay_distdir_strategy',
53 distdir_flat = 'overlay_distdir_flat',
54 distdir_verify = 'overlay_distdir_verify',
55 + distmap_file = 'overlay_distmap_file',
56
57 # --- overlay
58
59 @@ -449,14 +456,22 @@ CONFIG_ENTRY_MAP = dict (
60 description = 'filter shell env',
61 ),
62
63 - hook_script = dict (
64 - path = [ 'SHELL_ENV', 'hook', ],
65 - value_type = 'fs_file',
66 + event_hook = dict (
67 + path = [ 'EVENT_HOOK', 'exe', ],
68 + value_type = 'fs_file',
69 description = 'script that is run on certain events, e.g. overlay_success',
70 ),
71
72 + event_hook_restrict = dict (
73 + path = [ 'EVENT_HOOK', 'restrict', ],
74 + value_type = 'list:str',
75 + description = 'mask for running hooks',
76 + ),
77 +
78 +
79 # * alias
80 - hook = 'hook_script',
81 + hook = 'event_hook',
82 + hook_restrict = 'event_hook_restrict',
83
84
85 # == other ==
86 @@ -467,12 +482,6 @@ CONFIG_ENTRY_MAP = dict (
87 description = 'directory for cache data',
88 ),
89
90 - tmpdir = dict (
91 - path = [ 'TMPDIR', 'root', ],
92 - value_type = 'fs_dir',
93 - description = 'directory for temporary data',
94 - ),
95 -
96 nosync = dict (
97 value_type = yesno,
98 description = 'forbid/allow syncing with remotes',
99
100 diff --git a/roverlay/hook.py b/roverlay/hook.py
101 new file mode 100644
102 index 0000000..3b13315
103 --- /dev/null
104 +++ b/roverlay/hook.py
105 @@ -0,0 +1,169 @@
106 +# R overlay -- run roverlay hooks (shell scripts)
107 +# -*- coding: utf-8 -*-
108 +# Copyright (C) 2013 André Erdmann <dywi@×××××××.de>
109 +# Distributed under the terms of the GNU General Public License;
110 +# either version 2 of the License, or (at your option) any later version.
111 +
112 +import os.path
113 +import logging
114 +
115 +import roverlay.config
116 +import roverlay.tools.shenv
117 +
118 +__all__ = [ 'run_hook', 'phase_allowed', ]
119 +
120 +LOGGER = logging.getLogger ( 'event_hook' )
121 +
122 +
123 +_EVENT_SCRIPT = None
124 +
125 +# None|iterable _EVENT_RESTRICT
126 +_EVENT_RESTRICT = None
127 +
128 +# int _EVENT_POLICY
129 +# -1: no policy (allow all)
130 +# 0: not configured
131 +# 1: allow unless in _EVENT_RESTRICT (blacklist)
132 +# 2: deny unless in _EVENT_RESTRICT (whitelist)
133 +# 4: deny all
134 +_EVENT_POLICY = 0
135 +
136 +def setup():
137 + global _EVENT_SCRIPT
138 + global _EVENT_POLICY
139 + global _EVENT_RESTRICT
140 +
141 + _EVENT_SCRIPT = roverlay.config.get ( 'EVENT_HOOK.exe', False )
142 + if _EVENT_SCRIPT is False:
143 + a_dir = roverlay.config.get ( 'OVERLAY.additions_dir', None )
144 + if a_dir:
145 + s = os.path.join (
146 + a_dir,
147 + *roverlay.config.get_or_fail ( 'EVENT_HOOK.default_exe_relpath' )
148 + )
149 + if os.path.isfile ( s ):
150 + _EVENT_SCRIPT = s
151 + # -- end if _EVENT_SCRIPT
152 +
153 + conf_restrict = roverlay.config.get ( 'EVENT_HOOK.restrict', False )
154 +
155 + if conf_restrict:
156 + # tristate None,False,True
157 + is_whitelist = None
158 + allow = set()
159 + deny = set()
160 + for p in conf_restrict:
161 + if p == '*':
162 + # "allow all"
163 + is_whitelist = False
164 + elif p == '-*':
165 + # "deny all"
166 + is_whitelist = True
167 + elif p == '-' or p == '+':
168 + # empty
169 + pass
170 + elif p[0] == '-':
171 + # deny <k>
172 + k = p[1:].lower()
173 + deny.add ( k )
174 + try:
175 + allow.remove ( k )
176 + except KeyError:
177 + pass
178 + else:
179 + # allow <k>
180 + k = ( p[1:] if p[0] == '+' else p ).lower()
181 + allow.add ( k )
182 + try:
183 + deny.remove ( k )
184 + except KeyError:
185 + pass
186 + # -- end for;
187 +
188 + if is_whitelist is None:
189 + # allow is set => is whitelist
190 + # neither allow nor deny are set => deny allow
191 + is_whitelist = bool ( allow or not deny )
192 + # -- end if is_whitelist #1
193 +
194 + if is_whitelist:
195 + if allow:
196 + _EVENT_RESTRICT = frozenset ( allow )
197 + _EVENT_POLICY = 2
198 + else:
199 + _EVENT_POLICY = 4
200 + elif deny:
201 + _EVENT_RESTRICT = frozenset ( deny )
202 + _EVENT_POLICY = 1
203 + else:
204 + _EVENT_POLICY = -1
205 + # -- end if is_whitelist #2
206 + else:
207 + _EVENT_POLICY = -1
208 + # -- end if conf_restrict
209 +# --- end of setup (...) ---
210 +
211 +def phase_allowed ( phase ):
212 + if _EVENT_POLICY == -1:
213 + return True
214 + elif _EVENT_POLICY == 1:
215 + # allow unless in restrict
216 + if phase not in _EVENT_RESTRICT:
217 + return True
218 + else:
219 + LOGGER.debug (
220 + "phase {!r} denied by blacklist policy.".format ( phase )
221 + )
222 + elif _EVENT_POLICY == 2:
223 + # deny unless in restrict
224 + if phase in _EVENT_RESTRICT:
225 + return True
226 + else:
227 + LOGGER.debug (
228 + "phase {!r} denied by whitelist policy.".format ( phase )
229 + )
230 + elif _EVENT_POLICY == 4:
231 + LOGGER.debug (
232 + "phase {!r} denied by 'deny all' policy".format ( phase )
233 + )
234 + else:
235 + LOGGER.warning (
236 + "phase {!r} denied by undefined policy {} (fix this)".format (
237 + phase, _EVENT_POLICY
238 + )
239 + )
240 + # -- end if _EVENT_POLICY
241 +
242 + # default return
243 + return False
244 +# --- end of phase_allowed (...) ---
245 +
246 +def phase_allowed_nolog ( phase ):
247 + return (
248 + _EVENT_POLICY == -1
249 + ) or (
250 + _EVENT_POLICY == 1 and phase not in _EVENT_RESTRICT
251 + ) or (
252 + _EVENT_POLICY == 2 and phase in _EVENT_RESTRICT
253 + )
254 +# --- end of phase_allowed_nolog (...) ---
255 +
256 +def run ( phase ):
257 + if _EVENT_SCRIPT is None:
258 + LOGGER.warning (
259 + "hook module not initialized - doing that now (FIXME!)"
260 + )
261 + setup()
262 +
263 +
264 +
265 + if _EVENT_SCRIPT and phase_allowed ( phase ):
266 + return roverlay.tools.shenv.run_script (
267 + _EVENT_SCRIPT, phase, return_success=True
268 + )
269 + else:
270 + # nop
271 + return True
272 +# --- end of run (...) ---
273 +
274 +run_hook = run
275
276 diff --git a/roverlay/main.py b/roverlay/main.py
277 index 901cbcf..4822e21 100644
278 --- a/roverlay/main.py
279 +++ b/roverlay/main.py
280 @@ -289,7 +289,7 @@ def main (
281 # this hook should be called _after_ verifying the overlay
282 # (verification is not implemented yet)
283 #
284 - if not roverlay.tools.shenv.run_hook ( 'overlay_success' ):
285 + if not roverlay.hook.run ( 'overlay_success' ):
286 die ( "overlay_success hook returned non-zero", DIE.OV_CREATE )
287
288 set_action_done ( "create" )
289 @@ -476,7 +476,7 @@ def main (
290 from roverlay.overlay.creator import OverlayCreator
291
292 import roverlay.config
293 - import roverlay.tools.shenv
294 + import roverlay.hook
295 except ImportError:
296 if HIDE_EXCEPTIONS:
297 die ( "Cannot import roverlay modules!", DIE.IMPORT )
298 @@ -491,6 +491,9 @@ def main (
299
300 # -- run
301
302 + # initialize roverlay.hook
303 + roverlay.hook.setup()
304 +
305 # always run sync 'cause commands = {create,sync,apply_rules}
306 # and create,apply_rules implies (no)sync
307 run_sync()
308
309 diff --git a/roverlay/tools/shenv.py b/roverlay/tools/shenv.py
310 index 85644d4..f0c054b 100644
311 --- a/roverlay/tools/shenv.py
312 +++ b/roverlay/tools/shenv.py
313 @@ -1,4 +1,4 @@
314 -# R overlay -- tools, run roverlay hooks (shell scripts)
315 +# R overlay -- tools, shell script environment
316 # -*- coding: utf-8 -*-
317 # Copyright (C) 2013 André Erdmann <dywi@×××××××.de>
318 # Distributed under the terms of the GNU General Public License;
319 @@ -8,6 +8,7 @@ import logging
320 import os
321 import subprocess
322 import tempfile
323 +import time
324
325
326 import roverlay.config
327 @@ -18,7 +19,6 @@ import roverlay.util
328 # _SHELL_ENV, _SHELL_INTPR are created when calling run_script()
329 #
330 _SHELL_ENV = None
331 -_SHELL_ENV_SCRIPT = None
332 #_SHELL_INTPR = None
333 LOGGER = logging.getLogger ( 'shenv' )
334
335 @@ -287,7 +287,11 @@ def run_script ( script, phase, return_success=False, logger=None ):
336
337 output = script_call.communicate()
338 except:
339 - script_call.kill()
340 + try:
341 + script_call.terminate()
342 + time.sleep ( 1 )
343 + finally:
344 + script_call.kill()
345 raise
346
347
348 @@ -327,15 +331,3 @@ def run_script ( script, phase, return_success=False, logger=None ):
349 else:
350 return script_call
351 # --- end of run_script (...) ---
352 -
353 -def run_hook ( phase ):
354 - global _SHELL_ENV_SCRIPT
355 - if _SHELL_ENV_SCRIPT is None:
356 - _SHELL_ENV_SCRIPT = roverlay.config.get ( 'SHELL_ENV.hook', False )
357 -
358 - if _SHELL_ENV_SCRIPT:
359 - return run_script ( _SHELL_ENV_SCRIPT, phase, return_success=True )
360 - else:
361 - # nop
362 - return True
363 -# --- end of run_hook (...) ---