From e0ac249ecdb93909a8d47e6b5aea40936ff809f0 Mon Sep 17 00:00:00 2001 From: Jonas Bardino Date: Sun, 2 Nov 2025 14:07:16 +0100 Subject: [PATCH 1/2] Rework `refresh_vgrid_map` in order to init all vgrid entries in `VGRIDS` early and to never skip init of the individual fields in those vgrid dicts, even if the source file for the corresponding field (like `owners` or `members`) is older than the map timestamp of the current vgrid map file. That should address a potential race when vgrids are modified during long-running refresh calls and any other causes for those fields missing in the existing map. Remove an unused leftover variable in check_vgrid_access. --- mig/shared/vgridaccess.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mig/shared/vgridaccess.py b/mig/shared/vgridaccess.py index 2c9f46e07..054ae27db 100644 --- a/mig/shared/vgridaccess.py +++ b/mig/shared/vgridaccess.py @@ -401,18 +401,18 @@ def refresh_vgrid_map(configuration, clean=False): optional_conf = [SETTINGS, ] for vgrid in all_vgrids: + # Make sure vgrid dict exists before filling it + vgrid_map[VGRIDS][vgrid] = vgrid_map[VGRIDS].get(vgrid, {}) for (field, name, list_call) in conf_read: conf_path = os.path.join(configuration.vgrid_home, vgrid, name) if not os.path.isfile(conf_path): - # Make sure vgrid dict exists before filling it - vgrid_map[VGRIDS][vgrid] = vgrid_map[VGRIDS].get(vgrid, {}) vgrid_map[VGRIDS][vgrid][field] = [] if vgrid != default_vgrid and field not in optional_conf: _logger.warning('missing file: %s' % conf_path) dirty[VGRIDS] = dirty.get(VGRIDS, []) + [vgrid] - elif vgrid not in vgrid_map[VGRIDS] or \ + elif field not in vgrid_map[VGRIDS][vgrid] or \ os.path.getmtime(conf_path) >= map_stamp: (status, entries) = list_call(vgrid, configuration, recursive=False) @@ -425,6 +425,8 @@ def refresh_vgrid_map(configuration, clean=False): vgrid_map[VGRIDS][vgrid] = map_entry vgrid_map[VGRIDS][vgrid][field] = entries dirty[VGRIDS] = dirty.get(VGRIDS, []) + [vgrid] + else: + _logger.debug("caching %s for %s in vgrid map" % (name, vgrid)) # Remove any missing vgrids from map missing_vgrids = [vgrid for vgrid in vgrid_map[VGRIDS] if not vgrid in all_vgrids] @@ -853,7 +855,6 @@ def check_vgrid_access(configuration, client_id, vgrid_name, recursive=True, the vgrid module and should replace that one everywhere that only vgrid map (cached) lookups are needed. """ - vgrid_access = [default_vgrid] vgrid_map = get_vgrid_map(configuration, recursive, caching) vgrid_entry = vgrid_map.get(VGRIDS, {}).get( vgrid_name, {OWNERS: [], MEMBERS: []}) From e0da4843b4b1226c300297460cd6e4e059e970d1 Mon Sep 17 00:00:00 2001 From: Jonas Bardino Date: Sun, 2 Nov 2025 22:36:09 +0100 Subject: [PATCH 2/2] Apply same idea to the update of `RESOURCES` and `USERS` in `refresh_vgrid_map` as recently introduced for the `VGRIDS` update there. It appears to also solve the last remaining spurious test errors in CI for PR #372. --- mig/shared/vgridaccess.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mig/shared/vgridaccess.py b/mig/shared/vgridaccess.py index 054ae27db..2988d54a0 100644 --- a/mig/shared/vgridaccess.py +++ b/mig/shared/vgridaccess.py @@ -451,7 +451,8 @@ def refresh_vgrid_map(configuration, clean=False): conf_path = os.path.join(configuration.resource_home, res, "config") if not os.path.isfile(conf_path): continue - if os.path.getmtime(conf_path) >= map_stamp: + if res not in vgrid_map[RESOURCES] or \ + os.path.getmtime(conf_path) >= map_stamp: # Read maps of exe name to vgrid list and of store name to vgrid # list. Save them separately to be able to distinguish them in # exe / store access and visibility @@ -562,7 +563,7 @@ def refresh_vgrid_map(configuration, clean=False): else: conf_mtime = -1 user_conf = {} - if conf_mtime >= map_stamp: + if user not in vgrid_map[USERS] or conf_mtime >= map_stamp: vgrid_map[USERS][user] = user_conf vgrid_map[USERS][user][ASSIGN] = vgrid_map[USERS][user].get(ASSIGN, [])