def write_resource_config(configuration, resource_conf, conf_path): """Write resource_conf dictionary settings into conf_path on disk""" lines = [] for (field, __) in resconfkeywords.get_resource_specs(configuration): value = resource_conf.get(field, None) if value: if 'RUNTIMEENVIRONMENT' == field: lines.append('::%s::' % field) for (re_name, env_pairs) in value: lines.append('name: %s' % re_name) for (env_name, env_val) in env_pairs: lines.append('%s=%s' % (env_name, env_val)) lines.append('') elif 'EXECONFIG' == field: for exe in resource_conf['EXECONFIG']: lines.append('::%s::' % field) for (exe_field, __ ) in resconfkeywords.get_exenode_specs(configuration): if exe_field.endswith('vgrid'): lines.append('%s=%s' % (exe_field, ','.join(exe[exe_field]))) else: lines.append('%s=%s' % (exe_field, exe[exe_field])) lines.append('') elif 'STORECONFIG' == field: for store in resource_conf['STORECONFIG']: lines.append('::%s::' % field) for (store_field, __) in resconfkeywords.get_storenode_specs( configuration): if store_field.endswith('vgrid'): lines.append( '%s=%s' % (store_field, ','.join(store[store_field]))) else: lines.append('%s=%s' % (store_field, store[store_field])) lines.append('') else: lines.append('::%s::' % field) lines.append('%s' % value) lines.append('') if not os.path.isdir(os.path.dirname(conf_path)): os.makedirs(os.path.dirname(conf_path)) conf_fd = open(conf_path, 'w') conf_fd.write('\n'.join(lines)) conf_fd.close() return lines
def write_resource_config(configuration, resource_conf, conf_path): """Write resource_conf dictionary settings into conf_path on disk""" lines = [] for (field, __) in resconfkeywords.get_resource_specs(configuration): value = resource_conf.get(field, None) if value: if 'RUNTIMEENVIRONMENT' == field: lines.append('::%s::' % field) for (re_name, env_pairs) in value: lines.append('name: %s' % re_name) for (env_name, env_val) in env_pairs: lines.append('%s=%s' % (env_name, env_val)) lines.append('') elif 'EXECONFIG' == field: for exe in resource_conf['EXECONFIG']: lines.append('::%s::' % field) for (exe_field, __) in resconfkeywords.get_exenode_specs(configuration): if exe_field.endswith('vgrid'): lines.append('%s=%s' % (exe_field, ','.join(exe[exe_field]))) else: lines.append('%s=%s' % (exe_field, exe[exe_field])) lines.append('') elif 'STORECONFIG' == field: for store in resource_conf['STORECONFIG']: lines.append('::%s::' % field) for (store_field, __) in resconfkeywords.get_storenode_specs(configuration): if store_field.endswith('vgrid'): lines.append('%s=%s' % (store_field, ','.join(store[store_field]))) else: lines.append('%s=%s' % (store_field, store[store_field])) lines.append('') else: lines.append('::%s::' % field) lines.append('%s' % value) lines.append('') if not os.path.isdir(os.path.dirname(conf_path)): os.makedirs(os.path.dirname(conf_path)) conf_fd = open(conf_path, 'w') conf_fd.write('\n'.join(lines)) conf_fd.close() return lines
def prepare_conf(configuration, input_args, resource_id): """Update minimally validated user input dictionary to one suitable for resource conf parsing. """ # Flatten list structure for all fields except vgrid ones user_args = {} for (key, val) in input_args.items(): if key.endswith('vgrid'): user_args[key] = val else: user_args[key] = val[-1].strip() # Merge the variable fields like runtimeenvironmentX and re_valuesX # pairs into the final form suitable for parsing. Both fields # should exist for all X in range(0, runtime_env_fields) . re_list = [] field_count = 0 field_count_arg = user_args.get('runtime_env_fields', None) if field_count_arg: field_count = int(field_count_arg) del user_args['runtime_env_fields'] for i in range(field_count): runtime_env = 'runtimeenvironment' + str(i) env_values = 're_values' + str(i) if user_args.has_key(runtime_env): if user_args.has_key(env_values): # re_valuesX is a single line, A=vx yz\nB=def, with all assignments var_lines = user_args[env_values].split('\n') re_values = [tuple(line.split('=', 1)) for line in var_lines] del user_args[env_values] else: re_values = [] re_list.append((user_args[runtime_env], re_values)) del user_args[runtime_env] user_args['RUNTIMEENVIRONMENT'] = re_list frontend_home = user_args.get('frontendhome', None) if frontend_home: if not user_args.get('RESOURCEHOME', None): user_args['RESOURCEHOME'] = frontend_home del user_args['frontendhome'] execution_leader = False if user_args.get('LRMSTYPE', '').find('-execution-leader') != -1: execution_leader = True all_exes = [] execution_nodes = user_args.get('exe-executionnodes', '') exe_names = retrieve_execution_nodes(execution_nodes, execution_leader) for name in exe_names: exe = {} if not user_args.get('exe-execution_dir', None): user_args['exe-execution_dir'] = user_args.get( 'exe-executionhome', '') for (key, __) in resconfkeywords.get_exenode_specs(configuration): exe[key] = user_args.get("exe-%s" % key, '') exe['name'] = exe['execution_node'] = name all_exes.append(exe) user_args['EXECONFIG'] = all_exes all_stores = [] storage_nodes = user_args.get('store-storagenodes', '') store_names = retrieve_storage_nodes(storage_nodes) for name in store_names: store = {} if not user_args.get('store-storage_dir', None): user_args['store-storage_dir'] = user_args.get( 'store-storagehome', '') for (key, __) in resconfkeywords.get_storenode_specs(configuration): store[key] = user_args.get("store-%s" % key, '') store['name'] = store['storage_node'] = name all_stores.append(store) user_args['STORECONFIG'] = all_stores for key in user_args.keys(): if key.startswith('exe-') or key.startswith('store-'): del user_args[key] conf = {} conf.update(user_args) # Now all fields should be valid conf fields, but we still need to # merge some partially filled ones if conf.get('RESOURCEHOME', None): if conf['RESOURCEHOME'].find(conf['HOSTURL']) == -1: conf['RESOURCEHOME'] = os.path.join(conf['RESOURCEHOME'], 'MiG', 'mig_frontend', resource_id) if not conf.get('FRONTENDLOG', None): conf['FRONTENDLOG'] = os.path.join(conf['RESOURCEHOME'], 'frontend.log') # We can not be sure to have any exes so remain conservative here execution_nodes = conf['EXECONFIG'] storage_nodes = conf['STORECONFIG'] nodes = 0 if execution_nodes and execution_nodes[-1]['nodecount'].isdigit(): nodes = int(execution_nodes[-1]['nodecount']) exe_count = len([i for i in exe_names if i]) store_count = len([i for i in store_names if i]) if execution_leader: exe_count -= 1 total_nodes = exe_count * nodes + store_count conf['NODECOUNT'] = total_nodes if conf.get('HOSTKEY', None): # HOSTKEY is either saved one with "FQDN,IP" prefixed or raw key # Make sure HOSTIP gets set and that HOSTKEY gets "FQDN,IP" prefix # if not already set. Leave key bits and comment alone. key_parts = conf['HOSTKEY'].split() + [''] # Simplified FQDN,IP matcher which just needs to distinguish from raw # ssh keys. We do that since the keys have evolved and may now contain # a number of different prefix strings like e.g. ecdsa-sha2-nistp256 # rather than just the old ssh-rsa one. if not re.match('^[a-zA-Z0-9.-]+,[0-9.]+$', key_parts[0]): try: fallback_ip = socket.gethostbyname(conf['HOSTURL']) except: fallback_ip = '0.0.0.0' conf['HOSTIP'] = conf.get('HOSTIP', fallback_ip) host_key = conf['HOSTURL'] + ',' + conf['HOSTIP'] raw_key = conf['HOSTKEY'].strip() host_key += ' ' + raw_key conf['HOSTKEY'] = host_key for exe in execution_nodes: execution_node = exe['execution_node'] execution_dir = exe['execution_dir'] if execution_dir.find(conf['HOSTURL']) == -1: execution_dir = os.path.join(exe['execution_dir'], 'MiG', 'mig_exe', resource_id) # In the execution leader model all executors share a working dir if execution_leader: # replace exe dir name with "all" but keep trailing slash execution_dir = os.path.join(execution_dir, 'all') if exe['name'] == exe_leader_name: script_prefix = 'leader' else: script_prefix = 'dummy' else: execution_dir = os.path.join(execution_dir, exe['name']) script_prefix = 'master' if not exe.get('exehostlog', None): exe['exehostlog'] = os.path.join(execution_dir, 'exehost.log') if not exe.get('joblog', None): exe['joblog'] = os.path.join(execution_dir, 'job.log') exe['execution_dir'] = execution_dir if 'default' == exe.get('start_command', '').strip(): exe['start_command'] = default_exe_start_command(exe) elif 'local' == exe.get('start_command', '').strip(): exe['start_command'] = local_exe_start_command(exe, script_prefix) if 'default' == exe.get('status_command', '').strip(): exe['status_command'] = default_exe_status_command(exe) elif 'local' == exe.get('status_command', '').strip(): exe['status_command'] = local_exe_status_command( exe, script_prefix) if 'default' == exe.get('stop_command', '').strip(): exe['stop_command'] = default_exe_stop_command(exe) elif 'local' == exe.get('stop_command', '').strip(): exe['stop_command'] = local_exe_stop_command(exe, script_prefix) if 'default' == exe.get('clean_command', '').strip(): exe['clean_command'] = default_exe_clean_command(exe) elif 'local' == exe.get('clean_command', '').strip(): exe['clean_command'] = local_exe_clean_command(exe, script_prefix) for store in storage_nodes: storage_node = store['storage_node'] storage_dir = store['storage_dir'] if storage_dir.find(conf['HOSTURL']) == -1: storage_dir = os.path.join(store['storage_dir'], 'MiG', 'mig_store', resource_id, store['name']) store['storage_dir'] = storage_dir if 'default' == store.get('start_command', '').strip(): store['start_command'] = default_store_start_command(store) elif 'local' == store.get('start_command', '').strip(): store['start_command'] = local_store_start_command(store) if 'default' == store.get('status_command', '').strip(): store['status_command'] = default_store_status_command(store) elif 'local' == store.get('status_command', '').strip(): store['status_command'] = local_store_status_command(store) if 'default' == store.get('stop_command', '').strip(): store['stop_command'] = default_store_stop_command(store) elif 'local' == store.get('stop_command', '').strip(): store['stop_command'] = local_store_stop_command(store) if 'default' == store.get('clean_command', '').strip(): store['clean_command'] = default_store_clean_command(store) elif 'local' == store.get('clean_command', '').strip(): store['clean_command'] = local_store_clean_command(store) return conf
def prepare_conf(configuration, input_args, resource_id): """Update minimally validated user input dictionary to one suitable for resource conf parsing. """ # Flatten list structure for all fields except vgrid ones user_args = {} for (key, val) in input_args.items(): if key.endswith('vgrid'): user_args[key] = val else: user_args[key] = val[-1].strip() # Merge the variable fields like runtimeenvironmentX and re_valuesX # pairs into the final form suitable for parsing. Both fields # should exist for all X in range(0, runtime_env_fields) . re_list = [] field_count = 0 field_count_arg = user_args.get('runtime_env_fields', None) if field_count_arg: field_count = int(field_count_arg) del user_args['runtime_env_fields'] for i in range(field_count): runtime_env = 'runtimeenvironment' + str(i) env_values = 're_values' + str(i) if user_args.has_key(runtime_env): if user_args.has_key(env_values): # re_valuesX is a single line, A=vx yz\nB=def, with all assignments var_lines = user_args[env_values].split('\n') re_values = [tuple(line.split('=', 1)) for line in var_lines] del user_args[env_values] else: re_values = [] re_list.append((user_args[runtime_env], re_values)) del user_args[runtime_env] user_args['RUNTIMEENVIRONMENT'] = re_list frontend_home = user_args.get('frontendhome', None) if frontend_home: if not user_args.get('RESOURCEHOME', None): user_args['RESOURCEHOME'] = frontend_home del user_args['frontendhome'] execution_leader = False if user_args.get('LRMSTYPE', '').find('-execution-leader') != -1: execution_leader = True all_exes = [] execution_nodes = user_args.get('exe-executionnodes', '') exe_names = retrieve_execution_nodes(execution_nodes, execution_leader) for name in exe_names: exe = {} if not user_args.get('exe-execution_dir', None): user_args['exe-execution_dir'] = user_args.get('exe-executionhome', '') for (key, __) in resconfkeywords.get_exenode_specs(configuration): exe[key] = user_args.get("exe-%s" % key, '') exe['name'] = exe['execution_node'] = name all_exes.append(exe) user_args['EXECONFIG'] = all_exes all_stores = [] storage_nodes = user_args.get('store-storagenodes', '') store_names = retrieve_storage_nodes(storage_nodes) for name in store_names: store = {} if not user_args.get('store-storage_dir', None): user_args['store-storage_dir'] = user_args.get('store-storagehome', '') for (key, __) in resconfkeywords.get_storenode_specs(configuration): store[key] = user_args.get("store-%s" % key, '') store['name'] = store['storage_node'] = name all_stores.append(store) user_args['STORECONFIG'] = all_stores for key in user_args.keys(): if key.startswith('exe-') or key.startswith('store-'): del user_args[key] conf = {} conf.update(user_args) # Now all fields should be valid conf fields, but we still need to # merge some partially filled ones if conf.get('RESOURCEHOME', None): if conf['RESOURCEHOME'].find(conf['HOSTURL']) == -1: conf['RESOURCEHOME'] = os.path.join(conf['RESOURCEHOME'], 'MiG', 'mig_frontend', resource_id) if not conf.get('FRONTENDLOG', None): conf['FRONTENDLOG'] = os.path.join(conf['RESOURCEHOME'], 'frontend.log') # We can not be sure to have any exes so remain conservative here execution_nodes = conf['EXECONFIG'] storage_nodes = conf['STORECONFIG'] nodes = 0 if execution_nodes: nodes = int(execution_nodes[-1]['nodecount']) exe_count = len([i for i in exe_names if i]) store_count = len([i for i in store_names if i]) if execution_leader: exe_count -= 1 total_nodes = exe_count * nodes + store_count conf['NODECOUNT'] = total_nodes if conf.get('HOSTKEY', None): # HOSTKEY is either saved one with "FQDN,IP" prefixed or raw key # Make sure HOSTIP gets set and that HOSTKEY gets "FQDN,IP" prefix # if not already set. Leave key bits and comment alone. key_parts = conf['HOSTKEY'].split() + [''] if not key_parts[1].startswith('ssh-'): host_key = '' try: fallback_ip = socket.gethostbyname(conf['HOSTURL']) except: fallback_ip = '0.0.0.0' conf['HOSTIP'] = conf.get('HOSTIP', fallback_ip) host_key = conf['HOSTURL'] + ',' + conf['HOSTIP'] raw_key = conf['HOSTKEY'].strip() host_key += ' ' + raw_key conf['HOSTKEY'] = host_key for exe in execution_nodes: execution_node = exe['execution_node'] execution_dir = exe['execution_dir'] if execution_dir.find(conf['HOSTURL']) == -1: execution_dir = os.path.join(exe['execution_dir'], 'MiG', 'mig_exe', resource_id) # In the execution leader model all executors share a working dir if execution_leader: # replace exe dir name with "all" but keep trailing slash execution_dir = os.path.join(execution_dir, 'all') if exe['name'] == exe_leader_name: script_prefix = 'leader' else: script_prefix = 'dummy' else: execution_dir = os.path.join(execution_dir, exe['name']) script_prefix = 'master' if not exe.get('exehostlog', None): exe['exehostlog'] = os.path.join(execution_dir, 'exehost.log') if not exe.get('joblog', None): exe['joblog'] = os.path.join(execution_dir, 'job.log') exe['execution_dir'] = execution_dir if 'default' == exe.get('start_command', '').strip(): exe['start_command'] = default_exe_start_command(execution_dir, execution_node) elif 'local' == exe.get('start_command', '').strip(): exe['start_command'] = local_exe_start_command(execution_dir, execution_node, script_prefix) if 'default' == exe.get('status_command', '').strip(): exe['status_command'] = default_exe_status_command(execution_dir, execution_node) elif 'local' == exe.get('status_command', '').strip(): exe['status_command'] = local_exe_status_command(execution_dir, execution_node, script_prefix) if 'default' == exe.get('stop_command', '').strip(): exe['stop_command'] = default_exe_stop_command(execution_dir, execution_node) elif 'local' == exe.get('stop_command', '').strip(): exe['stop_command'] = local_exe_stop_command(execution_dir, execution_node, script_prefix) if 'default' == exe.get('clean_command', '').strip(): exe['clean_command'] = default_exe_clean_command(execution_dir, execution_node) elif 'local' == exe.get('clean_command', '').strip(): exe['clean_command'] = local_exe_clean_command(execution_dir, execution_node, script_prefix) for store in storage_nodes: storage_node = store['storage_node'] storage_dir = store['storage_dir'] if storage_dir.find(conf['HOSTURL']) == -1: storage_dir = os.path.join(store['storage_dir'], 'MiG', 'mig_store', resource_id, store['name']) store['storage_dir'] = storage_dir if 'default' == store.get('start_command', '').strip(): store['start_command'] = default_store_start_command(storage_dir, storage_node) elif 'local' == store.get('start_command', '').strip(): store['start_command'] = local_store_start_command(storage_dir, storage_node) if 'default' == store.get('status_command', '').strip(): store['status_command'] = default_store_status_command(storage_dir, storage_node) elif 'local' == store.get('status_command', '').strip(): store['status_command'] = local_store_status_command(storage_dir, storage_node) if 'default' == store.get('stop_command', '').strip(): store['stop_command'] = default_store_stop_command(storage_dir, storage_node) elif 'local' == store.get('stop_command', '').strip(): store['stop_command'] = local_store_stop_command(storage_dir, storage_node) if 'default' == store.get('clean_command', '').strip(): store['clean_command'] = default_store_clean_command(storage_dir, storage_node) elif 'local' == store.get('clean_command', '').strip(): store['clean_command'] = local_store_clean_command(storage_dir, storage_node) return conf
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) status = returnvalues.OK resource_keywords = resconfkeywords.get_resource_keywords(configuration) exenode_keywords = resconfkeywords.get_exenode_keywords(configuration) storenode_keywords = resconfkeywords.get_storenode_keywords(configuration) title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Resource administration help' output_objects.append({ 'object_type': 'header', 'text': 'Resource administration help' }) output_objects.append({'object_type': 'sectionheader', 'text' : 'Welcome to the %s resource administration help' % \ configuration.short_title }) output_objects.append({ 'object_type': 'text', 'text': 'Help for each of the resource editor fields is available below.' }) res_fields = resconfkeywords.get_resource_specs(configuration) exe_fields = resconfkeywords.get_exenode_specs(configuration) store_fields = resconfkeywords.get_storenode_specs(configuration) # Resource overall fields output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='%s'>%s:</a></b><br /> %s<br /> <br />""" % ('frontendhome', 'Frontend Home Path', """The %s user home directory on the frontend""" % \ configuration.short_title ) }) for (field, spec) in res_fields: if 'invisible' == spec['Editor']: continue title = spec['Title'] output_objects.append({ 'object_type': 'html_form', 'text': """ <b><a name='res-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % (field, title, resource_keywords[field]['Description'], resource_keywords[field]['Example']) }) # Execution node fields output_objects.append({ 'object_type': 'html_form', 'text': """ <b><a name='exe-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % ('executionnodes', 'Execution Node(s)', exenode_keywords['name']['Description'], """ This fields configures all the job execution nodes in one %(site)s resource.<br /> It is possible to specify several execution nodes by seperating them with ';'<br /> and it's possible to denote ranges of execution nodes by using '->'.<br /> <br /> Example: n0->n8 ; n10 ; n12->n24<br /> <br /> Specifies the nodes n0 to n8, n10 and n12 to n24.<br /> <br /> Please note that the following node count field specifies the number of actual physical hosts associated with each of these %(site)s execution nodes. In case of a one-to-one mapping between %(site)s execution nodes and actual nodes, it should just be set to 1. Only if each %(site)s execution node gives access to multiple nodes e.g. in a cluster or batch system, should it be set higher.<br /> """ % { 'site': configuration.short_title }) }) output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='exe-%s'>%s:</a></b><br /> %s<br /> <br />""" % ('executionhome', 'Execution Home Path', """The %s user home directory on execution nodes""" % \ configuration.short_title ) }) for (field, spec) in exe_fields: if 'invisible' == spec['Editor']: continue title = spec['Title'] output_objects.append({ 'object_type': 'html_form', 'text': """ <b><a name='exe-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % (field, title, exenode_keywords[field]['Description'], exenode_keywords[field]['Example']) }) # Storage node fields output_objects.append({ 'object_type': 'html_form', 'text': """ <b><a name='store-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % ('store-storagenodes', 'Storage Node(s)', storenode_keywords['name']['Description'], """ This fields configures all the storage nodes in one %(site)s resource.<br /> It is possible to specify several storage nodes by seperating them with ';'<br /> and it's possible to denote ranges of storage nodes by using '->'.<br /> <br /> Example: n0->n8 ; n10 ; n12->n24<br /> <br /> Specifies the nodes n0 to n8, n10 and n12 to n24.<br /> <br /> Please note that the following disk field specifies the amount of actual physical storage reserved for %(site)s on each of these %(site)s storage nodes.<br /> """ % { 'site': configuration.short_title }) }) output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='store-%s'>%s:</a></b><br /> %s<br /> <br />""" % ('storagehome', 'Storage Home Path', """The %s user home directory on storage nodes""" % \ configuration.short_title ) }) for (field, spec) in store_fields: if 'invisible' == spec['Editor']: continue title = spec['Title'] output_objects.append({ 'object_type': 'html_form', 'text': """ <b><a name='store-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % (field, title, storenode_keywords[field]['Description'], storenode_keywords[field]['Example']) }) 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] (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) hosturl = accepted['hosturl'][-1] hostidentifier = accepted['hostidentifier'][-1] resource_id = '%s.%s' % (hosturl, hostidentifier) extra_selects = 3 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) # Find allowed VGrids and Runtimeenvironments and add them to # configuration object for automated choice handling allowed_vgrids = [''] + res_vgrid_access(configuration, resource_id) allowed_vgrids.sort() configuration.vgrids = allowed_vgrids (re_status, allowed_run_envs) = list_runtime_environments(configuration) allowed_run_envs.sort() area_cols = 80 area_rows = 5 status = returnvalues.OK logger.info('Starting Resource edit GUI.') title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Resource Editor' output_objects.append({'object_type': 'header', 'text': 'Resource Editor'}) output_objects.append({ 'object_type': 'sectionheader', 'text': '%s Resource Editor' % configuration.short_title }) output_objects.append({ 'object_type': 'text', 'text': ''' Please fill in or edit the fields below to fit your %s resource reservation. Most fields will work with their default values. So if you are still in doubt after reading the help description, you can likely just leave the field alone.''' % configuration.short_title }) if hosturl and hostidentifier: conf = init_conf(configuration, hosturl, hostidentifier) if not conf: status = returnvalues.CLIENT_ERROR output_objects.append({ 'object_type': 'error_text', 'text': '''No such resource! (%s.%s)''' % (hosturl, hostidentifier) }) return (output_objects, status) else: conf = empty_resource_config(configuration) res_fields = resconfkeywords.get_resource_specs(configuration) exe_fields = resconfkeywords.get_exenode_specs(configuration) store_fields = resconfkeywords.get_storenode_specs(configuration) form_method = 'post' csrf_limit = get_csrf_limit(configuration) fill_helpers = { 'short_title': configuration.short_title, 'form_method': form_method, 'csrf_field': csrf_field, 'csrf_limit': csrf_limit } target_op = 'reseditaction' csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) fill_helpers.update({'target_op': target_op, 'csrf_token': csrf_token}) output_objects.append({ 'object_type': 'html_form', 'text': """ <form method='%(form_method)s' action='%(target_op)s.py'> <input type='hidden' name='%(csrf_field)s' value='%(csrf_token)s' /> """ % fill_helpers }) # Resource overall fields output_objects.append({ 'object_type': 'sectionheader', 'text': "Main Resource Settings" }) output_objects.append({ 'object_type': 'text', 'text': """This section configures general options for the resource.""" }) (title, field) = ('Host FQDN', 'HOSTURL') if hosturl: try: hostip = conf.get('HOSTIP', socket.gethostbyname(hosturl)) except: hostip = '<unknown>' output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#res-%s'>help</a><br /> <input type='hidden' name='%s' value='%s' /> <input type='hidden' name='hostip' value='%s' /> %s <br /> <br />""" % (title, field, field, conf[field], hostip, conf[field]) }) else: output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#res-%s'>help</a><br /> <input class='fillwidth padspace' type='text' name='%s' size='%d' value='%s' required pattern='[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+' title='Fully qualified domain name or Internet IP address of the resource' /> <br /> <br />""" % (title, field, field, field_size(conf[field]), conf[field]) }) (title, field) = ('Host identifier', 'HOSTIDENTIFIER') if hostidentifier: output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#res-%s'>help</a><br /> <input type='hidden' name='%s' value='%s' /> %s <br /> <br />""" % (title, field, field, conf[field], conf[field]) }) (field, title) = 'frontendhome', 'Frontend Home Path' output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#%s'>help</a><br /> <input class='fillwidth padspace' type='text' name='%s' size='%d' value='%s' required pattern='[^ ]+' title='Absolute path to user home on the resource' /> <br /> <br />""" % (title, field, field, field_size(conf[field]), conf[field]) }) for (field, spec) in res_fields: title = spec['Title'] field_type = spec['Type'] if spec['Required']: required_str = 'required' else: required_str = '' if 'invisible' == spec['Editor']: continue elif 'input' == spec['Editor']: if spec['Type'] == 'int': input_str = """ <input class='fillwidth padspace' type='number' name='%s' size='%d' value='%s' min=0 pattern='[0-9]+' %s /> """ % (field, field_size(conf[field]), conf[field], required_str) else: input_str = """ <input class='fillwidth padspace' type='text' name='%s' size='%d' value='%s' %s /> """ % (field, field_size(conf[field]), conf[field], required_str) output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#res-%s'>help</a> <br /> %s<br /> <br />""" % (title, field, input_str) }) elif 'select' == spec['Editor']: choices = available_choices(configuration, client_id, resource_id, field, spec) res_value = conf[field] value_select = '' if field_type.startswith('multiple'): select_count = len(res_value) + extra_selects else: select_count = 1 res_value = [res_value] for i in range(select_count): value_select += "<select name='%s'>\n" % field for name in choices: selected = '' if i < len(res_value) and res_value[i] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' value_select += """<option %s value='%s'>%s</option>\n""" \ % (selected, name, display) value_select += """</select><br />\n""" output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#res-%s'>help</a><br /> %s <br />""" % (title, field, value_select) }) # Not all resource fields here map directly to keywords/specs input field (title, field) = ('Runtime Environments', 'RUNTIMEENVIRONMENT') re_list = conf[field] show = re_list + [('', []) for i in range(extra_selects)] re_select = "<input type='hidden' name='runtime_env_fields' value='%s'/>\n" \ % len(show) i = 0 for active in show: re_select += "<select name='runtimeenvironment%d'>\n" % i for name in allowed_run_envs + ['']: selected = '' if active[0] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' re_select += """<option %s value='%s'>%s</option>\n""" % \ (selected, name, display) re_select += """</select><br />\n""" values = '\n'.join(['%s=%s' % pair for pair in active[1]]) re_select += "<textarea class='fillwidth padspace' cols='%d' rows='%d' name='re_values%d'>%s</textarea><br />\n" % \ (area_cols, area_rows, i, values) i += 1 output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#res-%s'>help</a><br /> Please enter any required environment variable settings on the form NAME=VALUE in the box below each selected runtimeenvironment.<br /> %s <br />""" % (title, field, re_select) }) # Execution node fields output_objects.append({ 'object_type': 'sectionheader', 'text': "Execution nodes" }) output_objects.append({ 'object_type': 'text', 'text': """This section configures execution nodes on the resource.""" }) (field, title) = 'executionnodes', 'Execution Node(s)' output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#exe-%s'>help</a><br /> <input class='fillwidth padspace' type='text' name='exe-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size( conf['all_exes'][field]), conf['all_exes'][field]) }) (field, title) = 'executionhome', 'Execution Home Path' output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#exe-%s'>help</a><br /> <input class='fillwidth padspace' type='text' name='exe-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size( conf['all_exes'][field]), conf['all_exes'][field]) }) for (field, spec) in exe_fields: title = spec['Title'] field_type = spec['Type'] # We don't really have a good map of required fields here so disable required_str = '' if 'invisible' == spec['Editor']: continue elif 'input' == spec['Editor']: if spec['Type'] == 'int': input_str = """ <input class='fillwidth padspace' type='number' name='exe-%s' size='%d' value='%s' min=0 pattern='[0-9]+' %s /> """ % (field, field_size(conf['all_exes'][field]), conf['all_exes'][field], required_str) else: input_str = """ <input class='fillwidth padspace' type='text' name='exe-%s' size='%d' value='%s' %s /> """ % (field, field_size(conf['all_exes'][field]), conf['all_exes'][field], required_str) output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#exe-%s'>help</a> <br /> %s <br /> <br />""" % (title, field, input_str) }) elif 'select' == spec['Editor']: choices = available_choices(configuration, client_id, resource_id, field, spec) exe_value = conf['all_exes'][field] value_select = '' if field_type.startswith('multiple'): select_count = len(exe_value) + extra_selects else: select_count = 1 exe_value = [exe_value] for i in range(select_count): value_select += "<select name='exe-%s'>\n" % field for name in choices: selected = '' if i < len(exe_value) and exe_value[i] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' value_select += """<option %s value='%s'>%s</option>\n""" \ % (selected, name, display) value_select += """</select><br />\n""" output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#exe-%s'>help</a><br /> %s <br />""" % (title, field, value_select) }) # Storage node fields output_objects.append({ 'object_type': 'sectionheader', 'text': "Storage nodes" }) output_objects.append({ 'object_type': 'text', 'text': """This section configures storage nodes on the resource.""" }) (field, title) = 'storagenodes', 'Storage Node(s)' output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#store-%s'>help</a><br /> <input class='fillwidth padspace' type='text' name='store-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size( conf['all_stores'][field]), conf['all_stores'][field]) }) (field, title) = 'storagehome', 'Storage Home Path' output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#store-%s'>help</a><br /> <input class='fillwidth padspace' type='text' name='store-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size( conf['all_stores'][field]), conf['all_stores'][field]) }) for (field, spec) in store_fields: title = spec['Title'] field_type = spec['Type'] # We don't really have a good map of required fields here so disable required_str = '' if 'invisible' == spec['Editor']: continue elif 'input' == spec['Editor']: if spec['Type'] == 'int': input_str = """ <input class='fillwidth padspace' type='number' name='store-%s' size='%d' value='%s' min=0 pattern='[0-9]+' %s /> """ % (field, field_size(conf['all_stores'][field]), conf['all_stores'][field], required_str) else: input_str = """ <input class='fillwidth padspace' type='text' name='store-%s' size='%d' value='%s' %s /> """ % (field, field_size(conf['all_stores'][field]), conf['all_stores'][field], required_str) output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#store-%s'>help</a> <br /> %s <br /> <br />""" % (title, field, input_str) }) elif 'select' == spec['Editor']: choices = available_choices(configuration, client_id, resource_id, field, spec) store_value = conf['all_stores'][field] value_select = '' if field_type.startswith('multiple'): select_count = len(store_value) + extra_selects else: select_count = 1 store_value = [store_value] for i in range(select_count): value_select += "<select name='store-%s'>\n" % field for name in choices: selected = '' if i < len(store_value) and store_value[i] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' value_select += """<option %s value='%s'>%s</option>\n""" \ % (selected, name, display) value_select += """</select><br />\n""" output_objects.append({ 'object_type': 'html_form', 'text': """<br /> <b>%s:</b> <a class='infolink iconspace' href='resedithelp.py#store-%s'>help</a><br /> %s <br />""" % (title, field, value_select) }) output_objects.append({ 'object_type': 'html_form', 'text': """ <input type='submit' value='Save' /> </form> """ }) 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] (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) status = returnvalues.OK resource_keywords = resconfkeywords.get_resource_keywords(configuration) exenode_keywords = resconfkeywords.get_exenode_keywords(configuration) storenode_keywords = resconfkeywords.get_storenode_keywords(configuration) title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Resource administration help' output_objects.append({'object_type': 'header', 'text': 'Resource administration help' }) output_objects.append({'object_type': 'sectionheader', 'text' : 'Welcome to the %s resource administration help' % \ configuration.short_title }) output_objects.append({'object_type': 'text', 'text' : 'Help for each of the resource editor fields is available below.' }) res_fields = resconfkeywords.get_resource_specs(configuration) exe_fields = resconfkeywords.get_exenode_specs(configuration) store_fields = resconfkeywords.get_storenode_specs(configuration) # Resource overall fields output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='%s'>%s:</a></b><br /> %s<br /> <br />""" % ('frontendhome', 'Frontend Home Path', """The %s user home directory on the frontend""" % \ configuration.short_title ) }) for (field, spec) in res_fields: if 'invisible' == spec['Editor']: continue title = spec['Title'] output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='res-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % (field, title, resource_keywords[field]['Description'], resource_keywords[field]['Example']) }) # Execution node fields output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='exe-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % ('executionnodes', 'Execution Node(s)', exenode_keywords['name']['Description'], """ This fields configures all the job execution nodes in one %(site)s resource.<br /> It is possible to specify several execution nodes by seperating them with ';'<br /> and it's possible to denote ranges of execution nodes by using '->'.<br /> <br /> Example: n0->n8 ; n10 ; n12->n24<br /> <br /> Specifies the nodes n0 to n8, n10 and n12 to n24.<br /> <br /> Please note that the following node count field specifies the number of actual physical hosts associated with each of these %(site)s execution nodes. In case of a one-to-one mapping between %(site)s execution nodes and actual nodes, it should just be set to 1. Only if each %(site)s execution node gives access to multiple nodes e.g. in a cluster or batch system, should it be set higher.<br /> """ % {'site' : configuration.short_title} ) }) output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='exe-%s'>%s:</a></b><br /> %s<br /> <br />""" % ('executionhome', 'Execution Home Path', """The %s user home directory on execution nodes""" % \ configuration.short_title ) }) for (field, spec) in exe_fields: if 'invisible' == spec['Editor']: continue title = spec['Title'] output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='exe-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % (field, title, exenode_keywords[field]['Description'], exenode_keywords[field]['Example']) }) # Storage node fields output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='store-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % ('store-storagenodes', 'Storage Node(s)', storenode_keywords['name']['Description'], """ This fields configures all the storage nodes in one %(site)s resource.<br /> It is possible to specify several storage nodes by seperating them with ';'<br /> and it's possible to denote ranges of storage nodes by using '->'.<br /> <br /> Example: n0->n8 ; n10 ; n12->n24<br /> <br /> Specifies the nodes n0 to n8, n10 and n12 to n24.<br /> <br /> Please note that the following disk field specifies the amount of actual physical storage reserved for %(site)s on each of these %(site)s storage nodes.<br /> """ % { 'site' : configuration.short_title} ) }) output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='store-%s'>%s:</a></b><br /> %s<br /> <br />""" % ('storagehome', 'Storage Home Path', """The %s user home directory on storage nodes""" % \ configuration.short_title ) }) for (field, spec) in store_fields: if 'invisible' == spec['Editor']: continue title = spec['Title'] output_objects.append({'object_type': 'html_form', 'text' : """ <b><a name='store-%s'>%s:</a></b><br /> %s<br /> <br /> Example: %s<br /> <br />""" % (field, title, storenode_keywords[field]['Description'], storenode_keywords[field]['Example']) }) 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] (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) hosturl = accepted['hosturl'][-1] hostidentifier = accepted['hostidentifier'][-1] resource_id = '%s.%s' % (hosturl, hostidentifier) extra_selects = 3 # Find allowed VGrids and Runtimeenvironments and add them to # configuration object for automated choice handling allowed_vgrids = [''] + res_allowed_vgrids(configuration, resource_id) allowed_vgrids.sort() configuration.vgrids = allowed_vgrids (re_status, allowed_run_envs) = list_runtime_environments(configuration) allowed_run_envs.sort() area_cols = 80 area_rows = 5 status = returnvalues.OK logger.info('Starting Resource edit GUI.') title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Resource Editor' output_objects.append({'object_type': 'header', 'text': 'Resource Editor' }) output_objects.append({'object_type': 'sectionheader', 'text' : '%s Resource Editor' % configuration.short_title}) output_objects.append({'object_type': 'text', 'text' : ''' Please fill in or edit the fields below to fit your %s resource reservation. Most fields will work with their default values. So if you are still in doubt after reading the help description, you can likely just leave the field alone.''' % configuration.short_title }) if hosturl and hostidentifier: conf = init_conf(configuration, hosturl, hostidentifier) if not conf: status = returnvalues.CLIENT_ERROR output_objects.append({'object_type': 'error_text', 'text' : '''No such resource! (%s.%s)''' % (hosturl, hostidentifier)}) return (output_objects, status) else: conf = empty_resource_config(configuration) res_fields = resconfkeywords.get_resource_specs(configuration) exe_fields = resconfkeywords.get_exenode_specs(configuration) store_fields = resconfkeywords.get_storenode_specs(configuration) output_objects.append({'object_type': 'html_form', 'text': """ <form method='post' action='reseditaction.py'> """ }) # Resource overall fields output_objects.append({'object_type': 'sectionheader', 'text' : "Main Resource Settings"}) output_objects.append({'object_type': 'text', 'text' : """This section configures general options for the resource.""" }) (title, field) = ('Host FQDN', 'HOSTURL') if hosturl: try: hostip = conf.get('HOSTIP', socket.gethostbyname(hosturl)) except: hostip = '<unknown>' output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#res-%s'>help</a><br /> <input type='hidden' name='%s' value='%s' /> <input type='hidden' name='hostip' value='%s' /> %s <br /> <br />""" % (title, field, field, conf[field], hostip, conf[field]) }) else: output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#res-%s'>help</a><br /> <input type='text' name='%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf[field]), conf[field]) }) (title, field) = ('Host identifier', 'HOSTIDENTIFIER') if hostidentifier: output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#res-%s'>help</a><br /> <input type='hidden' name='%s' value='%s' /> %s <br /> <br />""" % (title, field, field, conf[field], conf[field]) }) (field, title) = 'frontendhome', 'Frontend Home Path' output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#%s'>help</a><br /> <input type='text' name='%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf[field]), conf[field]) }) for (field, spec) in res_fields: title = spec['Title'] field_type = spec['Type'] if 'invisible' == spec['Editor']: continue elif 'input' == spec['Editor']: output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#res-%s'>help</a><br /> <input type='text' name='%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf[field]), conf[field]) }) elif 'select' == spec['Editor']: choices = available_choices(configuration, client_id, resource_id, field, spec) res_value = conf[field] value_select = '' if field_type.startswith('multiple'): select_count = len(res_value) + extra_selects else: select_count = 1 res_value = [res_value] for i in range(select_count): value_select += "<select name='%s'>\n" % field for name in choices: selected = '' if i < len(res_value) and res_value[i] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' value_select += """<option %s value='%s'>%s</option>\n""" \ % (selected, name, display) value_select += """</select><br />\n""" output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#res-%s'>help</a><br /> %s <br />""" % (title, field, value_select) }) # Not all resource fields here map directly to keywords/specs input field (title, field) = ('Runtime Environments', 'RUNTIMEENVIRONMENT') re_list = conf[field] show = re_list + [('', []) for i in range(extra_selects)] re_select = "<input type='hidden' name='runtime_env_fields' value='%s'/>\n" \ % len(show) i = 0 for active in show: re_select += "<select name='runtimeenvironment%d'>\n" % i for name in allowed_run_envs + ['']: selected = '' if active[0] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' re_select += """<option %s value='%s'>%s</option>\n""" % \ (selected, name, display) re_select += """</select><br />\n""" values = '\n'.join(['%s=%s' % pair for pair in active[1]]) re_select += "<textarea cols='%d' rows='%d' name='re_values%d'>%s</textarea><br />\n" % \ (area_cols, area_rows, i, values) i += 1 output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#res-%s'>help</a><br /> Please enter any required environment variable settings on the form NAME=VALUE in the box below each selected runtimeenvironment.<br /> %s <br />""" % (title, field, re_select) }) # Execution node fields output_objects.append({'object_type': 'sectionheader', 'text' : "Execution nodes"}) output_objects.append({'object_type': 'text', 'text' : """This section configures execution nodes on the resource.""" }) (field, title) = 'executionnodes', 'Execution Node(s)' output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#exe-%s'>help</a><br /> <input type='text' name='exe-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf['all_exes'][field]), conf['all_exes'][field]) }) (field, title) = 'executionhome', 'Execution Home Path' output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#exe-%s'>help</a><br /> <input type='text' name='exe-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf['all_exes'][field]), conf['all_exes'][field]) }) for (field, spec) in exe_fields: title = spec['Title'] field_type = spec['Type'] if 'invisible' == spec['Editor']: continue elif 'input' == spec['Editor']: output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#exe-%s'>help</a><br /> <input type='text' name='exe-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf['all_exes'][field]), conf['all_exes'][field]) }) elif 'select' == spec['Editor']: choices = available_choices(configuration, client_id, resource_id, field, spec) exe_value = conf['all_exes'][field] value_select = '' if field_type.startswith('multiple'): select_count = len(exe_value) + extra_selects else: select_count = 1 exe_value = [exe_value] for i in range(select_count): value_select += "<select name='exe-%s'>\n" % field for name in choices: selected = '' if i < len(exe_value) and exe_value[i] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' value_select += """<option %s value='%s'>%s</option>\n""" \ % (selected, name, display) value_select += """</select><br />\n""" output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#exe-%s'>help</a><br /> %s <br />""" % (title, field, value_select) }) # Storage node fields output_objects.append({'object_type': 'sectionheader', 'text' : "Storage nodes"}) output_objects.append({'object_type': 'text', 'text' : """This section configures storage nodes on the resource.""" }) (field, title) = 'storagenodes', 'Storage Node(s)' output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#store-%s'>help</a><br /> <input type='text' name='store-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf['all_stores'][field]), conf['all_stores'][field]) }) (field, title) = 'storagehome', 'Storage Home Path' output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#store-%s'>help</a><br /> <input type='text' name='store-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf['all_stores'][field]), conf['all_stores'][field]) }) for (field, spec) in store_fields: title = spec['Title'] field_type = spec['Type'] if 'invisible' == spec['Editor']: continue elif 'input' == spec['Editor']: output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#store-%s'>help</a><br /> <input type='text' name='store-%s' size='%d' value='%s' /> <br /> <br />""" % (title, field, field, field_size(conf['all_stores'][field]), conf['all_stores'][field]) }) elif 'select' == spec['Editor']: choices = available_choices(configuration, client_id, resource_id, field, spec) store_value = conf['all_stores'][field] value_select = '' if field_type.startswith('multiple'): select_count = len(store_value) + extra_selects else: select_count = 1 store_value = [store_value] for i in range(select_count): value_select += "<select name='store-%s'>\n" % field for name in choices: selected = '' if i < len(store_value) and store_value[i] == name: selected = 'selected' display = "%s" % name if display == '': display = ' ' value_select += """<option %s value='%s'>%s</option>\n""" \ % (selected, name, display) value_select += """</select><br />\n""" output_objects.append({'object_type': 'html_form', 'text' : """<br /> <b>%s:</b> <a class='infolink' href='resedithelp.py#store-%s'>help</a><br /> %s <br />""" % (title, field, value_select) }) output_objects.append({'object_type': 'html_form', 'text': """ <input type='submit' value='Save' /> </form> """ }) return (output_objects, status)