Beispiel #1
0
    def __init__(self, pav_cfg, test, mb_tracker, build_name=None):
        """Inititalize the build object.
        :param pav_cfg: The Pavilion config object
        :param pavilion.test_run.TestRun test: The test run responsible for
        starting this build.
        :param MultiBuildTracker mb_tracker: A thread-safe tracker object for
        keeping info on what the build is doing.
        :param str build_name: The build name, if this is a build that already
        exists.
        :raises TestBuilderError: When the builder can't be initialized.
        """

        if mb_tracker is None:
            mb_tracker = MultiBuildTracker(log=False)
        self.tracker = mb_tracker.register(self, test.status)

        self._pav_cfg = pav_cfg
        self._config = test.config.get('build', {})
        self._group = test.group
        self._umask = test.umask
        self._script_path = test.build_script_path
        self.test = test
        self._timeout = test.build_timeout
        self._timeout_file = test.build_timeout_file

        self._fix_source_path()

        if not test.build_local:
            self.tracker.update(state=STATES.BUILD_DEFERRED,
                                note="Build will run on nodes.")

        if build_name is None:
            self.name = self.name_build()
            self.tracker.update(state=STATES.BUILD_CREATED,
                                note="Builder created.")
        else:
            self.name = build_name

        self.path = pav_cfg.working_dir / 'builds' / self.name  # type: Path
        self.tmp_log_path = self.path.with_suffix('.log')
        self.log_path = self.path / self.LOG_NAME
        fail_name = 'fail.{}.{}'.format(self.name, self.test.id)
        self.fail_path = pav_cfg.working_dir / 'builds' / fail_name
        self.finished_path = self.path.with_suffix(self.FINISHED_SUFFIX)

        if self._timeout_file is not None:
            self._timeout_file = self.path / self._timeout_file
        else:
            self._timeout_file = self.tmp_log_path

        # Don't allow a file to be written outside of the build context dir.
        files_to_create = self._config.get('create_files')
        if files_to_create:
            for file, contents in files_to_create.items():
                file_path = Path(utils.resolve_path(self.path / file))
                if not utils.dir_contains(file_path,
                                          utils.resolve_path(self.path)):
                    raise TestBuilderError(
                        "'create_file: {}': file path"
                        " outside build context.".format(file_path))
Beispiel #2
0
    def finalize(self, var_man):
        """Resolve any remaining deferred variables, and generate the final
        run script."""

        self.var_man.undefer(new_vars=var_man)

        self.config = resolver.TestConfigResolver.resolve_deferred(
            self.config, self.var_man)
        self._save_config()
        # Save our newly updated variables.
        self.var_man.save(self._variables_path)

        # Create files specified via run config key.
        files_to_create = self.config['run'].get('create_files', [])
        if files_to_create:
            for file, contents in files_to_create.items():
                file_path = Path(self.build_path / file)
                # Prevent files from being written outside build directory.
                if not utils.dir_contains(file_path, self.build_path):
                    raise TestRunError(
                        "'create_file: {}': file path"
                        " outside build context.".format(file_path))
                # Prevent files from overwriting existing directories.
                if file_path.is_dir():
                    raise TestRunError(
                        "'create_file: {}' clashes with"
                        " existing directory in build dir.".format(file_path))
                # Create file parent directory(ies).
                dirname = file_path.parent
                (self.build_path / dirname).mkdir(parents=True, exist_ok=True)

                # Don't try to overwrite a symlink without removing it first.
                if file_path.is_symlink():
                    file_path.unlink()

                # Write file.
                with PermissionsManager(file_path, self.group, self.umask), \
                        file_path.open('w') as file_:

                    for line in contents:
                        file_.write("{}\n".format(line))

        if not self.skipped:
            self.skipped = self._get_skipped()

        self.save_attributes()

        self._write_script(
            'run',
            self.run_script_path,
            self.config['run'],
        )