# HG changeset patch # User Søren Løvborg # Date 1468843397 -7200 # Node ID 0b6d2ca7175fc90d758d7da86d5452452aca9620 # Parent 4f4a73acd6b3a983ffc9affb2b141143002f58f0 db: drop RhodeCode compatibility (database rebranding etc.) To migrate from RhodeCode, users will have to first migrate to Kallithea 0.3.2. diff -r 4f4a73acd6b3 -r 0b6d2ca7175f README.rst --- a/README.rst Fri Jul 15 16:02:13 2016 +0200 +++ b/README.rst Mon Jul 18 14:03:17 2016 +0200 @@ -162,76 +162,14 @@ install it via the command: ``pip install sphinx`` . -Converting from RhodeCode -------------------------- - -Currently, you have two options for working with an existing RhodeCode -database: - -- keep the database unconverted (intended for testing and evaluation) -- convert the database in a one-time step - -Maintaining interoperability -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Interoperability with RhodeCode 2.2.X installations is provided so you don't -have to immediately commit to switching to Kallithea. This option will most -likely go away once the two projects have diverged significantly. - -To run Kallithea on a RhodeCode database, run:: - - echo "BRAND = 'rhodecode'" > kallithea/brand.py - -This location will depend on where you installed Kallithea. If you installed -via:: - - python2 setup.py install - -then you will find this location at -``$VIRTUAL_ENV/lib/python2.7/site-packages/Kallithea-0.1-py2.7.egg/kallithea``. - -One-time conversion -^^^^^^^^^^^^^^^^^^^ +Migrating from RhodeCode +------------------------ -Alternatively, if you would like to convert the database for good, you can use -a helper script provided by Kallithea. This script will operate directly on the -database, using the database string you can find in your ``production.ini`` (or -``development.ini``) file. For example, if using SQLite:: - - cd /path/to/kallithea - cp /path/to/rhodecode/rhodecode.db kallithea.db - pip install sqlalchemy-migrate - python2 kallithea/bin/rebranddb.py sqlite:///kallithea.db - -.. Note:: - - If you started out using the branding interoperability approach mentioned - above, watch out for stray brand.pyc after removing brand.py. - -Git hooks -^^^^^^^^^ - -After switching to Kallithea, it will be necessary to update the Git_ hooks in -your repositories. If not, the Git_ hooks from RhodeCode will still be called, -which will cause ``git push`` to fail every time. - -If you do not have any custom Git_ hooks deployed, perform the following steps -(this may take some time depending on the number and size of repositories you -have): - -1. Log-in as an administrator. - -2. Open page *Admin > Settings > Remap and Rescan*. - -3. Turn on the option **Install Git Hooks**. - -4. Turn on the option **Overwrite existing Git hooks**. - -5. Click on the button **Rescan Repositories**. - -If you do have custom hooks, you will need to merge those changes manually. In -order to get sample hooks from Kallithea, the easiest way is to create a new Git_ -repository, and have a look at the hooks deployed there. +Kallithea 0.3.2 and earlier supports migrating from an existing RhodeCode +installation. To migrate, install Kallithea 0.3.2 and follow the +instructions in the 0.3.2 README to perform a one-time conversion of the +database from RhodeCode to Kallithea, before upgrading to this version +of Kallithea. .. _virtualenv: http://pypi.python.org/pypi/virtualenv diff -r 4f4a73acd6b3 -r 0b6d2ca7175f docs/upgrade.rst --- a/docs/upgrade.rst Fri Jul 15 16:02:13 2016 +0200 +++ b/docs/upgrade.rst Mon Jul 18 14:03:17 2016 +0200 @@ -7,6 +7,13 @@ This describes the process for upgrading Kallithea, independently of the Kallithea installation method. +.. note:: + If you are upgrading from a RhodeCode installation, you must first + install Kallithea 0.3.2 and follow the instructions in the 0.3.2 + README to perform a one-time conversion of the database from + RhodeCode to Kallithea, before upgrading to the latest version + of Kallithea. + 1. Stop the Kallithea web application ------------------------------------- diff -r 4f4a73acd6b3 -r 0b6d2ca7175f kallithea/__init__.py --- a/kallithea/__init__.py Fri Jul 15 16:02:13 2016 +0200 +++ b/kallithea/__init__.py Mon Jul 18 14:03:17 2016 +0200 @@ -44,28 +44,18 @@ # Linked module for extensions EXTENSIONS = {} -# BRAND controls internal references in database and config to the products -# own name. -# -# NOTE: If you want compatibility with a database that was originally created -# for use with the RhodeCode software product, change BRAND to "rhodecode", -# either by editing here or by creating a new file: -# echo "BRAND = 'rhodecode'" > kallithea/brand.py - -BRAND = "kallithea" try: - from kallithea.brand import BRAND + import kallithea.brand except ImportError: pass - -# Prefix for the ui and settings table names -DB_PREFIX = (BRAND + "_") if BRAND != "kallithea" else "" +else: + assert False, 'Database rebranding is no longer supported; see README.' # Users.extern_type and .extern_name value for local users -EXTERN_TYPE_INTERNAL = BRAND if BRAND != 'kallithea' else 'internal' +EXTERN_TYPE_INTERNAL = 'internal' # db_migrate_version.repository_id value, same as kallithea/lib/dbmigrate/migrate.cfg -DB_MIGRATIONS = BRAND + "_db_migrations" +DB_MIGRATIONS = "kallithea_db_migrations" try: from kallithea.lib import get_current_revision diff -r 4f4a73acd6b3 -r 0b6d2ca7175f kallithea/bin/rebranddb.py --- a/kallithea/bin/rebranddb.py Fri Jul 15 16:02:13 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -#!/usr/bin/env python2 - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -""" -Script for rebranding of database to and from what Kallithea expects - -Works on databases from v1.7.2 to v2.2.5 -""" - -import sys -from sqlalchemy import * -import sqlalchemy.orm -import sqlalchemy.ext.declarative -import migrate.changeset # a part of sqlalchemy-migrate which is available on pypi - -def do_migrate(db, old, new): - print 'Migrating %s from %s to %s' % (db, old or '?', new) - metadata = MetaData() - metadata.bind = create_engine(db) - metadata.reflect() - assert metadata.tables, 'Cannot reflect table names from db' - - if not old: - assert 'db_migrate_version' in metadata.tables, 'Cannot reflect db_migrate_version from db' - t = metadata.tables['db_migrate_version'] - l = t.select().where(t.c.repository_path == 'versions').execute().fetchall() - assert len(l) == 1, 'Cannot find a single versions entry in db_migrate_version' - assert l[0].repository_id.endswith('_db_migrations') - old = l[0].repository_id[:-len('_db_migrations')] - print 'Detected migration from old name %s' % old - if new != old: - assert not t.select().where(t.c.repository_id == new + '_db_migrations').execute().fetchall(), 'db_migrate_version has entries for both old and new name' - - def tablename(brand, s): - return s if brand == 'kallithea' else (brand + '_' + s) - new_ui_name = tablename(new, 'ui') - old_ui_name = tablename(old, 'ui') - new_settings_name = tablename(new, 'settings') - old_settings_name = tablename(old, 'settings') - - # Table renames using sqlalchemy-migrate (available on pypi) - if new_ui_name == old_ui_name: - print 'No renaming of %s' % new_ui_name - else: - try: - t = metadata.tables[old_ui_name] - print 'Renaming', t, 'to', new_ui_name - migrate.changeset.rename_table(t, new_ui_name) - except KeyError as e: - print 'Not renaming ui:', e - - if new_settings_name == old_settings_name: - print 'No renaming of %s' % new_settings_name - else: - try: - t = metadata.tables[old_settings_name] - print 'Renaming', t, 'to', new_settings_name - migrate.changeset.rename_table(t, new_settings_name) - except KeyError as e: - print 'Not renaming settings:', e - - old_auth_name = 'internal' if old == 'kallithea' else old - new_auth_name = 'internal' if new == 'kallithea' else new - - # using this API because ... dunno ... it is simple and works - conn = metadata.bind.connect() - trans = conn.begin() - t = metadata.tables['users'] - - print 'Bulk fixing of User extern_name' - try: - t.c.extern_name - except AttributeError: - print 'No extern_name to rename' - else: - t.update().where(t.c.extern_name == old_auth_name).values(extern_name=new_auth_name).execute() - - print 'Bulk fixing of User extern_type' - try: - t.c.extern_type - except AttributeError: - print 'No extern_type to rename' - else: - t.update().where(t.c.extern_type == old_auth_name).values(extern_type=new_auth_name).execute() - - trans.commit() - - # For the following conversions, use ORM ... and create stub models that works for that purpose - Base = sqlalchemy.ext.declarative.declarative_base() - - class Ui(Base): - __tablename__ = new_ui_name - ui_id = Column("ui_id", Integer(), primary_key=True) - ui_section = Column("ui_section", String()) - ui_key = Column("ui_key", String()) - ui_value = Column("ui_value", String()) - ui_active = Column("ui_active", Boolean()) - - class Setting(Base): - __tablename__ = new_settings_name - app_settings_id = Column("app_settings_id", Integer(), primary_key=True) - app_settings_name = Column("app_settings_name", String()) - app_settings_value = Column("app_settings_value", String()) - #app_settings_type = Column("app_settings_type", String()) # not present in v1.7.2 - - class DbMigrateVersion(Base): - __tablename__ = 'db_migrate_version' - repository_id = Column('repository_id', String(), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) - - Session = sqlalchemy.orm.sessionmaker(bind=metadata.bind) - session = Session() - - print 'Fixing hook names' - - oldhooks = u'python:%s.lib.hooks.' % old - newhooks = u'python:%s.lib.hooks.' % new - for u in session.query(Ui).filter(Ui.ui_section == 'hooks').all(): - if u.ui_value.startswith(oldhooks): - print '- fixing %s' % u.ui_key - u.ui_value = newhooks + u.ui_value[len(oldhooks):] - session.add(u) - session.commit() - - print 'Fixing auth module names' - for s in session.query(Setting).filter(Setting.app_settings_name == 'auth_plugins').all(): - print '- fixing %s' % s.app_settings_name - s.app_settings_value = (s.app_settings_value - .replace(old + '.lib.auth_modules.auth_', new + '.lib.auth_modules.auth_') - .replace('.auth_modules.auth_' + old_auth_name, '.auth_modules.auth_' + new_auth_name)) - session.add(s) - for s in session.query(Setting).filter(Setting.app_settings_name == 'auth_' + old_auth_name + '_enabled').all(): - print '- fixing %s' % s.app_settings_name - s.app_settings_name = 'auth_' + new_auth_name + '_enabled' - session.add(s) - session.commit() - - print 'Fixing db migration version number' - for s in session.query(DbMigrateVersion).filter(DbMigrateVersion.repository_id == old + '_db_migrations', DbMigrateVersion.repository_path == 'versions').all(): - print '- fixing %s' % s.repository_id - s.repository_id = new + '_db_migrations' - session.commit() - - print 'Done' - -def main(argv): - if len(argv) < 2 or argv[1] in ['-h', '--help']: - print 'usage: kallithea/bin/rebranddb.py DBSTRING [NEW] [OLD]' - print ' where DBSTRING is the value of sqlalchemy.db1.url from the .ini,' - print ' NEW defaults to "kallithea", OLD is by default detected from the db"' - raise SystemExit(0) - new = 'kallithea' - if len(argv) > 2: - new = argv[2] - old = None - if len(argv) > 3: - old = argv[3] - do_migrate(argv[1], old, new) - -if __name__ == '__main__': - main(sys.argv) diff -r 4f4a73acd6b3 -r 0b6d2ca7175f kallithea/lib/utils.py --- a/kallithea/lib/utils.py Fri Jul 15 16:02:13 2016 +0200 +++ b/kallithea/lib/utils.py Mon Jul 18 14:03:17 2016 +0200 @@ -44,8 +44,6 @@ from webhelpers.text import collapse, remove_formatting, strip_tags from beaker.cache import _cache_decorate -from kallithea import BRAND - from kallithea.lib.vcs.utils.hgcompat import ui, config from kallithea.lib.vcs.utils.helpers import get_scm from kallithea.lib.vcs.exceptions import VCSError @@ -366,8 +364,6 @@ for ui_ in hg_ui: if ui_.ui_active: ui_val = safe_str(ui_.ui_value) - if ui_.ui_section == 'hooks' and BRAND != 'kallithea' and ui_val.startswith('python:' + BRAND + '.lib.hooks.'): - ui_val = ui_val.replace('python:' + BRAND + '.lib.hooks.', 'python:kallithea.lib.hooks.') log.debug('settings ui from db: [%s] %s=%s', ui_.ui_section, ui_.ui_key, ui_val) baseui.setconfig(safe_str(ui_.ui_section), safe_str(ui_.ui_key), diff -r 4f4a73acd6b3 -r 0b6d2ca7175f kallithea/model/db.py --- a/kallithea/model/db.py Fri Jul 15 16:02:13 2016 +0200 +++ b/kallithea/model/db.py Mon Jul 18 14:03:17 2016 +0200 @@ -43,7 +43,6 @@ from pylons.i18n.translation import lazy_ugettext as _ -from kallithea import DB_PREFIX from kallithea.lib.exceptions import DefaultUserException from kallithea.lib.vcs import get_backend from kallithea.lib.vcs.utils.helpers import get_scm @@ -165,7 +164,7 @@ } class Setting(Base, BaseModel): - __tablename__ = DB_PREFIX + 'settings' + __tablename__ = 'settings' __table_args__ = ( _table_args_default_dict, ) @@ -328,7 +327,7 @@ class Ui(Base, BaseModel): - __tablename__ = DB_PREFIX + 'ui' + __tablename__ = 'ui' __table_args__ = ( # FIXME: ui_key as key is wrong and should be removed when the corresponding # Ui.get_by_key has been replaced by the composite key