def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) resource_list = accepted['unique_resource_name'] resource_id = resource_list.pop() res_dir = os.path.join(configuration.resource_home, resource_id) # Prevent unauthorized access (owner_status, owner_list) = resource_owners(configuration, resource_id) if not owner_status: output_objects.append( {'object_type': 'error_text', 'text' : "Could not look up '%s' owners - no such resource?" % resource_id }) return (output_objects, returnvalues.CLIENT_ERROR) elif client_id not in owner_list: logger.warning('user %s tried to delete resource "%s" not owned' % \ (client_id, resource_id)) output_objects.append({'object_type': 'error_text', 'text' : "You can't delete '%s' - you don't own it!" % resource_id}) output_objects.append({'object_type': 'link', 'destination': 'resman.py', 'class': 'infolink', 'title': 'Show resources', 'text': 'Show resources'}) return (output_objects, returnvalues.CLIENT_ERROR) # Locking the access to resources and vgrids. lock_path_vgrid = os.path.join(configuration.resource_home, "vgrid.lock") lock_handle_vgrid = open(lock_path_vgrid, 'a') fcntl.flock(lock_handle_vgrid.fileno(), fcntl.LOCK_EX) lock_path_res = os.path.join(configuration.resource_home, "resource.lock") lock_handle_res = open(lock_path_res, 'a') fcntl.flock(lock_handle_res.fileno(), fcntl.LOCK_EX) # Only resources that are down may be deleted. # A "FE.PGID" file with a PGID in the resource's home directory means that # the FE is running. pgid_path = os.path.join(res_dir, 'FE.PGID') fe_running = True try: # determine if fe runs by finding out if pgid is numerical pgid_file = open(pgid_path, 'r') fcntl.flock(pgid_file, fcntl.LOCK_EX) pgid = pgid_file.readline().strip() fcntl.flock(pgid_file, fcntl.LOCK_UN) pgid_file.close() if not pgid.isdigit(): raise Exception('FE already stopped') except: fe_running = False if fe_running: output_objects.append({'object_type': 'error_text', 'text' : "Can't delete the running resource %s!" % resource_id}) output_objects.append({'object_type': 'link', 'destination': 'resman.py', 'class': 'infolink', 'title': 'Show resources', 'text': 'Show resources'}) lock_handle_vgrid.close() lock_handle_res.close() return (output_objects, returnvalues.CLIENT_ERROR) # Deleting the resource files, but not the resource directory itself. # The resource directory is kept, to prevent hijacking of resource id's try: for name in os.listdir(res_dir): file_path = os.path.join(res_dir, name) if os.path.isfile(file_path): os.unlink(file_path) except Exception, err: output_objects.append({'object_type': 'error_text', 'text' : 'Deletion exception: ' + str(err)}) output_objects.append({'object_type': 'link', 'destination': 'resman.py', 'class': 'infolink', 'title': 'Show resources', 'text': 'Show resources'}) lock_handle_vgrid.close() lock_handle_res.close() return (output_objects, returnvalues.CLIENT_ERROR)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] if not configuration.site_enable_resources: output_objects.append({ 'object_type': 'error_text', 'text': '''Resources are not enabled on this system''' }) return (output_objects, returnvalues.SYSTEM_ERROR) # IMPORTANT: we can not validate input completely here! # We validate the parts used in the path manipulation and only use # the remaining variables directly in the generated config file that # is then handed to the parser for full validation. critical_arguments = {} critical_fields = defaults.keys() # IMPORTANT: we must explicitly inlude CSRF token critical_fields.append(csrf_field) for field in critical_fields: critical_arguments[field] = user_arguments_dict.get(field, ['']) (validate_status, accepted) = validate_input_and_cert( critical_arguments, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) hosturl = accepted['HOSTURL'][-1] hostidentifier = accepted['HOSTIDENTIFIER'][-1] if hostidentifier: action = 'update' else: action = 'create' hostidentifier = keyword_auto accepted['HOSTIDENTIFIER'] = [hostidentifier] resource_id = "%s.%s" % (hosturl, hostidentifier) if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) # Override original critical values with the validated ones for field in critical_fields: user_arguments_dict[field] = accepted[field] status = returnvalues.OK title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Resource edit actions' output_objects.append({ 'object_type': 'header', 'text': 'Resource edit actions' }) conf = prepare_conf(configuration, user_arguments_dict, resource_id) if 'create' == action: logger.info('%s is trying to create resource %s (%s)' % (client_id, hosturl, conf)) output_objects.append({ 'object_type': 'sectionheader', 'text': 'Creating resource configuration' }) # We only get here if hostidentifier is dynamic so no access control if not handle_update(configuration, client_id, resource_id, conf, output_objects, True): status = returnvalues.SYSTEM_ERROR elif 'update' == action: logger.info('%s is trying to update resource %s (%s)' % (client_id, resource_id, conf)) output_objects.append({ 'object_type': 'sectionheader', 'text': 'Updating existing resource configuration' }) # Prevent unauthorized access to existing resources (owner_status, owner_list) = resource_owners(configuration, resource_id) if not owner_status: output_objects.append({ 'object_type': 'error_text', 'text': "Could not look up '%s' owners - no such resource?" % resource_id }) status = returnvalues.SYSTEM_ERROR elif client_id in owner_list: if not handle_update(configuration, client_id, resource_id, conf, output_objects, False): status = returnvalues.SYSTEM_ERROR else: status = returnvalues.CLIENT_ERROR output_objects.append({ 'object_type': 'error_text', 'text': 'You can only update your own resources!' }) else: status = returnvalues.CLIENT_ERROR output_objects.append({ 'object_type': 'error_text', 'text': 'Unknown action request!' }) return (output_objects, status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] ### IMPORTANT: we can not validate input completely here! # We validate the parts used in the path manipulation and only use # the remaining variables directly in the generated config file that # is then handed to the parser for full validation. critical_arguments = {} critical_fields = defaults.keys() for field in critical_fields: critical_arguments[field] = user_arguments_dict.get(field, ['']) (validate_status, accepted) = validate_input_and_cert( critical_arguments, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) hosturl = accepted['HOSTURL'][-1] hostidentifier = accepted['HOSTIDENTIFIER'][-1] if hostidentifier: action = 'update' else: action = 'create' hostidentifier = '$HOSTIDENTIFIER' accepted['HOSTIDENTIFIER'] = [hostidentifier] resource_id = "%s.%s" % (hosturl, hostidentifier) # Override original critical values with the validated ones for field in critical_fields: user_arguments_dict[field] = accepted[field] status = returnvalues.OK title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Resource edit actions' output_objects.append({'object_type': 'header', 'text': 'Resource edit actions'}) conf = prepare_conf(configuration, user_arguments_dict, resource_id) if 'create' == action: logger.info('%s is trying to create resource %s (%s)' % \ (client_id, hosturl, conf)) output_objects.append({'object_type': 'sectionheader', 'text' : 'Creating resource configuration'}) # We only get here if hostidentifier is dynamic so no access control if not handle_update(configuration, client_id, resource_id, conf, output_objects, True): status = returnvalues.SYSTEM_ERROR elif 'update' == action: logger.info('%s is trying to update resource %s (%s)' % \ (client_id, resource_id, conf)) output_objects.append({'object_type': 'sectionheader', 'text' : 'Updating existing resource configuration'}) # Prevent unauthorized access to existing resources (owner_status, owner_list) = resource_owners(configuration, resource_id) if not owner_status: output_objects.append( {'object_type': 'error_text', 'text' : "Could not look up '%s' owners - no such resource?" % \ resource_id}) status = returnvalues.SYSTEM_ERROR elif client_id in owner_list: if not handle_update(configuration, client_id, resource_id, conf, output_objects, False): status = returnvalues.SYSTEM_ERROR else: status = returnvalues.CLIENT_ERROR output_objects.append({'object_type': 'error_text', 'text' : 'You can only update your own resources!' }) else: status = returnvalues.CLIENT_ERROR output_objects.append({'object_type': 'error_text', 'text' : 'Unknown action request!' }) return (output_objects, status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] title_entry = find_entry(output_objects, 'title') label = "%s" % configuration.site_vgrid_label title_entry['text'] = '%s send request' % configuration.short_title output_objects.append({ 'object_type': 'header', 'text': '%s send request' % configuration.short_title }) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) target_id = client_id vgrid_name = accepted['vgrid_name'][-1].strip() visible_user_names = accepted['cert_id'] visible_res_names = accepted['unique_resource_name'] request_type = accepted['request_type'][-1].strip().lower() request_text = accepted['request_text'][-1].strip() protocols = [proto.strip() for proto in accepted['protocol']] use_any = False if any_protocol in protocols: use_any = True protocols = configuration.notify_protocols protocols = [proto.lower() for proto in protocols] if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) valid_request_types = [ 'resourceowner', 'resourceaccept', 'resourcereject', 'vgridowner', 'vgridmember', 'vgridresource', 'vgridaccept', 'vgridreject', 'plain' ] if not request_type in valid_request_types: output_objects.append({ 'object_type': 'error_text', 'text': '%s is not a valid request_type (valid types: %s)!' % (request_type.lower(), valid_request_types) }) return (output_objects, returnvalues.CLIENT_ERROR) if not protocols: output_objects.append({ 'object_type': 'error_text', 'text': 'No protocol specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) user_map = get_user_map(configuration) reply_to = user_map[client_id][USERID] # Try to point replies to client_id email client_email = extract_field(reply_to, 'email') if request_type == "plain": if not visible_user_names: output_objects.append({ 'object_type': 'error_text', 'text': 'No user ID specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) user_id = visible_user_names[-1].strip() anon_map = anon_to_real_user_map(configuration) if anon_map.has_key(user_id): user_id = anon_map[user_id] if not user_map.has_key(user_id): output_objects.append({ 'object_type': 'error_text', 'text': 'No such user: %s' % user_id }) return (output_objects, returnvalues.CLIENT_ERROR) target_name = user_id user_dict = user_map[user_id] vgrid_access = user_vgrid_access(configuration, client_id) vgrids_allow_email = user_dict[CONF].get('VGRIDS_ALLOW_EMAIL', []) vgrids_allow_im = user_dict[CONF].get('VGRIDS_ALLOW_IM', []) if any_vgrid in vgrids_allow_email: email_vgrids = vgrid_access else: email_vgrids = set(vgrids_allow_email).intersection(vgrid_access) if any_vgrid in vgrids_allow_im: im_vgrids = vgrid_access else: im_vgrids = set(vgrids_allow_im).intersection(vgrid_access) if use_any: # Do not try disabled protocols if ANY was requested if not email_vgrids: protocols = [ proto for proto in protocols if proto not in email_keyword_list ] if not im_vgrids: protocols = [ proto for proto in protocols if proto in email_keyword_list ] if not email_vgrids and [ proto for proto in protocols if proto in email_keyword_list ]: output_objects.append({ 'object_type': 'error_text', 'text': 'You are not allowed to send emails to %s!' % user_id }) return (output_objects, returnvalues.CLIENT_ERROR) if not im_vgrids and [ proto for proto in protocols if proto not in email_keyword_list ]: output_objects.append({ 'object_type': 'error_text', 'text': 'You are not allowed to send instant messages to %s!' % user_id }) return (output_objects, returnvalues.CLIENT_ERROR) for proto in protocols: if not user_dict[CONF].get(proto.upper(), False): if use_any: # Remove missing protocols if ANY protocol was requested protocols = [i for i in protocols if i != proto] else: output_objects.append({ 'object_type': 'error_text', 'text': 'User %s does not accept %s messages!' % (user_id, proto) }) return (output_objects, returnvalues.CLIENT_ERROR) if not protocols: output_objects.append({ 'object_type': 'error_text', 'text': 'User %s does not accept requested protocol(s) messages!' % user_id }) return (output_objects, returnvalues.CLIENT_ERROR) target_list = [user_id] elif request_type in ["vgridaccept", "vgridreject"]: # Always allow accept messages but only between owners/members if not visible_user_names and not visible_res_names: output_objects.append({ 'object_type': 'error_text', 'text': 'No user or resource ID specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) if not vgrid_name: output_objects.append({ 'object_type': 'error_text', 'text': 'No vgrid_name specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) if vgrid_name.upper() == default_vgrid.upper(): output_objects.append({ 'object_type': 'error_text', 'text': 'No requests for %s are allowed!' % default_vgrid }) return (output_objects, returnvalues.CLIENT_ERROR) if not vgrid_is_owner(vgrid_name, client_id, configuration): output_objects.append({ 'object_type': 'error_text', 'text': 'You are not an owner of %s or a parent %s!' % (vgrid_name, label) }) return (output_objects, returnvalues.CLIENT_ERROR) # NOTE: we support exactly one vgrid but multiple users/resources here if visible_user_names: logger.info("setting user recipients: %s" % visible_user_names) target_list = [user_id.strip() for user_id in visible_user_names] elif visible_res_names: # vgrid resource accept - lookup and notify resource owners logger.info("setting res owner recipients: %s" % visible_res_names) target_list = [] for unique_resource_name in visible_res_names: logger.info("loading res owners for %s" % unique_resource_name) (load_status, res_owners) = resource_owners(configuration, unique_resource_name) if not load_status: output_objects.append({ 'object_type': 'error_text', 'text': 'Could not lookup owners of %s!' % unique_resource_name }) continue logger.info("adding res owners to recipients: %s" % res_owners) target_list += [user_id for user_id in res_owners] target_id = '%s %s owners' % (vgrid_name, label) target_name = vgrid_name elif request_type in ["resourceaccept", "resourcereject"]: # Always allow accept messages between actual resource owners if not visible_user_names: output_objects.append({ 'object_type': 'error_text', 'text': 'No user ID specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) if not visible_res_names: output_objects.append({ 'object_type': 'error_text', 'text': 'No resource ID specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) # NOTE: we support exactly one resource but multiple users here unique_resource_name = visible_res_names[-1].strip() target_name = unique_resource_name res_map = get_resource_map(configuration) if not res_map.has_key(unique_resource_name): output_objects.append({ 'object_type': 'error_text', 'text': 'No such resource: %s' % unique_resource_name }) return (output_objects, returnvalues.CLIENT_ERROR) owners_list = res_map[unique_resource_name][OWNERS] if not client_id in owners_list: output_objects.append({ 'object_type': 'error_text', 'text': 'You are not an owner of %s!' % unique_resource_name }) output_objects.append({ 'object_type': 'error_text', 'text': 'Invalid resource %s message!' % request_type }) return (output_objects, returnvalues.CLIENT_ERROR) target_id = '%s resource owners' % unique_resource_name target_name = unique_resource_name target_list = [user_id.strip() for user_id in visible_user_names] elif request_type == "resourceowner": if not visible_res_names: output_objects.append({ 'object_type': 'error_text', 'text': 'No resource ID specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) # NOTE: we support exactly one resource but multiple users here unique_resource_name = visible_res_names[-1].strip() anon_map = anon_to_real_res_map(configuration.resource_home) if anon_map.has_key(unique_resource_name): unique_resource_name = anon_map[unique_resource_name] target_name = unique_resource_name res_map = get_resource_map(configuration) if not res_map.has_key(unique_resource_name): output_objects.append({ 'object_type': 'error_text', 'text': 'No such resource: %s' % unique_resource_name }) return (output_objects, returnvalues.CLIENT_ERROR) target_list = res_map[unique_resource_name][OWNERS] if client_id in target_list: output_objects.append({ 'object_type': 'error_text', 'text': 'You are already an owner of %s!' % unique_resource_name }) return (output_objects, returnvalues.CLIENT_ERROR) request_dir = os.path.join(configuration.resource_home, unique_resource_name) access_request = { 'request_type': request_type, 'entity': client_id, 'target': unique_resource_name, 'request_text': request_text } if not save_access_request(configuration, request_dir, access_request): output_objects.append({ 'object_type': 'error_text', 'text': 'Could not save request - owners may still manually add you' }) return (output_objects, returnvalues.SYSTEM_ERROR) elif request_type in ["vgridmember", "vgridowner", "vgridresource"]: if not vgrid_name: output_objects.append({ 'object_type': 'error_text', 'text': 'No vgrid_name specified!' }) return (output_objects, returnvalues.CLIENT_ERROR) # default vgrid is read-only if vgrid_name.upper() == default_vgrid.upper(): output_objects.append({ 'object_type': 'error_text', 'text': 'No requests for %s are not allowed!' % default_vgrid }) return (output_objects, returnvalues.CLIENT_ERROR) # stop owner or member request if already an owner # and prevent repeated resource access requests if request_type == 'vgridresource': # NOTE: we support exactly one resource here unique_resource_name = visible_res_names[-1].strip() target_id = entity = unique_resource_name if vgrid_is_resource(vgrid_name, unique_resource_name, configuration): output_objects.append({ 'object_type': 'error_text', 'text': 'You already have access to %s or a parent %s.' % (vgrid_name, label) }) return (output_objects, returnvalues.CLIENT_ERROR) else: target_id = entity = client_id if vgrid_is_owner(vgrid_name, client_id, configuration): output_objects.append({ 'object_type': 'error_text', 'text': 'You are already an owner of %s or a parent %s!' % (vgrid_name, label) }) return (output_objects, returnvalues.CLIENT_ERROR) # only ownership requests are allowed for existing members if request_type == 'vgridmember': if vgrid_is_member(vgrid_name, client_id, configuration): output_objects.append({ 'object_type': 'error_text', 'text': 'You are already a member of %s or a parent %s.' % (vgrid_name, label) }) return (output_objects, returnvalues.CLIENT_ERROR) # Find all VGrid owners configured to receive notifications target_name = vgrid_name (settings_status, settings_dict) = vgrid_settings(vgrid_name, configuration, recursive=True, as_dict=True) if not settings_status: settings_dict = {} request_recipients = settings_dict.get('request_recipients', default_vgrid_settings_limit) # We load and use direct owners first if any - otherwise inherited owners_list = [] for inherited in (False, True): (owners_status, owners_list) = vgrid_owners(vgrid_name, configuration, recursive=inherited) if not owners_status: output_objects.append({ 'object_type': 'error_text', 'text': 'Failed to lookup owners for %s %s - sure it exists?' % (vgrid_name, label) }) return (output_objects, returnvalues.CLIENT_ERROR) elif owners_list: break if not owners_list: output_objects.append({ 'object_type': 'error_text', 'text': 'Failed to lookup owners for %s %s - sure it exists?' % (vgrid_name, label) }) return (output_objects, returnvalues.CLIENT_ERROR) # Now we have direct or inherited owners to notify target_list = owners_list[:request_recipients] request_dir = os.path.join(configuration.vgrid_home, vgrid_name) access_request = { 'request_type': request_type, 'entity': entity, 'target': vgrid_name, 'request_text': request_text } if not save_access_request(configuration, request_dir, access_request): output_objects.append({ 'object_type': 'error_text', 'text': 'Could not save request - owners may still manually add you' }) return (output_objects, returnvalues.SYSTEM_ERROR) else: output_objects.append({ 'object_type': 'error_text', 'text': 'Invalid request type: %s' % request_type }) return (output_objects, returnvalues.CLIENT_ERROR) # Now send request to all targets in turn # TODO: inform requestor if no owners have mail/IM set in their settings logger.debug("sending notification to recipients: %s" % target_list) for target in target_list: if not target: logger.warning("skipping empty notify target: %s" % target_list) continue # USER_CERT entry is destination notify = [] for proto in protocols: notify.append('%s: SETTINGS' % proto) job_dict = { 'NOTIFY': notify, 'JOB_ID': 'NOJOBID', 'USER_CERT': target, 'EMAIL_SENDER': client_email } notifier = notify_user_thread( job_dict, [target_id, target_name, request_type, request_text, reply_to], 'SENDREQUEST', logger, '', configuration, ) # Try finishing delivery but do not block forever on one message notifier.join(30) output_objects.append({ 'object_type': 'text', 'text': 'Sent %s message to %d people' % (request_type, len(target_list)) }) output_objects.append({ 'object_type': 'text', 'text': """Please make sure you have notifications configured on your Setings page if you expect a reply to this message""" }) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) resource_list = accepted['unique_resource_name'] resource_id = resource_list.pop() if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append( {'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) res_dir = os.path.join(configuration.resource_home, resource_id) # Prevent unauthorized access (owner_status, owner_list) = resource_owners(configuration, resource_id) if not owner_status: output_objects.append( {'object_type': 'error_text', 'text' : "Could not look up '%s' owners - no such resource?" % resource_id }) return (output_objects, returnvalues.CLIENT_ERROR) elif client_id not in owner_list: logger.warning('user %s tried to delete resource "%s" not owned' % \ (client_id, resource_id)) output_objects.append({'object_type': 'error_text', 'text' : "You can't delete '%s' - you don't own it!" % resource_id}) output_objects.append({'object_type': 'link', 'destination': 'resman.py', 'class': 'infolink iconspace', 'title': 'Show resources', 'text': 'Show resources'}) return (output_objects, returnvalues.CLIENT_ERROR) # Locking the access to resources and vgrids. lock_path_vgrid = os.path.join(configuration.resource_home, "vgrid.lock") lock_handle_vgrid = open(lock_path_vgrid, 'a') fcntl.flock(lock_handle_vgrid.fileno(), fcntl.LOCK_EX) lock_path_res = os.path.join(configuration.resource_home, "resource.lock") lock_handle_res = open(lock_path_res, 'a') fcntl.flock(lock_handle_res.fileno(), fcntl.LOCK_EX) # Only resources that are down may be deleted. # A "FE.PGID" file with a PGID in the resource's home directory means that # the FE is running. pgid_path = os.path.join(res_dir, 'FE.PGID') fe_running = True try: # determine if fe runs by finding out if pgid is numerical pgid_file = open(pgid_path, 'r') fcntl.flock(pgid_file, fcntl.LOCK_EX) pgid = pgid_file.readline().strip() fcntl.flock(pgid_file, fcntl.LOCK_UN) pgid_file.close() if not pgid.isdigit(): raise Exception('FE already stopped') except: fe_running = False if fe_running: output_objects.append({'object_type': 'error_text', 'text' : "Can't delete the running resource %s!" % resource_id}) output_objects.append({'object_type': 'link', 'destination': 'resman.py', 'class': 'infolink iconspace', 'title': 'Show resources', 'text': 'Show resources'}) lock_handle_vgrid.close() lock_handle_res.close() return (output_objects, returnvalues.CLIENT_ERROR) # Deleting the resource files, but not the resource directory itself. # The resource directory is kept, to prevent hijacking of resource id's try: for name in os.listdir(res_dir): file_path = os.path.join(res_dir, name) if os.path.isfile(file_path): os.unlink(file_path) except Exception, err: output_objects.append({'object_type': 'error_text', 'text' : 'Deletion exception: ' + str(err)}) output_objects.append({'object_type': 'link', 'destination': 'resman.py', 'class': 'infolink iconspace', 'title': 'Show resources', 'text': 'Show resources'}) lock_handle_vgrid.close() lock_handle_res.close() return (output_objects, returnvalues.CLIENT_ERROR)