Example #1
0
    def set_entry_point(self):
        """Locate the top-level driver script for the POD.

        Raises: :class:`~util.PodRuntimeError` if driver script can't be found.
        """
        if not self.driver:
            self.log.warning("No valid driver script found for %s.",
                             self.full_name)
            # try to find one anyway
            script_names = [self.name, "driver"]
            file_names = [f"{script}{ext}" for script in script_names \
                for ext in self._interpreters.keys()]
            for f in file_names:
                path_ = os.path.join(self.POD_CODE_DIR, f)
                if os.path.exists(path_):
                    self.log.debug("Setting driver script for %s to '%s'.",
                                   self.full_name, f)
                    self.driver = path_
                    break  # go with the first one found
        if not self.driver:
            raise util.PodRuntimeError(
                (f"No driver script found in "
                 f"{self.POD_CODE_DIR}. Specify 'driver' in settings.jsonc."),
                self)

        if not os.path.isabs(self.driver):  # expand relative path
            self.driver = os.path.join(self.POD_CODE_DIR, self.driver)
        if not os.path.exists(self.driver):
            raise util.PodRuntimeError(
                f"Unable to locate driver script '{self.driver}'.", self)
    def check_pod_driver(self):
        """Private method called by :meth:`~diagnostic.Diagnostic.setup`.

        Raises: :exc:`~diagnostic.PodRuntimeError` if driver script
            can't be found.
        """
        programs = util.get_available_programs()

        if not self.driver:
            _log.warning("No valid driver entry found for %s", self.full_name)
            #try to find one anyway
            try_filenames = [self.name + ".", "driver."]
            file_combos = [ file_root + ext for file_root \
                in try_filenames for ext in programs]
            _log.debug("Checking for possible driver names in {} {}".format(
                self.POD_CODE_DIR, file_combos))
            for try_file in file_combos:
                try_path = os.path.join(self.POD_CODE_DIR, try_file)
                _log.debug(" looking for driver file " + try_path)
                if os.path.exists(try_path):
                    self.driver = try_path
                    _log.debug("Found driver script for {}: {}".format(
                        self.name, self.driver))
                    break  #go with the first one found
                else:
                    _log.debug("\t " + try_path + " not found...")
        if self.driver == '':
            raise util.PodRuntimeError(
                (f"No driver script found in "
                 f"{self.POD_CODE_DIR}. Specify 'driver' in settings.jsonc."),
                self)

        if not os.path.isabs(self.driver):  # expand relative path
            self.driver = os.path.join(self.POD_CODE_DIR, self.driver)
        if not os.path.exists(self.driver):
            raise util.PodRuntimeError(
                f"Unable to locate driver script {self.driver}.", self)

        if self.program == '':
            # Find ending of filename to determine the program that should be used
            driver_ext = self.driver.split('.')[-1]
            # Possible error: Driver file type unrecognized
            if driver_ext not in programs:
                raise util.PodRuntimeError(
                    (f"Don't know how to call a .{driver_ext} "
                     f"file.\nSupported programs: {programs}"), self)
            self.program = programs[driver_ext]
            _log.debug("Found program " + programs[driver_ext])
Example #3
0
    def pre_run_setup(self):
        """Perform filesystem operations and checks prior to running the POD.

        In order, this 1) sets environment variables specific to the POD, 2)
        creates POD-specific working directories, and 3) checks for the existence
        of the POD's driver script.

        Note:
            The existence of data files is checked with
            :meth:`~data_manager.DataManager.fetchData`
            and the runtime environment is validated separately as a function of
            :meth:`~environment_manager.EnvironmentManager.run`. This is because
            each POD is run in a subprocess (due to the necessity of supporting
            multiple languages) so the validation must take place in that
            subprocess.

        Raises:
            :exc:`~diagnostic.PodRuntimeError` if requirements aren't met. This
                is re-raised from the :meth:`diagnostic.Diagnostic.set_entry_point`
                and :meth:`diagnostic.Diagnostic._check_for_varlist_files`
                subroutines.
        """
        try:
            self.set_pod_env_vars()
            self.set_entry_point()
        except Exception as exc:
            raise util.PodRuntimeError("Caught exception during pre_run_setup",
                                       self) from exc
Example #4
0
    def set_interpreter(self):
        """Determine what executable should be used to run the driver script.

        .. note::
           Existence of the program on the environment's ``$PATH`` isn't checked
           until before the POD runs (see :mod:`src.environment_manager`.)
        """

        if not self.program:
            # Find ending of filename to determine the program that should be used
            _, driver_ext = os.path.splitext(self.driver)
            # Possible error: Driver file type unrecognized
            if driver_ext not in self._interpreters:
                raise util.PodRuntimeError((
                    f"Don't know how to call a '{driver_ext}' "
                    f"file.\nSupported programs: {list(self._interpreters.values())}"
                ), self)
            self.program = self._interpreters[driver_ext]
            self.log.debug("Set program for %s to '%s'.", self.full_name,
                           self.program)
    def __init__(self, log=_log):
        super(CondaEnvironmentManager, self).__init__(log=log)

        paths = core.PathManager()
        self.code_root = paths.CODE_ROOT
        self.conda_dir = os.path.join(self.code_root, 'src', 'conda')
        self.env_list = []
        for file_ in os.listdir(self.conda_dir):
            if file_.endswith('.yml'):
                name, _ = os.path.splitext(file_)
                self.env_list.append(name.split('env_')[-1])

        # find conda executable
        # conda_init for bash defines conda as a shell function; will get error
        # if we try to call the conda executable directly
        try:
            conda_info = util.run_shell_command(
                f"{self.conda_dir}/conda_init.sh {paths.get('conda_root','')}",
                log=self.log)
            for line in conda_info:
                key, val = line.split('=')
                if key == '_CONDA_EXE':
                    self.conda_exe = val
                    assert os.path.exists(self.conda_exe)
                elif key == '_CONDA_ROOT':
                    self.conda_root = val
        except Exception as exc:
            raise util.PodRuntimeError("Can't find conda.") from exc

        # find where environments are installed
        if 'conda_env_root' in paths and paths.conda_env_root:
            self.conda_env_root = paths.conda_env_root
            if not os.path.isdir(self.conda_env_root):
                self.log.warning(
                    "Conda env directory '%s' not found; creating.",
                    self.conda_env_root)
                os.makedirs(self.conda_env_root)  # recursive mkdir if needed
        else:
            # only true in default anaconda install, may need to fix
            self.conda_env_root = os.path.join(self.conda_root, 'envs')
Example #6
0
    def pre_run_setup(self):
        """Extra code only applicable in frepp cooperative mode. If this code is 
        called, all the POD's model data has been generated. Write a placeholder
        directory to POD_OUT_DIR, so if frepp invokes the MDTF package again 
        while we're running, only our results will be written to the overall 
        output.
        """
        super(GfdlDiagnostic, self).pre_run_setup()

        config = core.ConfigManager()
        frepp_mode = config.get('frepp', False)
        if frepp_mode and not os.path.exists(self.POD_OUT_DIR):
            try:
                gfdl_util.make_remote_dir(self.POD_OUT_DIR)
                self._has_placeholder = True
            except Exception as exc:
                try:
                    raise util.PodRuntimeError((f"Caught exception making output "
                        f"directory at {self.POD_OUT_DIR}; deactivating {self.name}."),
                        self) from exc
                except Exception as chained_exc:
                    _log.error(chained_exc)
                    self.exceptions.log(chained_exc)