コード例 #1
0
    def run_image_task(self, image_build_conf):
        task_id, image_name = self.build_filesystem(image_build_conf)

        task = TaskWatcher(self.session, task_id, self.poll_interval)
        try:
            task.wait()
        except BuildCanceledException:
            self.log.info("Build was canceled, canceling task %s", task_id)
            try:
                self.session.cancelTask(task_id)
                self.log.info('task %s canceled', task_id)
            except Exception as exc:
                self.log.info("Exception while canceling a task (ignored): %s",
                              util.exception_message(exc))

        if task.failed():
            try:
                # Koji may re-raise the error that caused task to fail
                task_result = self.session.getTaskResult(task_id)
            except Exception as exc:
                task_result = util.exception_message(exc)
            raise RuntimeError('image task, {}, failed: {}'.format(
                task_id, task_result))

        return task_id, image_name
コード例 #2
0
    def run(self):
        self.set_arguments()
        args = self.parser.parse_args()
        logging.captureWarnings(True)

        if args.verbose:
            set_logging(level=logging.DEBUG)
            set_logging_osbs(level=logging.DEBUG)
        elif args.quiet:
            set_logging(level=logging.WARNING)
            set_logging_osbs(level=logging.WARNING)
        else:
            set_logging(level=logging.INFO)
            set_logging_osbs(level=logging.INFO)
        try:
            args.func(args)
        except AttributeError:
            if hasattr(args, 'func'):
                raise
            else:
                self.parser.print_help()
        except KeyboardInterrupt:
            pass
        except Exception as ex:
            if args.verbose:
                raise
            else:
                logger.error("exception caught: %s", exception_message(ex))
コード例 #3
0
    def build_docker_image(self):
        """
        build docker image

        :return: BuildResult
        """
        exception_being_handled = False
        self.builder = InsideBuilder(self.source, self.image)
        # Make sure exit_runner is defined for finally block
        exit_runner = None
        try:
            self.fs_watcher.start()
            signal.signal(signal.SIGTERM, self.throw_canceled_build_exception)
            prebuild_runner = PreBuildPluginsRunner(
                self.builder.tasker,
                self,
                self.prebuild_plugins_conf,
                plugin_files=self.plugin_files)
            prepublish_runner = PrePublishPluginsRunner(
                self.builder.tasker,
                self,
                self.prepublish_plugins_conf,
                plugin_files=self.plugin_files)
            postbuild_runner = PostBuildPluginsRunner(
                self.builder.tasker,
                self,
                self.postbuild_plugins_conf,
                plugin_files=self.plugin_files)
            # time to run pre-build plugins, so they can access cloned repo
            logger.info("running pre-build plugins")
            try:
                prebuild_runner.run()
            except PluginFailedException as ex:
                logger.error("one or more prebuild plugins failed: %s", ex)
                raise
            except AutoRebuildCanceledException as ex:
                logger.info(str(ex))
                self.autorebuild_canceled = True
                raise

            # we are delaying initialization, because prebuild plugin reactor_config
            # might change build method
            buildstep_runner = BuildStepPluginsRunner(
                self.builder.tasker,
                self,
                self.buildstep_plugins_conf,
                plugin_files=self.plugin_files)

            logger.info("running buildstep plugins")
            try:
                self.build_result = buildstep_runner.run()

                if self.build_result.is_failed():
                    raise PluginFailedException(self.build_result.fail_reason)
            except PluginFailedException as ex:
                self.builder.is_built = False
                logger.error('buildstep plugin failed: %s', ex)
                raise

            self.builder.is_built = True
            if self.build_result.is_image_available():
                self.builder.image_id = self.build_result.image_id

            # run prepublish plugins
            try:
                prepublish_runner.run()
            except PluginFailedException as ex:
                logger.error("one or more prepublish plugins failed: %s", ex)
                raise

            if self.build_result.is_image_available():
                self.built_image_inspect = self.builder.inspect_built_image()
                history = self.builder.tasker.get_image_history(
                    self.builder.image_id)
                diff_ids = self.built_image_inspect[INSPECT_ROOTFS][
                    INSPECT_ROOTFS_LAYERS]

                # diff_ids is ordered oldest first
                # history is ordered newest first
                # We want layer_sizes to be ordered oldest first
                self.layer_sizes = [{
                    "diff_id": diff_id,
                    "size": layer['Size']
                } for (diff_id, layer) in zip(diff_ids, reversed(history))]

            try:
                postbuild_runner.run()
            except PluginFailedException as ex:
                logger.error("one or more postbuild plugins failed: %s", ex)
                raise

            return self.build_result
        except Exception as ex:
            logger.debug("caught exception (%s) so running exit plugins",
                         exception_message(ex))
            exception_being_handled = True
            raise
        finally:
            # We need to make sure all exit plugins are executed
            signal.signal(signal.SIGTERM, lambda *args: None)

            exit_runner = ExitPluginsRunner(self.builder.tasker,
                                            self,
                                            self.exit_plugins_conf,
                                            keep_going=True,
                                            plugin_files=self.plugin_files)
            try:
                exit_runner.run(keep_going=True)
            except PluginFailedException as ex:
                logger.error("one or more exit plugins failed: %s", ex)

                # raise exception only in case that there is no previous exception being already
                # handled to prevent replacing original exceptions (root cause) with exceptions
                # from exit plugins
                if not exception_being_handled:
                    raise ex
            finally:
                self.source.remove_tmpdir()
                self.fs_watcher.finish()

            signal.signal(signal.SIGTERM, signal.SIG_DFL)
コード例 #4
0
ファイル: inner.py プロジェクト: chmeliik/atomic-reactor
    def build_docker_image(self) -> None:
        """
        build docker image
        """
        print_version_of_tools()

        exception_being_handled = False
        # Make sure exit_runner is defined for finally block
        exit_runner = None
        try:
            self.fs_watcher.start()
            signal.signal(signal.SIGTERM, self.throw_canceled_build_exception)
            prebuild_runner = PreBuildPluginsRunner(
                self, self.plugins.prebuild, plugin_files=self.plugin_files)
            prepublish_runner = PrePublishPluginsRunner(
                self, self.plugins.prepublish, plugin_files=self.plugin_files)
            postbuild_runner = PostBuildPluginsRunner(
                self, self.plugins.postbuild, plugin_files=self.plugin_files)
            # time to run pre-build plugins, so they can access cloned repo
            logger.info("running pre-build plugins")
            try:
                prebuild_runner.run()
            except PluginFailedException as ex:
                logger.error("one or more prebuild plugins failed: %s", ex)
                raise

            # we are delaying initialization, because prebuild plugin reactor_config
            # might change build method
            buildstep_runner = BuildStepPluginsRunner(
                self, self.plugins.buildstep, plugin_files=self.plugin_files)

            logger.info("running buildstep plugins")
            try:
                buildstep_runner.run()
            except PluginFailedException as ex:
                logger.error('buildstep plugin failed: %s', ex)
                raise

            # run prepublish plugins
            try:
                prepublish_runner.run()
            except PluginFailedException as ex:
                logger.error("one or more prepublish plugins failed: %s", ex)
                raise

            try:
                postbuild_runner.run()
            except PluginFailedException as ex:
                logger.error("one or more postbuild plugins failed: %s", ex)
                raise
        except Exception as ex:
            logger.debug("caught exception (%s) so running exit plugins",
                         exception_message(ex))
            exception_being_handled = True
            raise
        finally:
            # We need to make sure all exit plugins are executed
            signal.signal(signal.SIGTERM, lambda *args: None)

            exit_runner = ExitPluginsRunner(self,
                                            self.plugins.exit,
                                            keep_going=True,
                                            plugin_files=self.plugin_files)
            try:
                exit_runner.run(keep_going=True)
            except PluginFailedException as ex:
                logger.error("one or more exit plugins failed: %s", ex)

                # raise exception only in case that there is no previous exception being already
                # handled to prevent replacing original exceptions (root cause) with exceptions
                # from exit plugins
                if not exception_being_handled:
                    raise ex
            finally:
                self.fs_watcher.finish()

            signal.signal(signal.SIGTERM, signal.SIG_DFL)
コード例 #5
0
    def run(self, keep_going=False, buildstep_phase=False):
        """
        run all requested plugins

        :param keep_going: bool, whether to keep going after unexpected
                                 failure (only used for exit plugins)
        :param buildstep_phase: bool, when True remaining plugins will
                                not be executed after a plugin completes
                                (only used for build-step plugins)
        """
        failed_msgs = []
        plugin_successful = False
        plugin_response = None
        available_plugins = self.available_plugins
        for plugin in available_plugins:
            plugin_successful = False

            logger.debug("running plugin '%s'", plugin.name)
            start_time = datetime.datetime.now()

            plugin_response = None
            skip_response = False
            try:
                plugin_instance = self.create_instance_from_plugin(
                    plugin.plugin_class, plugin.conf)
                self.save_plugin_timestamp(plugin.plugin_class.key, start_time)
                plugin_response = plugin_instance.run()
                plugin_successful = True
                if buildstep_phase:
                    assert isinstance(plugin_response, BuildResult)
                    if plugin_response.is_failed():
                        logger.error("Build step plugin %s failed: %s",
                                     plugin.plugin_class.key,
                                     plugin_response.fail_reason)
                        self.on_plugin_failed(plugin.plugin_class.key,
                                              plugin_response.fail_reason)
                        plugin_successful = False
                        self.plugins_results[
                            plugin.plugin_class.key] = plugin_response
                        break

            except AutoRebuildCanceledException as ex:
                # if auto rebuild is canceled, then just reraise
                # NOTE: We need to catch and reraise explicitly, so that the below except clause
                #   doesn't catch this and make PluginFailedException out of it in the end
                #   (calling methods would then need to parse exception message to see if
                #   AutoRebuildCanceledException was raised here)
                raise
            except InappropriateBuildStepError:
                logger.debug('Build step %s is not appropriate',
                             plugin.plugin_class.key)
                # don't put None, in results for InappropriateBuildStepError
                skip_response = True
                if not buildstep_phase:
                    raise
            except Exception as ex:
                msg = "plugin '%s' raised an exception: %s" % (
                    plugin.plugin_class.key, exception_message(ex))
                logger.debug(traceback.format_exc())
                if not plugin.is_allowed_to_fail:
                    self.on_plugin_failed(plugin.plugin_class.key, ex)

                if plugin.is_allowed_to_fail or keep_going:
                    logger.warning(msg)
                    logger.info("error is not fatal, continuing...")
                    if not plugin.is_allowed_to_fail:
                        failed_msgs.append(msg)
                else:
                    logger.error(msg)
                    raise PluginFailedException(msg)

                plugin_response = ex

            try:
                if start_time:
                    finish_time = datetime.datetime.now()
                    duration = finish_time - start_time
                    seconds = duration.total_seconds()
                    logger.debug("plugin '%s' finished in %ds", plugin.name,
                                 seconds)
                    self.save_plugin_duration(plugin.plugin_class.key, seconds)
            except Exception:
                logger.exception("failed to save plugin duration")

            if not skip_response:
                self.plugins_results[plugin.plugin_class.key] = plugin_response

            if plugin_successful and buildstep_phase:
                logger.debug('stopping further execution of plugins '
                             'after first successful plugin')
                break

        if len(failed_msgs) == 1:
            raise PluginFailedException(failed_msgs[0])
        elif len(failed_msgs) > 1:
            raise PluginFailedException(
                "Multiple plugins raised an exception: " + str(failed_msgs))

        if not plugin_successful and buildstep_phase and not plugin_response:
            self.on_plugin_failed("BuildStepPlugin",
                                  "No appropriate build step")
            raise PluginFailedException("No appropriate build step")

        return self.plugins_results
コード例 #6
0
    def run(self, keep_going=False, buildstep_phase=False):
        """
        run all requested plugins

        :param keep_going: bool, whether to keep going after unexpected
                                 failure (only used for exit plugins)
        :param buildstep_phase: bool, when True remaining plugins will
                                not be executed after a plugin completes
                                (only used for build-step plugins)
        """
        failed_msgs = []
        plugin_successful = False
        plugin_response = None
        available_plugins = self.available_plugins
        for plugin in available_plugins:
            plugin_successful = False

            plugin_response = None
            skip_response = False
            try:
                plugin_instance = self.create_instance_from_plugin(
                    plugin.plugin_class, plugin.conf)
                with self._execution_timer(plugin):
                    plugin_response = plugin_instance.run()
                plugin_successful = True

            except InappropriateBuildStepError:
                logger.debug('Build step %s is not appropriate',
                             plugin.plugin_class.key)
                # don't put None, in results for InappropriateBuildStepError
                skip_response = True
                if not buildstep_phase:
                    raise
            except Exception as ex:
                msg = "plugin '%s' raised an exception: %s" % (
                    plugin.plugin_class.key, exception_message(ex))
                logger.debug(traceback.format_exc())
                if not plugin.is_allowed_to_fail:
                    self.on_plugin_failed(plugin.plugin_class.key, ex)

                if plugin.is_allowed_to_fail or keep_going:
                    logger.warning(msg)
                    logger.info("error is not fatal, continuing...")
                    if not plugin.is_allowed_to_fail:
                        failed_msgs.append(msg)
                else:
                    logger.error(msg)
                    raise PluginFailedException(msg) from ex

                plugin_response = ex

            if not skip_response:
                self.plugins_results[plugin.plugin_class.key] = plugin_response

            if plugin_successful and buildstep_phase:
                logger.debug('stopping further execution of plugins '
                             'after first successful plugin')
                break

        if len(failed_msgs) == 1:
            raise PluginFailedException(failed_msgs[0])
        elif len(failed_msgs) > 1:
            raise PluginFailedException(
                "Multiple plugins raised an exception: " + str(failed_msgs))

        # When a buildstep plugin raises InappropriateBuildStepError, next
        # buildstep plugin will run. This ensures to fail the build process
        # if all buildstep plugins are tried and no one succeeds.
        if not plugin_successful and buildstep_phase and available_plugins:
            self.on_plugin_failed("BuildStepPlugin",
                                  "No appropriate build step")
            raise PluginFailedException("No appropriate build step")

        return self.plugins_results