def refresh_user_map(configuration): """Refresh map of users and their configuration. Uses a pickled dictionary for efficiency. User IDs are stored in their raw (non-anonymized form). Only update map for users that updated conf after last map save. """ dirty = [] map_path = os.path.join(configuration.mig_system_files, "user.map") lock_path = os.path.join(configuration.mig_system_files, "user.lock") lock_handle = open(lock_path, 'a') fcntl.flock(lock_handle.fileno(), fcntl.LOCK_EX) user_map, map_stamp = load_user_map(configuration, do_lock=False) # Find all users and their configurations all_users = list_users(configuration.user_home) real_map = real_to_anon_user_map(configuration.user_home) for user in all_users: settings_path = os.path.join(configuration.user_settings, client_id_dir(user), settings_filename) profile_path = os.path.join(configuration.user_settings, client_id_dir(user), profile_filename) settings_mtime, profile_mtime = 0, 0 if os.path.isfile(settings_path): settings_mtime = os.path.getmtime(settings_path) if os.path.isfile(profile_path): profile_mtime = os.path.getmtime(profile_path) if settings_mtime + profile_mtime > 0: conf_mtime = max(settings_mtime, profile_mtime) else: conf_mtime = -1 # init first time user_map[user] = user_map.get(user, {}) if not user_map[user].has_key(CONF) or conf_mtime >= map_stamp: user_conf = get_user_conf(user, configuration, True) if not user_conf: user_conf = {} user_map[user][CONF] = user_conf public_id = user if user_conf.get('ANONYMOUS', True): public_id = real_map[user] user_map[user][USERID] = public_id user_map[user][MODTIME] = map_stamp dirty += [user] # Remove any missing users from map missing_user = [user for user in user_map.keys() \ if not user in all_users] for user in missing_user: del user_map[user] dirty += [user] if dirty: try: dump(user_map, map_path) except Exception, exc: configuration.logger.error("Could not save user map: %s" % exc)
def refresh_vgrid_map(configuration): """Refresh map of users and resources with their direct vgrid participation. That is, without inheritance. Uses a pickled dictionary for efficiency. Resource and user IDs are stored in their raw (non-anonymized form). Only update map for users and resources that updated conf after last map save. """ dirty = {} vgrid_changes = {} map_path = os.path.join(configuration.mig_system_files, "vgrid.map") lock_path = os.path.join(configuration.mig_system_files, "vgrid.lock") lock_handle = open(lock_path, 'a') fcntl.flock(lock_handle.fileno(), fcntl.LOCK_EX) vgrid_map, map_stamp = load_vgrid_map(configuration, do_lock=False) vgrid_helper = {default_vgrid: {RESOURCES: '*', OWNERS: '', MEMBERS: '*'}} if not vgrid_map.has_key(VGRIDS): vgrid_map[VGRIDS] = vgrid_helper dirty[VGRIDS] = dirty.get(VGRIDS, []) + [default_vgrid] if not vgrid_map.has_key(RESOURCES): vgrid_map[RESOURCES] = {} dirty[RESOURCES] = dirty.get(RESOURCES, []) if not vgrid_map.has_key(USERS): vgrid_map[USERS] = {} dirty[USERS] = dirty.get(USERS, []) # Find all vgrids and their allowed users and resources (status, all_vgrids) = vgrid_list_vgrids(configuration) if not status: all_vgrids = [] conf_read = [(RESOURCES, configuration.vgrid_resources, vgrid_resources), (OWNERS, configuration.vgrid_owners, vgrid_owners), (MEMBERS, configuration.vgrid_members, vgrid_members)] for vgrid in all_vgrids: 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): configuration.logger.warning('missing file: %s' % (conf_path)) # Make sure vgrid dict exists before filling it vgrid_map[VGRIDS][vgrid] = vgrid_map[VGRIDS].get(vgrid, {}) vgrid_map[VGRIDS][vgrid][field] = [] dirty[VGRIDS] = dirty.get(VGRIDS, []) + [vgrid] elif not vgrid_map[VGRIDS].has_key(vgrid) or \ os.path.getmtime(conf_path) >= map_stamp: (status, entries) = list_call(vgrid, configuration, recursive=False) if not status: entries = [] vgrid_changes[vgrid] = (vgrid_map[VGRIDS].get(vgrid, []), entries) vgrid_map[VGRIDS][vgrid] = vgrid_map[VGRIDS].get(vgrid, {}) vgrid_map[VGRIDS][vgrid][field] = entries dirty[VGRIDS] = dirty.get(VGRIDS, []) + [vgrid] # Remove any missing vgrids from map missing_vgrids = [vgrid for vgrid in vgrid_map[VGRIDS].keys() \ if not vgrid in all_vgrids] for vgrid in missing_vgrids: vgrid_changes[vgrid] = (vgrid_map[VGRIDS][vgrid], []) del vgrid_map[VGRIDS][vgrid] dirty[VGRIDS] = dirty.get(VGRIDS, []) + [vgrid] # Find all resources and their vgrid assignments # TODO: use get_resource_map output instead? all_resources = list_resources(configuration.resource_home, only_valid=True) real_map = real_to_anon_res_map(configuration.resource_home) for res in all_resources: # Sandboxes do not change their vgrid participation if vgrid_map[RESOURCES].has_key(res) and sandbox_resource(res): continue 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: vgrid_map[RESOURCES][res] = get_all_exe_vgrids(res) assigned = [] all_exes = [i for i in vgrid_map[RESOURCES][res].keys() \ if not i in RES_SPECIALS] for exe in all_exes: exe_vgrids = vgrid_map[RESOURCES][res][exe] assigned += [i for i in exe_vgrids if i and i not in assigned] vgrid_map[RESOURCES][res][ASSIGN] = assigned vgrid_map[RESOURCES][res][ALLOW] = vgrid_map[RESOURCES][res].get(ALLOW, []) public_id = res anon_val = get_resource_fields(configuration.resource_home, res, ['ANONYMOUS'], configuration.logger) if anon_val.get('ANONYMOUS', True): public_id = real_map[res] vgrid_map[RESOURCES][res][RESID] = public_id dirty[RESOURCES] = dirty.get(RESOURCES, []) + [res] # Remove any missing resources from map missing_res = [res for res in vgrid_map[RESOURCES].keys() \ if not res in all_resources] for res in missing_res: del vgrid_map[RESOURCES][res] dirty[RESOURCES] = dirty.get(RESOURCES, []) + [res] # Update list of mutually agreed vgrid participations for dirty resources # and resources assigned to dirty vgrids configuration.logger.info("update res vgrid participations: %s" % vgrid_changes) update_res = [i for i in dirty.get(RESOURCES, []) if i not in MAP_SECTIONS] # configuration.logger.info("update vgrid allow res") for (vgrid, (old, new)) in vgrid_changes.items(): # configuration.logger.info("update res vgrid %s" % vgrid) for res in [i for i in vgrid_map[RESOURCES].keys() \ if i not in update_res]: # Sandboxes do not change their vgrid participation if sandbox_resource(res): continue # configuration.logger.info("update res vgrid %s for res %s" % (vgrid, res)) if vgrid_allowed(res, old) != vgrid_allowed(res, new): update_res.append(res) # configuration.logger.info("update res assign vgrid") for res in [i for i in update_res if i not in missing_res]: allow = [] for vgrid in vgrid_map[RESOURCES][res][ASSIGN]: if vgrid_allowed(res, vgrid_map[VGRIDS][vgrid][RESOURCES]): allow.append(vgrid) vgrid_map[RESOURCES][res][ALLOW] = allow configuration.logger.info("done updating vgrid res participations") # Find all users and their vgrid assignments # TODO: use get_user_map output instead? all_users = list_users(configuration.user_home) real_map = real_to_anon_user_map(configuration.user_home) for user in all_users: settings_path = os.path.join(configuration.user_settings, client_id_dir(user), settings_filename) profile_path = os.path.join(configuration.user_settings, client_id_dir(user), profile_filename) settings_mtime, profile_mtime = 0, 0 if os.path.isfile(settings_path): settings_mtime = os.path.getmtime(settings_path) if os.path.isfile(profile_path): profile_mtime = os.path.getmtime(profile_path) if settings_mtime + profile_mtime > 0: conf_mtime = max(settings_mtime, profile_mtime) user_conf = get_user_conf(user, configuration) else: conf_mtime = -1 user_conf = {} if conf_mtime >= map_stamp: vgrid_map[USERS][user] = user_conf vgrid_map[USERS][user][ASSIGN] = vgrid_map[USERS][user].get(ASSIGN, []) vgrid_map[USERS][user][ALLOW] = vgrid_map[USERS][user].get(ALLOW, []) public_id = user if user_conf.get('ANONYMOUS', True): public_id = real_map[user] vgrid_map[USERS][user][USERID] = public_id dirty[USERS] = dirty.get(USERS, []) + [user] # Remove any missing users from map missing_user = [user for user in vgrid_map[USERS].keys() \ if not user in all_users] for user in missing_user: del vgrid_map[USERS][user] dirty[USERS] = dirty.get(USERS, []) + [user] # Update list of mutually agreed vgrid participations for dirty users # and users assigned to dirty vgrids update_user = [i for i in dirty.get(USERS, []) if i not in MAP_SECTIONS] for (vgrid, (old, new)) in vgrid_changes.items(): for user in [i for i in vgrid_map[USERS].keys() \ if i not in update_user]: if vgrid_allowed(user, old) != vgrid_allowed(user, new): update_user.append(user) for user in [i for i in update_user if i not in missing_user]: allow = [] for vgrid in vgrid_map[USERS][user][ASSIGN]: if vgrid_allowed(user, vgrid_map[VGRIDS][vgrid][OWNERS]) or \ vgrid_allowed(user, vgrid_map[VGRIDS][vgrid][MEMBERS]): allow.append(vgrid) # users implicitly assign all vgrids vgrid_map[USERS][user][ASSIGN] = allow vgrid_map[USERS][user][ALLOW] = allow if dirty: try: dump(vgrid_map, map_path) except Exception, exc: configuration.logger.error("Could not save vgrid map: %s" % exc)