Skip to content

Commit

Permalink
Added Ability to Query Single Machine
Browse files Browse the repository at this point in the history
In this commit-- added the ability to give machine name as a query.
Additionally, fixed some the argument descriptions. Also, fixed argument
descriptions to be more descriptive on choices.

Test suite: `scripts_regression_tests.py`
and
```
./query_config
./query_config --grids
./query_config --machines
./query_config --machines current
./query_config --machines redsky
./query_config --machines edison
./query_config --machines skybridge
./query_config --compsets
./query_config --compsets all
./query_config --compsets drv
./query_config --component
```
Test baseline:
Test namelist changes:
Test status: bit for bit

Fixes #1155, #1190

User interface changes?:
manage_case -> query_config
--compset -> --compsets
--machine -> --machines
added 'all' option for --compsets
added 'current' and <machine> to --machines

Code review: @billsacks, @jgfouca
  • Loading branch information
Erich L Foster committed May 5, 2017
1 parent 4f0a70e commit 20eee71
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 38 deletions.
10 changes: 5 additions & 5 deletions scripts/lib/CIME/XML/compsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def get_compset_match(self, name):
user_mods = user_mods_node.text
else:
user_mods = None
logger.debug("Found node match with alias: %s and lname: %s" % (alias, lname))
logger.debug("Found node match with alias: {} and lname: {}".format(alias, lname))
return (lname, alias, science_support, user_mods)
return (None, None, [False], None)

Expand Down Expand Up @@ -72,7 +72,7 @@ def get_value(self, name, attribute=None, resolved=False, subgroup=None):
nodes = self.get_nodes(nodename="compset")
for node in nodes:
for child in node:
logger.debug ("Here child is %s with value %s"%(child.tag,child.text))
logger.debug ("Here child is {} with value {}".format(child.tag,child.text))
if child.tag == "alias":
alias = child.text
if child.tag == "lname":
Expand All @@ -84,11 +84,11 @@ def print_values(self, help=True):
help_text = self.get_value(name="help")
compsets_text = self.get_value("names")
if help:
logger.info(" %s " %help_text)
logger.info(" {} ".format(help_text))

logger.info(" --------------------------------------")
logger.info(" Compset Short Name: Compset Long Name ")
logger.info(" Compset Alias: Compset Long Name ")
logger.info(" --------------------------------------")
for v in compsets_text.iteritems():
label, definition = v
logger.info(" %20s : %s" %(label, definition))
logger.info(" {:20} : {}".format(label, definition))
17 changes: 9 additions & 8 deletions scripts/lib/CIME/XML/machines.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def __init__(self, infile=None, files=None, machine=None):
if infile is None:
infile = files.get_value("MACHINES_SPEC_FILE")
schema = files.get_schema("MACHINES_SPEC_FILE")
logger.debug("Verifying using schema %s"%schema)
logger.debug("Verifying using schema {}".format(schema))

self.machines_dir = os.path.dirname(infile)

Expand All @@ -38,7 +38,7 @@ def __init__(self, infile=None, files=None, machine=None):
# Append the contents of $HOME/.cime/config_machines.xml if it exists
# This could cause problems if node matchs are repeated when only one is expected
local_infile = os.path.join(os.environ.get("HOME"),".cime","config_machines.xml")
logger.debug("Infile: %s" , local_infile)
logger.debug("Infile: {}" , local_infile)
if os.path.exists(local_infile):
GenericXML.read(self, local_infile, schema)

Expand All @@ -48,7 +48,7 @@ def __init__(self, infile=None, files=None, machine=None):
else:
machine = self.probe_machine_name()

expect(machine is not None, "Could not initialize machine object from %s or %s" % (infile, local_infile))
expect(machine is not None, "Could not initialize machine object from {} or {}".format(infile, local_infile))
self.set_machine(machine)

def get_machines_dir(self):
Expand Down Expand Up @@ -113,7 +113,8 @@ def probe_machine_name(self, warn=True):

names_not_found_quoted = ["'" + name + "'" for name in names_not_found]
names_not_found_str = ' or '.join(names_not_found_quoted)
logger.warning("Could not find machine match for %s" % names_not_found_str)
if warn:
logger.warning("Could not find machine match for {}".format(names_not_found_str))

return machine

Expand All @@ -136,7 +137,7 @@ def _probe_machine_name_one_guess(self, nametomatch):
logger.debug("machine regex string is " + regex_str)
regex = re.compile(regex_str)
if regex.match(nametomatch):
logger.debug("Found machine: %s matches %s" % (machtocheck, nametomatch))
logger.debug("Found machine: {} matches {}".format(machtocheck, nametomatch))
machine = machtocheck
break

Expand All @@ -158,7 +159,7 @@ def set_machine(self, machine):
self.machine = machine
elif self.machine != machine or self.machine_node is None:
self.machine_node = self.get_optional_node("machine", {"MACH" : machine})
expect(self.machine_node is not None, "No machine %s found" % machine)
expect(self.machine_node is not None, "No machine {} found".format(machine))
self.machine = machine

return machine
Expand Down Expand Up @@ -275,7 +276,7 @@ def has_batch_system(self):
batch_system = self.get_optional_node("BATCH_SYSTEM", root=self.machine_node)
if batch_system is not None:
result = (batch_system.text is not None and batch_system.text != "none")
logger.debug("Machine %s has batch: %s" % (self.machine, result))
logger.debug("Machine {} has batch: {}".format(self.machine, result))
return result

def get_suffix(self, suffix_type):
Expand All @@ -299,7 +300,7 @@ def print_values(self):
max_tasks_per_node = machine.find("MAX_TASKS_PER_NODE")
pes_per_node = machine.find("PES_PER_NODE")

print " %s : %s "% (name , desc.text)
print " {} : {} ".format(name , desc.text)
print " os ", os_.text
print " compilers ",compilers.text
if pes_per_node is not None:
Expand Down
94 changes: 69 additions & 25 deletions scripts/query_config
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ def query_grids(long_output):
grids.print_values()

###############################################################################
def query_machines(current=False):
def query_machines(machine_name=None):
###############################################################################

files = Files()
config_file = files.get_value("MACHINES_SPEC_FILE")
expect(os.path.isfile(config_file),
"Cannot find config_file {} on disk".format(config_file))
# Provide a special machine name indicating no need for a machine name
machines = Machines(config_file,machine="Query")
machines.print_values(current_only=current)
machines = Machines(config_file, machine="Query")
machines.print_values(machine_name=machine_name)

###############################################################################
def query_compsets(name):
Expand Down Expand Up @@ -144,11 +144,26 @@ def parse_command_line(args):

CIME.utils.setup_standard_logging_options(parser)

parser.add_argument("--compset",
help="Query compsets that are set by the target component for {} model".format(cime_model))
files, components = get_compsets()
valid_components = ['all']
for item in components:
valid_components.append(item)

parser.add_argument("--component",
help="Query component settings that are set by the target component for {} model".format(cime_model))
parser.add_argument("--compsets", nargs='?', const='all', choices=valid_components,
help="Query compsets corresponding to the target component for the {} model".format(cime_model))

files, components = get_components()
# Loop through the elements for each component class (in config_files.xml)
valid_components = []
for comp in components:
string = "CONFIG_{}_FILE".format(comp)

# determine all components in string
components = files.get_components(string)
for item in components:
valid_components.append(item)
parser.add_argument("--component", choices=valid_components,
help="Query component settings corresponding to the target component for {} model".format(cime_model))

parser.add_argument("--grids", action="store_true",
help="Query supported model grids for {} model".format(cime_model))
Expand All @@ -157,16 +172,26 @@ def parse_command_line(args):
# parser.add_argument("--grids-alias",
# help="Query model grids for input grid alias for {} model - not implemented yet".format(cime_model))

parser.add_argument("--machines", nargs='?', action='store', const=True, choices=['current', 'empty'],
help="Query supported machines for {} model".format(cime_model))
config_file = files.get_value("MACHINES_SPEC_FILE")
expect(os.path.isfile(config_file),
"Cannot find config_file {} on disk".format(config_file))
machines = Machines(config_file, machine="Query")
machines = machines.get_nodes(nodename="machine")
machine_names = ['current']
for machine in machines:
machine_names.append(machine.get("MACH"))
parser.add_argument("--machines", nargs='?', action='store', const=True, choices=machine_names,
help="Query supported machines for {} model."
" If option is left empty then all machines are listed,"
" if current is giving the current machine details are listed.".format(cime_model))

parser.add_argument("--long", action="store_true",
help="Provide long output for queries")

args = CIME.utils.parse_args_and_handle_standard_logging_options(args, parser)

# make sure at least one argument has been passed
if not (args.grids or args.compset or args.component or args.machines):
if not (args.grids or args.compsets or args.component or args.machines):
parser.print_help(sys.stderr)

CIME.utils.handle_standard_logging_options(args)
Expand Down Expand Up @@ -204,21 +229,40 @@ class ArgumentParser(argparse.ArgumentParser):
.format(self.prog, message, components))
elif "component" in message:
files, components = get_components()
# Loop through the elements for each component class (in config_files.xml)
valid_components = []
for comp in components:
string = "CONFIG_{}_FILE".format(comp)

# determine all components in string
components = files.get_components(string)
for item in components:
valid_components.append(item)
self.exit(2, '{}: error: {}\nValid input arguments are {}\n'
.format(self.prog, message, components))
.format(self.prog, message, valid_components))
# for all other errors
self.exit(2, '{}: error: {}\n'.format(self.prog, message))

# we overide print_values from Machines to add current in machine description
class Machines(CIME.XML.machines.Machines):

def print_values(self, current_only=False):
# write out machines
if current_only and not self.probe_machine_name(warn=False):
print "Current machine is not listed in config file: {}".format(config_file)
def print_values(self, machine_name=None):
# set flag to look for single machine
if machine_name is not None:
single_machine = True
if machine_name == 'current':
machine_name = self.probe_machine_name(warn=False)
else:
single_machine = False

# if we can't find the specified machine
if single_machine and machine_name is None:
files = Files()
config_file = files.get_value("MACHINES_SPEC_FILE")
print "Machine is not listed in config file: {}".format(config_file)
else: # write out machines
machines = self.get_nodes(nodename="machine")
print "Machines"
print "Machine(s)"
for machine in machines:
name = machine.get("MACH")
desc = machine.find("DESC")
Expand All @@ -228,15 +272,16 @@ class Machines(CIME.XML.machines.Machines):
pes_per_node = machine.find("PES_PER_NODE")

current_machine = self.probe_machine_name(warn=False)
if current_machine and current_machine in name:
print " {} : {} ".format(name + " (current)", desc.text)
if not single_machine:
name += " (current)" if current_machine and current_machine in name else ""
print " {} : {} ".format(name, desc.text)
print " os ", os_.text
print " compilers ",compilers.text
if pes_per_node is not None:
print " pes/node ",pes_per_node.text
if max_tasks_per_node is not None:
print " max_tasks/node ",max_tasks_per_node.text
elif not current_only:
elif single_machine and machine_name in name:
print " {} : {} ".format(name, desc.text)
print " os ", os_.text
print " compilers ",compilers.text
Expand All @@ -254,17 +299,16 @@ def _main_func():
if args.grids:
query_grids(long_output=args.long)

if args.compset:
query_compsets(name=args.compset)
if args.compsets:
query_compsets(name=args.compsets)

if args.component:
query_component(args.component)

# this order is required since booleans are not iterable
if args.machines is not None and args.machines is True:
if args.machines is not None and args.machines is True: # print all machines
query_machines()
elif args.machines is not None and 'current' in args.machines:
query_machines(current=True)
elif args.machines is not None: # print the selected machine
query_machines(machine_name=args.machines)


###############################################################################
Expand Down

0 comments on commit 20eee71

Please sign in to comment.