Skip to content

Commit 00eaa60

Browse files
committed
T9146: add initial set/call_dependencies as exempt from possible cycle
The category of initial set/call_dependents only apply when the script is called natively, and not as a dependency. This allows an exemption from a possible dependency cycle.
1 parent d2b54b9 commit 00eaa60

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

python/vyos/configdep.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
'config-mode-dependencies')
3535

3636
dependency_list: list[typing.Callable] = []
37+
dependency_list_initial: list[typing.Callable] = []
3738

3839
DEBUG = False
3940

@@ -181,6 +182,15 @@ def called_as_dependent() -> bool:
181182
return True
182183
return False
183184

185+
186+
def parent_called_as_dependent() -> bool:
187+
st = stack()[2:]
188+
for f in st:
189+
if f.filename == __file__:
190+
return True
191+
return False
192+
193+
184194
def graph_from_dependency_dict(d: dict) -> dict:
185195
g = {}
186196
for k in list(d):
@@ -214,3 +224,58 @@ def check_dependency_graph(dependency_dir: str = dependency_dir,
214224
d = dict_merge(json.load(f), d)
215225

216226
return is_acyclic(d)
227+
228+
229+
def def_closure_initial(
230+
target: str, config: 'Config', tagnode: typing.Optional[str] = None
231+
) -> typing.Callable:
232+
def func_impl():
233+
if tagnode is not None:
234+
os.environ['VYOS_TAGNODE_VALUE'] = tagnode
235+
run_config_mode_script(target, config)
236+
237+
tag_ext = f'_{tagnode}' if tagnode is not None else ''
238+
func_impl.__name__ = f'{target}{tag_ext}'
239+
240+
return func_impl
241+
242+
243+
def set_dependents_initial(
244+
target: str, config: 'Config', tagnode: typing.Optional[str] = None
245+
):
246+
if parent_called_as_dependent():
247+
return
248+
249+
k = caller_name()
250+
lst = dependency_list_initial
251+
252+
func = def_closure(target, config, tagnode)
253+
append_uniq(lst, func)
254+
255+
debug_print(
256+
f'set_dependents_initial: caller {k}, current dependents {names_of(lst)}'
257+
)
258+
259+
260+
def call_dependents_initial():
261+
# pylint: disable=global-statement
262+
global dependency_list_initial
263+
264+
if parent_called_as_dependent():
265+
return
266+
267+
k = caller_name()
268+
lst = dependency_list_initial
269+
debug_print(
270+
f'call_dependents_initial: caller {k}, remaining dependents {names_of(lst)}'
271+
)
272+
273+
while lst:
274+
f = lst.pop(0)
275+
debug_print(f'calling: {f.__name__}')
276+
try:
277+
f()
278+
except ConfigError as e:
279+
s = f'dependent {f.__name__}: {str(e)}'
280+
dependency_list_initial = []
281+
raise ConfigError(s) from e

0 commit comments

Comments
 (0)