diff --git a/rhodecode/lib/db_manage.py b/rhodecode/lib/db_manage.py --- a/rhodecode/lib/db_manage.py +++ b/rhodecode/lib/db_manage.py @@ -1,16 +1,4 @@ # -*- coding: utf-8 -*- -""" - rhodecode.lib.db_manage - ~~~~~~~~~~~~~~~~~~~~~~~ - - Database creation, and setup module for RhodeCode. Used for creation - of database as well as for migration operations - - :created_on: Apr 10, 2010 - :author: marcink - :copyright: (C) 2010-2012 Marcin Kuzminski - :license: GPLv3, see COPYING for more details. -""" # 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 @@ -23,6 +11,18 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +""" +rhodecode.lib.db_manage +~~~~~~~~~~~~~~~~~~~~~~~ + +Database creation, and setup module for RhodeCode. Used for creation +of database as well as for migration operations + +:created_on: Apr 10, 2010 +:author: marcink +:copyright: (c) 2013 RhodeCode GmbH. +:license: GPLv3, see LICENSE for more details. +""" import os import sys @@ -39,15 +39,15 @@ from rhodecode.lib.utils import ask_ok from rhodecode.model import init_model from rhodecode.model.db import User, Permission, RhodeCodeUi, \ RhodeCodeSetting, UserToPerm, DbMigrateVersion, RepoGroup, \ - UserRepoGroupToPerm, CacheInvalidation, UserGroup + UserRepoGroupToPerm, CacheInvalidation, UserGroup, Repository from sqlalchemy.engine import create_engine -from rhodecode.model.repos_group import ReposGroupModel +from rhodecode.model.repo_group import RepoGroupModel #from rhodecode.model import meta from rhodecode.model.meta import Session, Base from rhodecode.model.repo import RepoModel from rhodecode.model.permission import PermissionModel -from rhodecode.model.users_group import UserGroupModel +from rhodecode.model.user_group import UserGroupModel log = logging.getLogger(__name__) @@ -61,172 +61,8 @@ def notify(msg): print('\n%s\n*** %s ***\n%s' % ('*' * ml, msg, '*' * ml)).upper() -class UpgradeSteps(object): - """ - Those steps follow schema versions so for example schema - for example schema with seq 002 == step_2 and so on. - """ - - def __init__(self, klass): - self.klass = klass - - def step_1(self): - pass - - def step_2(self): - notify('Patching repo paths for newer version of RhodeCode') - self.klass.fix_repo_paths() - - notify('Patching default user of RhodeCode') - self.klass.fix_default_user() - - log.info('Changing ui settings') - self.klass.create_ui_settings() - - def step_3(self): - notify('Adding additional settings into RhodeCode db') - self.klass.fix_settings() - notify('Adding ldap defaults') - self.klass.create_ldap_options(skip_existing=True) - - def step_4(self): - notify('create permissions and fix groups') - self.klass.create_permissions() - self.klass.fixup_groups() - - def step_5(self): - pass - - def step_6(self): - - notify('re-checking permissions') - self.klass.create_permissions() - - notify('installing new UI options') - sett4 = RhodeCodeSetting('show_public_icon', True) - Session().add(sett4) - sett5 = RhodeCodeSetting('show_private_icon', True) - Session().add(sett5) - sett6 = RhodeCodeSetting('stylify_metatags', False) - Session().add(sett6) - - notify('fixing old PULL hook') - _pull = RhodeCodeUi.get_by_key('preoutgoing.pull_logger') - if _pull: - _pull.ui_key = RhodeCodeUi.HOOK_PULL - Session().add(_pull) - - notify('fixing old PUSH hook') - _push = RhodeCodeUi.get_by_key('pretxnchangegroup.push_logger') - if _push: - _push.ui_key = RhodeCodeUi.HOOK_PUSH - Session().add(_push) - - notify('installing new pre-push hook') - hooks4 = RhodeCodeUi() - hooks4.ui_section = 'hooks' - hooks4.ui_key = RhodeCodeUi.HOOK_PRE_PUSH - hooks4.ui_value = 'python:rhodecode.lib.hooks.pre_push' - Session().add(hooks4) - - notify('installing new pre-pull hook') - hooks6 = RhodeCodeUi() - hooks6.ui_section = 'hooks' - hooks6.ui_key = RhodeCodeUi.HOOK_PRE_PULL - hooks6.ui_value = 'python:rhodecode.lib.hooks.pre_pull' - Session().add(hooks6) - - notify('installing hgsubversion option') - # enable hgsubversion disabled by default - hgsubversion = RhodeCodeUi() - hgsubversion.ui_section = 'extensions' - hgsubversion.ui_key = 'hgsubversion' - hgsubversion.ui_value = '' - hgsubversion.ui_active = False - Session().add(hgsubversion) - - notify('installing hg git option') - # enable hggit disabled by default - hggit = RhodeCodeUi() - hggit.ui_section = 'extensions' - hggit.ui_key = 'hggit' - hggit.ui_value = '' - hggit.ui_active = False - Session().add(hggit) - - notify('re-check default permissions') - default_user = User.get_by_username(User.DEFAULT_USER) - perm = Permission.get_by_key('hg.fork.repository') - reg_perm = UserToPerm() - reg_perm.user = default_user - reg_perm.permission = perm - Session().add(reg_perm) - - def step_7(self): - perm_fixes = self.klass.reset_permissions(User.DEFAULT_USER) - Session().commit() - if perm_fixes: - notify('There was an inconsistent state of permissions ' - 'detected for default user. Permissions are now ' - 'reset to the default value for default user. ' - 'Please validate and check default permissions ' - 'in admin panel') - - def step_8(self): - self.klass.create_permissions() - self.klass.populate_default_permissions() - self.klass.create_default_options(skip_existing=True) - Session().commit() - - def step_9(self): - pass - - def step_10(self): - pass - - def step_11(self): - self.klass.update_repo_info() - - def step_12(self): - self.klass.create_permissions() - Session().commit() - - self.klass.populate_default_permissions() - Session().commit() - - #fix all usergroups - ug_model = UserGroupModel() - for ug in UserGroup.get_all(): - perm_obj = ug_model._create_default_perms(ug) - Session().add(perm_obj) - Session().commit() - - adm = User.get_first_admin() - # fix owners of UserGroup - for ug in Session().query(UserGroup).all(): - ug.user_id = adm.user_id - Session().add(ug) - Session().commit() - - # fix owners of RepoGroup - for ug in Session().query(RepoGroup).all(): - ug.user_id = adm.user_id - Session().add(ug) - Session().commit() - - def step_13(self): - pass - - def step_14(self): - # fix nullable columns on last_update - for r in RepoModel().get_all(): - if r.updated_on is None: - r.updated_on = datetime.datetime.fromtimestamp(0) - Session().add(r) - Session().commit() - class DbManage(object): - def __init__(self, log_sql, dbconf, root, tests=False, cli_args={}): + def __init__(self, log_sql, dbconf, root, tests=False, SESSION=None, cli_args={}): self.dbname = dbconf.split('/')[-1] self.tests = tests self.root = root @@ -234,17 +70,21 @@ class DbManage(object): self.log_sql = log_sql self.db_exists = False self.cli_args = cli_args - self.init_db() + self.init_db(SESSION=SESSION) force_ask = self.cli_args.get('force_ask') if force_ask is not None: global ask_ok ask_ok = lambda *args, **kwargs: force_ask - def init_db(self): - engine = create_engine(self.dburi, echo=self.log_sql) - init_model(engine) - self.sa = Session() + def init_db(self, SESSION=None): + if SESSION: + self.sa = SESSION + else: + #init new sessions + engine = create_engine(self.dburi, echo=self.log_sql) + init_model(engine) + self.sa = Session() def create_tables(self, override=False): """ @@ -257,7 +97,8 @@ class DbManage(object): else: destroy = ask_ok('Are you sure to destroy old database ? [y/n]') if not destroy: - sys.exit('Nothing tables created') + print 'Nothing done.' + sys.exit(0) if destroy: Base.metadata.drop_all() @@ -289,13 +130,14 @@ class DbManage(object): '********************** WARNING **********************\n' 'Make sure your version of sqlite is at least 3.7.X. \n' 'Earlier versions are known to fail on some migrations\n' - '*****************************************************\n' - ) + '*****************************************************\n') + upgrade = ask_ok('You are about to perform database upgrade, make ' 'sure You backed up your database before. ' 'Continue ? [y/n]') if not upgrade: - sys.exit('No upgrade performed') + print 'No upgrade performed' + sys.exit(0) repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))), 'rhodecode/lib/dbmigrate') @@ -303,19 +145,19 @@ class DbManage(object): try: curr_version = api.db_version(db_uri, repository_path) - msg = ('Found current database under version' - ' control with version %s' % curr_version) + msg = ('Found current database under version ' + 'control with version %s' % curr_version) except (RuntimeError, DatabaseNotControlledError): curr_version = 1 - msg = ('Current database is not under version control. Setting' - ' as version %s' % curr_version) + msg = ('Current database is not under version control. Setting ' + 'as version %s' % curr_version) api.version_control(db_uri, repository_path, curr_version) notify(msg) - if curr_version == __dbversion__: - sys.exit('This database is already at the newest version') + print 'This database is already at the newest version' + sys.exit(0) # clear cache keys log.info("Clearing cache keys now...") @@ -329,16 +171,11 @@ class DbManage(object): _step = None for step in upgrade_steps: notify('performing upgrade step %s' % step) - time.sleep(2) + time.sleep(0.5) api.upgrade(db_uri, repository_path, step) notify('schema upgrade for step %s completed' % (step,)) - fixture = 'step_%s' % step - notify('performing fixture step %s' % fixture) - getattr(UpgradeSteps(self), fixture)() - self.sa.commit() - notify('fixture %s completed' % (fixture,)) _step = step notify('upgrade to version %s successful' % _step) @@ -367,7 +204,7 @@ class DbManage(object): used mostly for anonymous access """ def_user = self.sa.query(User)\ - .filter(User.username == 'default')\ + .filter(User.username == User.DEFAULT_USER)\ .one() def_user.name = 'Anonymous' @@ -447,7 +284,7 @@ class DbManage(object): self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL, False) - def create_ui_settings(self): + def create_ui_settings(self, repo_store_path): """ Creates ui settings, fills out hooks and disables dotencode @@ -505,6 +342,15 @@ class DbManage(object): largefiles.ui_value = '' self.sa.add(largefiles) + # set default largefiles cache dir, defaults to + # /repo location/.cache/largefiles + largefiles = RhodeCodeUi() + largefiles.ui_section = 'largefiles' + largefiles.ui_key = 'usercache' + largefiles.ui_value = os.path.join(repo_store_path, '.cache', + 'largefiles') + self.sa.add(largefiles) + # enable hgsubversion disabled by default hgsubversion = RhodeCodeUi() hgsubversion.ui_section = 'extensions' @@ -521,37 +367,35 @@ class DbManage(object): hggit.ui_active = False self.sa.add(hggit) - def create_ldap_options(self, skip_existing=False): - """Creates ldap settings""" + def create_auth_plugin_options(self, skip_existing=False): + """ + Create default auth plugin settings, and make it active - for k, v in [('ldap_active', 'false'), ('ldap_host', ''), - ('ldap_port', '389'), ('ldap_tls_kind', 'PLAIN'), - ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''), - ('ldap_dn_pass', ''), ('ldap_base_dn', ''), - ('ldap_filter', ''), ('ldap_search_scope', ''), - ('ldap_attr_login', ''), ('ldap_attr_firstname', ''), - ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]: + :param skip_existing: + """ - if skip_existing and RhodeCodeSetting.get_by_name(k) is not None: + for k, v, t in [('auth_plugins', 'rhodecode.lib.auth_modules.auth_rhodecode', 'list'), + ('auth_rhodecode_enabled', 'True', 'bool')]: + if skip_existing and RhodeCodeSetting.get_by_name(k) != None: log.debug('Skipping option %s' % k) continue - setting = RhodeCodeSetting(k, v) + setting = RhodeCodeSetting(k, v, t) self.sa.add(setting) def create_default_options(self, skip_existing=False): """Creates default settings""" - for k, v in [ - ('default_repo_enable_locking', False), - ('default_repo_enable_downloads', False), - ('default_repo_enable_statistics', False), - ('default_repo_private', False), - ('default_repo_type', 'hg')]: + for k, v, t in [ + ('default_repo_enable_locking', False, 'bool'), + ('default_repo_enable_downloads', False, 'bool'), + ('default_repo_enable_statistics', False, 'bool'), + ('default_repo_private', False, 'bool'), + ('default_repo_type', 'hg', 'unicode')]: if skip_existing and RhodeCodeSetting.get_by_name(k) is not None: log.debug('Skipping option %s' % k) continue - setting = RhodeCodeSetting(k, v) + setting = RhodeCodeSetting(k, v, t) self.sa.add(setting) def fixup_groups(self): @@ -567,7 +411,7 @@ class DbManage(object): if default is None: log.debug('missing default permission for group %s adding' % g) - perm_obj = ReposGroupModel()._create_default_perms(g) + perm_obj = RepoGroupModel()._create_default_perms(g) self.sa.add(perm_obj) def reset_permissions(self, username): @@ -651,7 +495,7 @@ class DbManage(object): def create_settings(self, path): - self.create_ui_settings() + self.create_ui_settings(path) ui_config = [ ('web', 'push_ssl', 'false'), @@ -669,20 +513,25 @@ class DbManage(object): self.sa.add(ui_conf) settings = [ - ('realm', 'RhodeCode authentication', unicode), - ('title', 'RhodeCode', unicode), - ('ga_code', '', unicode), - ('show_public_icon', True, bool), - ('show_private_icon', True, bool), - ('stylify_metatags', False, bool), - ('dashboard_items', 100, int), - ('show_version', True, bool) + ('realm', 'RhodeCode', 'unicode'), + ('title', '', 'unicode'), + ('ga_code', '', 'unicode'), + ('show_public_icon', True, 'bool'), + ('show_private_icon', True, 'bool'), + ('stylify_metatags', False, 'bool'), + ('dashboard_items', 100, 'int'), + ('admin_grid_items', 25, 'int'), + ('show_version', True, 'bool'), + ('use_gravatar', True, 'bool'), + ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'), + ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'), + ('update_url', RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode'), ] for key, val, type_ in settings: - sett = RhodeCodeSetting(key, val) + sett = RhodeCodeSetting(key, val, type_) self.sa.add(sett) - self.create_ldap_options() + self.create_auth_plugin_options() self.create_default_options() log.info('created ui config') @@ -691,7 +540,8 @@ class DbManage(object): log.info('creating user %s' % username) UserModel().create_or_update(username, password, email, firstname='RhodeCode', lastname='Admin', - active=True, admin=admin) + active=True, admin=admin, + extern_type="rhodecode") def create_default_user(self): log.info('creating default user')