Apply a upgrade and register that it was successful.

        A upgrade may throw a RuntimeError, if an unrecoverable error happens.

        :param upgrade: A single upgrade

def apply_upgrade(self, upgrade):
        """Apply a upgrade and register that it was successful.

        A upgrade may throw a RuntimeError, if an unrecoverable error happens.

        :param upgrade: A single upgrade
        """
        self._setup_log_prefix(plugin_id=upgrade.name)

        try:  # Nested due to Python 2.4
            try:
                upgrade.do_upgrade()
                self.register_success(upgrade)
            except RuntimeError as e:
                msg = ["Upgrade error(s):"]

                for m in e.args:
                    msg.append(" (-) %s" % m)

                logger = self.get_logger()
                logger.error("\n".join(msg))

                raise RuntimeError(
                    "Upgrade '%s' failed. Your installation is in an"
                    " inconsistent state. Please manually review the upgrade "
                    "and resolve inconsistencies." % upgrade['id']
                )
        finally:
            self._teardown_log_prefix()