コード例 #1
0
ファイル: resource.py プロジェクト: ucphhpc/migrid
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
コード例 #2
0
ファイル: resource.py プロジェクト: heromod/migrid
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
コード例 #3
0
ファイル: resource.py プロジェクト: ucphhpc/migrid
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
コード例 #4
0
ファイル: resource.py プロジェクト: heromod/migrid
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
コード例 #5
0
ファイル: resedithelp.py プロジェクト: ucphhpc/migrid
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:&nbsp;%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:&nbsp;%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:&nbsp; 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:&nbsp;%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:&nbsp;%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:&nbsp; 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:&nbsp;%s<br />
<br />""" % (field, title, storenode_keywords[field]['Description'],
             storenode_keywords[field]['Example'])
        })

    return (output_objects, status)
コード例 #6
0
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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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)
コード例 #7
0
ファイル: resedithelp.py プロジェクト: heromod/migrid
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:&nbsp;%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:&nbsp;%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:&nbsp; 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:&nbsp;%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:&nbsp;%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:&nbsp; 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:&nbsp;%s<br />
<br />""" % (field, title, storenode_keywords[field]['Description'],
               storenode_keywords[field]['Example'])
                               })

    return (output_objects, status)
コード例 #8
0
ファイル: resedit.py プロジェクト: heromod/migrid
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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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>&nbsp;<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)