Repository: ESMCI/cime

Issue:
Clearer error message needed for incorrect setting of CIME_MODEL
1) setenv  CIME_MODEL CESM,  results in following error message that is less than helpful
```
Traceback (most recent call last):
  File "./create_newcase", line 180, in <module>
    _main_func()
  File "./create_newcase", line 151, in _main_func
    with Case(caseroot, read_only=False) as case:
  File "/fs/cgd/data0/mvertens/src/cime.esmci/scripts/Tools/../../utils/python/CIME/case.py", line 77, in __init__
    self.read_xml()
  File "/fs/cgd/data0/mvertens/src/cime.esmci/scripts/Tools/../../utils/python/CIME/case.py", line 152, in read_xml
    self._env_entryid_files.append(EnvRun(self._caseroot))
  File "/fs/cgd/data0/mvertens/src/cime.esmci/scripts/Tools/../../utils/python/CIME/XML/env_run.py", line 16, in __init__
    EnvBase.__init__(self, case_root, infile)
  File "/fs/cgd/data0/mvertens/src/cime.esmci/scripts/Tools/../../utils/python/CIME/XML/env_base.py", line 25, in __init__
    headernode = headerobj.get_header_node(os.path.basename(fullpath))
  File "/fs/cgd/data0/mvertens/src/cime.esmci/scripts/Tools/../../utils/python/CIME/XML/headers.py", line 26, in get_header_node
    fnode = self.get_node("file", attributes={"name" : fname})
  File "/fs/cgd/data0/mvertens/src/cime.esmci/scripts/Tools/../../utils/python/CIME/XML/generic_xml.py", line 95, in get_node
    nodes = self.get_nodes(nodename, attributes=attributes, root=root, xpath=xpath)
  File "/fs/cgd/data0/mvertens/src/cime.esmci/scripts/Tools/../../utils/python/CIME/XML/generic_xml.py", line 118, in get_nodes
    root = self.root
AttributeError: 'Headers' object has no attribute 'root'
/

```
We need an error message saying what the acceptable values of CIME_MODEL currently are

2) If a try to invoked create_newcase for a CESM machine, but have not set CIME_MODEL to cesm,
a more clear error message would be helpful, stating that the machine is not available for the target CIME_MODEL and giving the supported CIME_MODELS that can be used.





Discussion:
@mvertens and @fischer-ncar - is this still an issue? If so, should it be added to the cesm2 milestone?
Still an issue.  setenv CIME_MODEL CESM, now results in
ERROR: Could not find or open file /home/fischer/code/cesm2_0_alpha06n/cime/config/CESM/config_files.xml


Resolving patch:
diff --git a/scripts/lib/CIME/XML/machines.py b/scripts/lib/CIME/XML/machines.py
--- a/scripts/lib/CIME/XML/machines.py
+++ b/scripts/lib/CIME/XML/machines.py
@@ -4,7 +4,7 @@
 from CIME.XML.standard_module_setup import *
 from CIME.XML.generic_xml import GenericXML
 from CIME.XML.files import Files
-from CIME.utils import convert_to_unknown_type, get_cime_config
+from CIME.utils import convert_to_unknown_type, get_cime_config, get_all_cime_models
 
 import socket
 
@@ -30,6 +30,7 @@ def __init__(self, infile=None, files=None, machine=None, extra_machines_dir=Non
         self.machines_dir = None
         self.custom_settings = {}
         schema = None
+        supported_models = []
         if files is None:
             files = Files()
         if infile is None:
@@ -66,8 +67,16 @@ def __init__(self, infile=None, files=None, machine=None, extra_machines_dir=Non
                     machine = cime_config.get("main", "machine")
                 if machine is None:
                     machine = self.probe_machine_name()
-
-        expect(machine is not None, "Could not initialize machine object from {} or {}".format(infile, local_infile))
+                    if machine is None:
+                        for potential_model in get_all_cime_models():
+                            local_infile = os.path.join(get_cime_root(), "config",potential_model,"machines","config_machines.xml")
+                            if local_infile != infile:
+                                GenericXML.read(self, local_infile, schema)
+                                if self.probe_machine_name() is not None:
+                                    supported_models.append(potential_model)
+                                GenericXML.change_file(self, infile, schema)
+
+        expect(machine is not None, "Could not initialize machine object from {} or {}. This machine is not available for the target CIME_MODEL. The supported CIME_MODELS that can be used are: {}".format(infile, local_infile, supported_models))
         self.set_machine(machine)
 
     def get_child(self, name=None, attributes=None, root=None, err_msg=None):
diff --git a/scripts/lib/CIME/utils.py b/scripts/lib/CIME/utils.py
--- a/scripts/lib/CIME/utils.py
+++ b/scripts/lib/CIME/utils.py
@@ -273,14 +273,24 @@ def get_cime_default_driver():
     expect(driver in ("mct", "nuopc", "moab"),"Attempt to set invalid driver {}".format(driver))
     return driver
 
+def get_all_cime_models():
+    modelsroot = os.path.join(get_cime_root(), "config")
+    models = []
+    for entry in os.listdir(modelsroot):
+        if os.path.isdir(os.path.join(modelsroot,entry)):
+            models.append(entry)
+    models.remove('xml_schemas')
+    return models
+
 def set_model(model):
     """
     Set the model to be used in this session
     """
     cime_config = get_cime_config()
+    cime_models = get_all_cime_models()
     if not cime_config.has_section('main'):
         cime_config.add_section('main')
-    expect(model in ['cesm','e3sm','ufs'],"model {} not recognized".format(model))
+    expect(model in cime_models,"model {} not recognized. The acceptable values of CIME_MODEL currently are {}".format(model, cime_models))
     cime_config.set('main','CIME_MODEL',model)
 
 def get_model():
@@ -304,10 +314,11 @@ def get_model():
     >>> reset_cime_config()
     """
     model = os.environ.get("CIME_MODEL")
-    if model in ['cesm', 'e3sm', 'ufs']:
+    cime_models = get_all_cime_models()
+    if model in cime_models:
         logger.debug("Setting CIME_MODEL={} from environment".format(model))
     else:
-        expect(model is None,"model {} not recognized".format(model))
+        expect(model is None,"model {} not recognized. The acceptable values of CIME_MODEL currently are {}".format(model, cime_models))
         cime_config = get_cime_config()
         if (cime_config.has_option('main','CIME_MODEL')):
             model = cime_config.get('main','CIME_MODEL')


Test patch: