Changeset - 60cbde084047
[Not reviewed]
beta
0 4 0
Marcin Kuzminski - 15 years ago 2010-12-11 04:29:21
marcin@python-works.com
fixed wrong migration schema
added filling out some default options for db migration script,
added path fix
4 files changed with 128 insertions and 52 deletions:
0 comments (0 inline, 0 general)
rhodecode/lib/db_manage.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.lib.db_manage
 
    ~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    Database creation, and setup module for RhodeCode
 
    
 
    :created_on: Apr 10, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
 
    :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; version 2
 
# of the License or (at your opinion) any later version of the license.
 
# 
 
# 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, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 

	
 
import os
 
import sys
 
import uuid
 
import logging
 
from os.path import dirname as dn, join as jn
 

	
 
from rhodecode import __dbversion__
 
from rhodecode.model.db import
 
from rhodecode.model import meta
 

	
 
from rhodecode.lib.auth import get_crypt_password
 
from rhodecode.lib.utils import ask_ok
 
from rhodecode.model import init_model
 
from rhodecode.model.db import User, Permission, RhodeCodeUi, RhodeCodeSettings, \
 
    UserToPerm, DbMigrateVersion
 

	
 
from sqlalchemy.engine import create_engine
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
class DbManage(object):
 
    def __init__(self, log_sql, dbconf, root, tests=False):
 
        self.dbname = dbconf.split('/')[-1]
 
        self.tests = tests
 
        self.root = root
 
        self.dburi = dbconf
 
        engine = create_engine(self.dburi, echo=log_sql)
 
        init_model(engine)
 
        self.sa = meta.Session()
 
        self.db_exists = False
 

	
 
    def check_for_db(self, override):
 
        db_path = jn(self.root, self.dbname)
 
        if self.dburi.startswith('sqlite'):
 
            log.info('checking for existing db in %s', db_path)
 
            if os.path.isfile(db_path):
 

	
 
                self.db_exists = True
 
                if not override:
 
                    raise Exception('database already exists')
 

	
 
    def create_tables(self, override=False):
 
        """Create a auth database
 
        """
 
        Create a auth database
 
        """
 

	
 
        self.check_for_db(override)
 
        if self.db_exists:
 
            log.info("database exist and it's going to be destroyed")
 
            if self.tests:
 
                destroy = True
 
            else:
 
                destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
 
            if not destroy:
 
                sys.exit()
 
            if self.db_exists and destroy:
 
                os.remove(jn(self.root, self.dbname))
 
        checkfirst = not override
 
        meta.Base.metadata.create_all(checkfirst=checkfirst)
 
        log.info('Created tables for %s', self.dbname)
 

	
 

	
 

	
 
    def set_db_version(self):
 
        try:
 
            ver = DbMigrateVersion()
 
            ver.version = __dbversion__
 
            ver.repository_id = 'rhodecode_db_migrations'
 
            ver.repository_path = 'versions'
 
            self.sa.add(ver)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 
        log.info('db version set to: %s', __dbversion__)
 

	
 
    def fix_repo_paths(self):
 
        """Fixes a old rhodecode version path into new one without a '*'
 
        """
 

	
 
        paths = self.sa.query(RhodeCodeUi)\
 
                .filter(RhodeCodeUi.ui_key == '/')\
 
                .scalar()
 

	
 
        paths.ui_value = paths.ui_value.replace('*', '')
 

	
 
        try:
 
            self.sa.add(paths)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 

	
 

	
 
    def admin_prompt(self, second=False):
 
        if not self.tests:
 
            import getpass
 

	
 

	
 
            def get_password():
 
                password = getpass.getpass('Specify admin password (min 6 chars):')
 
                confirm = getpass.getpass('Confirm password:')
 

	
 
                if password != confirm:
 
                    log.error('passwords mismatch')
 
                    return False
 
                if len(password) < 6:
 
                    log.error('password is to short use at least 6 characters')
 
                    return False
 

	
 
                return password
 

	
 
            username = raw_input('Specify admin username:')
 

	
 
            password = get_password()
 
            if not password:
 
                #second try
 
                password = get_password()
 
                if not password:
 
                    sys.exit()
 

	
 
            email = raw_input('Specify admin email:')
 
            self.create_user(username, password, email, True)
 
        else:
 
            log.info('creating admin and regular test users')
 
            self.create_user('test_admin', 'test12', 'test_admin@mail.com', True)
 
            self.create_user('test_regular', 'test12', 'test_regular@mail.com', False)
 
            self.create_user('test_regular2', 'test12', 'test_regular2@mail.com', False)
 

	
 
    def create_ui_settings(self):
 
        """Creates ui settings, fills out hooks
 
        and disables dotencode
 

	
 
        """
 
        #HOOKS
 
        hooks1_key = 'changegroup.update'
 
        hooks1_ = self.sa.query(RhodeCodeUi)\
 
            .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
 

	
 
        hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
 
        hooks1.ui_section = 'hooks'
 
        hooks1.ui_key = hooks1_key
 
        hooks1.ui_value = 'hg update >&2'
 
        hooks1.ui_active = False
 

	
 
        hooks2_key = 'changegroup.repo_size'
 
        hooks2_ = self.sa.query(RhodeCodeUi)\
 
            .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
 

	
 
        hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
 
        hooks2.ui_section = 'hooks'
 
        hooks2.ui_key = hooks2_key
 
        hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
 

	
 
        hooks3 = RhodeCodeUi()
 
        hooks3.ui_section = 'hooks'
 
        hooks3.ui_key = 'pretxnchangegroup.push_logger'
 
        hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
 

	
 
        hooks4 = RhodeCodeUi()
 
        hooks4.ui_section = 'hooks'
 
        hooks4.ui_key = 'preoutgoing.pull_logger'
 
        hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
 

	
 
        #For mercurial 1.7 set backward comapatibility with format
 
        dotencode_disable = RhodeCodeUi()
 
        dotencode_disable.ui_section = 'format'
 
        dotencode_disable.ui_key = 'dotencode'
 
        dotencode_disable.ui_value = 'false'
 

	
 
        try:
 
            self.sa.add(hooks1)
 
            self.sa.add(hooks2)
 
            self.sa.add(hooks3)
 
            self.sa.add(hooks4)
 
            self.sa.add(dotencode_disable)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 

	
 
    def create_ldap_options(self):
 
        """Creates ldap settings"""
 

	
 
        try:
 
            for k in ['ldap_active', 'ldap_host', 'ldap_port', 'ldap_ldaps',
 
                      'ldap_dn_user', 'ldap_dn_pass', 'ldap_base_dn']:
 

	
 
                setting = RhodeCodeSettings(k, '')
 
                self.sa.add(setting)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def config_prompt(self, test_repo_path=''):
 
        log.info('Setting up repositories config')
 

	
 
        if not self.tests and not test_repo_path:
 
            path = raw_input('Specify valid full path to your repositories'
 
                        ' you can change this later in application settings:')
 
        else:
 
            path = test_repo_path
 

	
 
        if not os.path.isdir(path):
 
            log.error('You entered wrong path: %s', path)
 
            sys.exit()
 

	
 
        hooks1 = RhodeCodeUi()
 
        hooks1.ui_section = 'hooks'
 
        hooks1.ui_key = 'changegroup.update'
 
        hooks1.ui_value = 'hg update >&2'
 
        hooks1.ui_active = False
 

	
 
        hooks2 = RhodeCodeUi()
 
        hooks2.ui_section = 'hooks'
 
        hooks2.ui_key = 'changegroup.repo_size'
 
        hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
 
        self.create_ui_settings()
 

	
 
        hooks3 = RhodeCodeUi()
 
        hooks3.ui_section = 'hooks'
 
        hooks3.ui_key = 'pretxnchangegroup.push_logger'
 
        hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
 

	
 
        hooks4 = RhodeCodeUi()
 
        hooks4.ui_section = 'hooks'
 
        hooks4.ui_key = 'preoutgoing.pull_logger'
 
        hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
 

	
 
        #for mercurial 1.7 set backward comapatibility with format
 

	
 
        dotencode_disable = RhodeCodeUi()
 
        dotencode_disable.ui_section = 'format'
 
        dotencode_disable.ui_key = 'dotencode'
 
        dotencode_disable.ui_section = 'false'
 

	
 

	
 
        #HG UI OPTIONS
 
        web1 = RhodeCodeUi()
 
        web1.ui_section = 'web'
 
        web1.ui_key = 'push_ssl'
 
        web1.ui_value = 'false'
 

	
 
        web2 = RhodeCodeUi()
 
        web2.ui_section = 'web'
 
        web2.ui_key = 'allow_archive'
 
        web2.ui_value = 'gz zip bz2'
 

	
 
        web3 = RhodeCodeUi()
 
        web3.ui_section = 'web'
 
        web3.ui_key = 'allow_push'
 
        web3.ui_value = '*'
 

	
 
        web4 = RhodeCodeUi()
 
        web4.ui_section = 'web'
 
        web4.ui_key = 'baseurl'
 
        web4.ui_value = '/'
 

	
 
        paths = RhodeCodeUi()
 
        paths.ui_section = 'paths'
 
        paths.ui_key = '/'
 
        paths.ui_value = path
 

	
 

	
 
        hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication')
 
        hgsettings2 = RhodeCodeSettings('title', 'RhodeCode')
 

	
 

	
 
        try:
 
            self.sa.add(hooks1)
 
            self.sa.add(hooks2)
 
            self.sa.add(hooks3)
 
            self.sa.add(hooks4)
 
            self.sa.add(web1)
 
            self.sa.add(web2)
 
            self.sa.add(web3)
 
            self.sa.add(web4)
 
            self.sa.add(paths)
 
            self.sa.add(hgsettings1)
 
            self.sa.add(hgsettings2)
 
            self.sa.add(dotencode_disable)
 
            for k in ['ldap_active', 'ldap_host', 'ldap_port', 'ldap_ldaps',
 
                      'ldap_dn_user', 'ldap_dn_pass', 'ldap_base_dn']:
 

	
 
                setting = RhodeCodeSettings(k, '')
 
                self.sa.add(setting)
 

	
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
        self.create_ldap_options()
 

	
 
        log.info('created ui config')
 

	
 
    def create_user(self, username, password, email='', admin=False):
 
        log.info('creating administrator user %s', username)
 
        new_user = User()
 
        new_user.username = username
 
        new_user.password = get_crypt_password(password)
 
        new_user.name = 'RhodeCode'
 
        new_user.lastname = 'Admin'
 
        new_user.email = email
 
        new_user.admin = admin
 
        new_user.active = True
 

	
 
        try:
 
            self.sa.add(new_user)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def create_default_user(self):
 
        log.info('creating default user')
 
        #create default user for handling default permissions.
 
        def_user = User()
 
        def_user.username = 'default'
 
        def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
 
        def_user.name = 'Anonymous'
 
        def_user.lastname = 'User'
 
        def_user.email = 'anonymous@rhodecode.org'
 
        def_user.admin = False
 
        def_user.active = False
 
        try:
 
            self.sa.add(def_user)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def create_permissions(self):
 
        #module.(access|create|change|delete)_[name]
 
        #module.(read|write|owner)
 
        perms = [('repository.none', 'Repository no access'),
 
                 ('repository.read', 'Repository read access'),
 
                 ('repository.write', 'Repository write access'),
 
                 ('repository.admin', 'Repository admin access'),
 
                 ('hg.admin', 'Hg Administrator'),
 
                 ('hg.create.repository', 'Repository create'),
 
                 ('hg.create.none', 'Repository creation disabled'),
 
                 ('hg.register.none', 'Register disabled'),
 
                 ('hg.register.manual_activate', 'Register new user with rhodecode without manual activation'),
 
                 ('hg.register.auto_activate', 'Register new user with rhodecode without auto activation'),
 
                ]
 

	
 
        for p in perms:
 
            new_perm = Permission()
 
            new_perm.permission_name = p[0]
 
            new_perm.permission_longname = p[1]
 
            try:
 
                self.sa.add(new_perm)
 
                self.sa.commit()
 
            except:
 
                self.sa.rollback()
 
                raise
 

	
 
    def populate_default_permissions(self):
 
        log.info('creating default user permissions')
 

	
 
        default_user = self.sa.query(User)\
 
        .filter(User.username == 'default').scalar()
 

	
 
        reg_perm = UserToPerm()
 
        reg_perm.user = default_user
 
        reg_perm.permission = self.sa.query(Permission)\
 
        .filter(Permission.permission_name == 'hg.register.manual_activate')\
 
        .scalar()
 

	
 
        create_repo_perm = UserToPerm()
 
        create_repo_perm.user = default_user
 
        create_repo_perm.permission = self.sa.query(Permission)\
 
        .filter(Permission.permission_name == 'hg.create.repository')\
 
        .scalar()
 

	
 
        default_repo_perm = UserToPerm()
 
        default_repo_perm.user = default_user
 
        default_repo_perm.permission = self.sa.query(Permission)\
 
        .filter(Permission.permission_name == 'repository.read')\
 
        .scalar()
 

	
 
        try:
 
            self.sa.add(reg_perm)
 
            self.sa.add(create_repo_perm)
 
            self.sa.add(default_repo_perm)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
rhodecode/lib/dbmigrate/__init__.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.lib.dbmigrate.__init__
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
    
 
    Database migration modules
 
    
 
    :created_on: Dec 11, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
 
    :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; version 2
 
# of the License or (at your opinion) any later version of the license.
 
# 
 
# 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, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 

	
 
import logging
 
from sqlalchemy import engine_from_config
 

	
 
from rhodecode import __dbversion__
 
from rhodecode.lib.dbmigrate.migrate.versioning import api
 
from rhodecode.lib.dbmigrate.migrate.exceptions import \
 
    DatabaseNotControlledError
 
from rhodecode.lib.utils import BasePasterCommand, Command, add_cache
 
from rhodecode.lib.db_manage import DbManage
 

	
 
log = logging.getLogger(__name__)
 

	
 
class UpgradeDb(BasePasterCommand):
 
    """Command used for paster to upgrade our database to newer version
 
    """
 

	
 
    max_args = 1
 
    min_args = 1
 

	
 
    usage = "CONFIG_FILE"
 
    summary = "Upgrades current db to newer version given configuration file"
 
    group_name = "RhodeCode"
 

	
 
    parser = Command.standard_parser(verbose=True)
 

	
 
    def command(self):
 
        from pylons import config
 

	
 
        add_cache(config)
 

	
 
        #engine = engine_from_config(config, 'sqlalchemy.db1.')
 

	
 

	
 
        repository_path = 'rhodecode/lib/dbmigrate'
 
        db_uri = config['sqlalchemy.db1.url']
 

	
 
        try:
 
            curr_version = api.db_version(db_uri, repository_path)
 
            msg = ('Found current database under version'
 
                 ' control with version %s' % curr_version)
 

	
 
        except (RuntimeError, DatabaseNotControlledError), e:
 
            curr_version = 1
 
            msg = ('Current database is not under version control setting'
 
                   ' as version %s' % curr_version)
 
            api.version_control(db_uri, repository_path, curr_version)
 

	
 
        self.notify_msg(msg)
 

	
 
        print msg
 
        #now we have our dbversion we can do upgrade
 
        self.notify_msg('attempting to do database upgrade to version %s' \
 
                        % __dbversion__)
 

	
 
        api.upgrade(db_uri, repository_path, __dbversion__)
 
        self.notify_msg('Schema upgrade completed')
 

	
 
        msg = 'attempting to do database upgrade to version %s' % __dbversion__
 
        print msg
 
        api.upgrade(db_uri, repository_path, __dbversion__)
 
        #we need to make now some extra operations into database
 
        self.notify_msg('Prociding with database updates')
 

	
 
        dbmanage = DbManage(log_sql=True, dbconf=db_uri,
 
                            root=config['here'], tests=False)
 

	
 
        self.notify_msg('Patching repo paths for newer version of rhodecode')
 
        dbmanage.fix_repo_paths()
 

	
 
        self.notify_msg('Changing ui settings')
 
        dbmanage.create_ui_settings()
 

	
 

	
 
    def update_parser(self):
 
        self.parser.add_option('--sql',
 
                      action='store_true',
 
                      dest='just_sql',
 
                      help="Prints upgrade sql for further investigation",
 
                      default=False)
rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py
Show inline comments
 
import logging
 
import datetime
 

	
 
from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relation, backref, class_mapper
 
from sqlalchemy.orm.session import Session
 
from rhodecode.model.meta import Base
 
from rhodecode.model.db import BaseModel
 

	
 
from rhodecode.lib.dbmigrate.migrate import *
 

	
 
log = logging.getLogger(__name__)
 

	
 
def upgrade(migrate_engine):
 
    """ Upgrade operations go here. 
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 

	
 
    #==========================================================================
 
    # Upgrade of `users` table
 
    #==========================================================================
 
    tblname = 'users'
 
    tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
 
                    autoload_with=migrate_engine)
 

	
 
    #ADD is_ldap column
 
    is_ldap = Column("is_ldap", Boolean(), nullable=True,
 
                     unique=None, default=False)
 
    is_ldap.create(tbl, populate_default=True)
 
    is_ldap.alter(nullable=False)
 

	
 
    #==========================================================================
 
    # Upgrade of `user_logs` table
 
    #==========================================================================    
 

	
 
    tblname = 'users'
 
    tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
 
                    autoload_with=migrate_engine)
 

	
 
    #ADD revision column
 
    revision = Column('revision', TEXT(length=None, convert_unicode=False,
 
                                       assert_unicode=None),
 
                      nullable=True, unique=None, default=None)
 
    revision.create(tbl)
 

	
 

	
 

	
 
    #==========================================================================
 
    # Upgrade of `repositories` table
 
    #==========================================================================    
 
    tblname = 'users'
 
    tblname = 'repositories'
 
    tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
 
                    autoload_with=migrate_engine)
 

	
 
    #ADD repo_type column
 
    #ADD repo_type column#
 
    repo_type = Column("repo_type", String(length=None, convert_unicode=False,
 
                                           assert_unicode=None),
 
                       nullable=True, unique=False, default='hg')
 

	
 
    repo_type.create(tbl, populate_default=True)
 
    repo_type.alter(nullable=False)
 
    #repo_type.alter(nullable=False)
 

	
 
    #ADD statistics column
 
    #ADD statistics column#
 
    enable_statistics = Column("statistics", Boolean(), nullable=True,
 
                               unique=None, default=True)
 
    enable_statistics.create(tbl)
 

	
 

	
 

	
 
    #==========================================================================
 
    # Add table `user_followings`
 
    #==========================================================================
 
    tblname = 'user_followings'
 

	
 
    class UserFollowing(Base, BaseModel):
 
        __tablename__ = 'user_followings'
 
        __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
 
                          UniqueConstraint('user_id', 'follows_user_id')
 
                          , {'useexisting':True})
 

	
 
        user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
        user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
 
        follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=None, default=None)
 
        follows_user_id = Column("follows_user_id", Integer(), ForeignKey(u'users.user_id'), nullable=True, unique=None, default=None)
 

	
 
        user = relation('User', primaryjoin='User.user_id==UserFollowing.user_id')
 

	
 
        follows_user = relation('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
 
        follows_repository = relation('Repository')
 

	
 
    Base.metadata.tables[tblname].create(migrate_engine)
 

	
 
    #==========================================================================
 
    # Add table `cache_invalidation`
 
    #==========================================================================
 
    tblname = 'cache_invalidation'
 

	
 
    class CacheInvalidation(Base, BaseModel):
 
        __tablename__ = 'cache_invalidation'
 
        __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
 
        cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
        cache_key = Column("cache_key", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
        cache_args = Column("cache_args", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
        cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
 

	
 

	
 
        def __init__(self, cache_key, cache_args=''):
 
            self.cache_key = cache_key
 
            self.cache_args = cache_args
 
            self.cache_active = False
 

	
 
        def __repr__(self):
 
            return "<CacheInvalidation('%s:%s')>" % (self.cache_id, self.cache_key)
 

	
 
    Base.metadata.tables[tblname].create(migrate_engine)
 

	
 
    return
 

	
 

	
 

	
 

	
 

	
 

	
 
def downgrade(migrate_engine):
 
    meta = MetaData()
 
    meta.bind = migrate_engine
 

	
 

	
rhodecode/lib/utils.py
Show inline comments
 
@@ -374,228 +374,241 @@ class OrderedDict(dict, DictMixin):
 

	
 
    def __reduce__(self):
 
        items = [[k, self[k]] for k in self]
 
        tmp = self.__map, self.__end
 
        del self.__map, self.__end
 
        inst_dict = vars(self).copy()
 
        self.__map, self.__end = tmp
 
        if inst_dict:
 
            return (self.__class__, (items,), inst_dict)
 
        return self.__class__, (items,)
 

	
 
    def keys(self):
 
        return list(self)
 

	
 
    setdefault = DictMixin.setdefault
 
    update = DictMixin.update
 
    pop = DictMixin.pop
 
    values = DictMixin.values
 
    items = DictMixin.items
 
    iterkeys = DictMixin.iterkeys
 
    itervalues = DictMixin.itervalues
 
    iteritems = DictMixin.iteritems
 

	
 
    def __repr__(self):
 
        if not self:
 
            return '%s()' % (self.__class__.__name__,)
 
        return '%s(%r)' % (self.__class__.__name__, self.items())
 

	
 
    def copy(self):
 
        return self.__class__(self)
 

	
 
    @classmethod
 
    def fromkeys(cls, iterable, value=None):
 
        d = cls()
 
        for key in iterable:
 
            d[key] = value
 
        return d
 

	
 
    def __eq__(self, other):
 
        if isinstance(other, OrderedDict):
 
            return len(self) == len(other) and self.items() == other.items()
 
        return dict.__eq__(self, other)
 

	
 
    def __ne__(self, other):
 
        return not self == other
 

	
 

	
 
#set cache regions for beaker so celery can utilise it
 
def add_cache(settings):
 
    cache_settings = {'regions':None}
 
    for key in settings.keys():
 
        for prefix in ['beaker.cache.', 'cache.']:
 
            if key.startswith(prefix):
 
                name = key.split(prefix)[1].strip()
 
                cache_settings[name] = settings[key].strip()
 
    if cache_settings['regions']:
 
        for region in cache_settings['regions'].split(','):
 
            region = region.strip()
 
            region_settings = {}
 
            for key, value in cache_settings.items():
 
                if key.startswith(region):
 
                    region_settings[key.split('.')[1]] = value
 
            region_settings['expire'] = int(region_settings.get('expire',
 
                                                                60))
 
            region_settings.setdefault('lock_dir',
 
                                       cache_settings.get('lock_dir'))
 
            if 'type' not in region_settings:
 
                region_settings['type'] = cache_settings.get('type',
 
                                                             'memory')
 
            beaker.cache.cache_regions[region] = region_settings
 

	
 
def get_current_revision():
 
    """
 
    Returns tuple of (number, id) from repository containing this package
 
    or None if repository could not be found.
 
    """
 
    try:
 
        from vcs import get_repo
 
        from vcs.utils.helpers import get_scm
 
        from vcs.exceptions import RepositoryError, VCSError
 
        repopath = os.path.join(os.path.dirname(__file__), '..', '..')
 
        scm = get_scm(repopath)[0]
 
        repo = get_repo(path=repopath, alias=scm)
 
        tip = repo.get_changeset()
 
        return (tip.revision, tip.short_id)
 
    except (ImportError, RepositoryError, VCSError), err:
 
        logging.debug("Cannot retrieve rhodecode's revision. Original error "
 
                      "was: %s" % err)
 
        return None
 

	
 
#===============================================================================
 
# TEST FUNCTIONS AND CREATORS
 
#===============================================================================
 
def create_test_index(repo_location, full_index):
 
    """Makes default test index
 
    :param repo_location:
 
    :param full_index:
 
    """
 
    from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
 
    from rhodecode.lib.pidlock import DaemonLock, LockHeld
 
    import shutil
 

	
 
    index_location = os.path.join(repo_location, 'index')
 
    if os.path.exists(index_location):
 
        shutil.rmtree(index_location)
 

	
 
    try:
 
        l = DaemonLock()
 
        WhooshIndexingDaemon(index_location=index_location,
 
                             repo_location=repo_location)\
 
            .run(full_index=full_index)
 
        l.release()
 
    except LockHeld:
 
        pass
 

	
 
def create_test_env(repos_test_path, config):
 
    """Makes a fresh database and 
 
    install test repository into tmp dir
 
    """
 
    from rhodecode.lib.db_manage import DbManage
 
    from rhodecode.tests import HG_REPO, GIT_REPO, NEW_HG_REPO, NEW_GIT_REPO, \
 
        HG_FORK, GIT_FORK, TESTS_TMP_PATH
 
    import tarfile
 
    import shutil
 
    from os.path import dirname as dn, join as jn, abspath
 

	
 
    log = logging.getLogger('TestEnvCreator')
 
    # create logger
 
    log.setLevel(logging.DEBUG)
 
    log.propagate = True
 
    # create console handler and set level to debug
 
    ch = logging.StreamHandler()
 
    ch.setLevel(logging.DEBUG)
 

	
 
    # create formatter
 
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
 

	
 
    # add formatter to ch
 
    ch.setFormatter(formatter)
 

	
 
    # add ch to logger
 
    log.addHandler(ch)
 

	
 
    #PART ONE create db
 
    dbconf = config['sqlalchemy.db1.url']
 
    log.debug('making test db %s', dbconf)
 

	
 
    dbmanage = DbManage(log_sql=True, dbconf=dbconf, root=config['here'],
 
                        tests=True)
 
    dbmanage.create_tables(override=True)
 
    dbmanage.config_prompt(repos_test_path)
 
    dbmanage.create_default_user()
 
    dbmanage.admin_prompt()
 
    dbmanage.create_permissions()
 
    dbmanage.populate_default_permissions()
 

	
 
    #PART TWO make test repo
 
    log.debug('making test vcs repositories')
 

	
 
    #remove old one from previos tests
 
    for r in [HG_REPO, GIT_REPO, NEW_HG_REPO, NEW_GIT_REPO, HG_FORK, GIT_FORK]:
 

	
 
        if os.path.isdir(jn(TESTS_TMP_PATH, r)):
 
            log.debug('removing %s', r)
 
            shutil.rmtree(jn(TESTS_TMP_PATH, r))
 

	
 
    #CREATE DEFAULT HG REPOSITORY
 
    cur_dir = dn(dn(abspath(__file__)))
 
    tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test_hg.tar.gz"))
 
    tar.extractall(jn(TESTS_TMP_PATH, HG_REPO))
 
    tar.close()
 

	
 

	
 
#==============================================================================
 
# PASTER COMMANDS
 
#==============================================================================
 

	
 
class BasePasterCommand(Command):
 
    """
 
    Abstract Base Class for paster commands.
 

	
 
    The celery commands are somewhat aggressive about loading
 
    celery.conf, and since our module sets the `CELERY_LOADER`
 
    environment variable to our loader, we have to bootstrap a bit and
 
    make sure we've had a chance to load the pylons config off of the
 
    command line, otherwise everything fails.
 
    """
 
    min_args = 1
 
    min_args_error = "Please provide a paster config file as an argument."
 
    takes_config_file = 1
 
    requires_config_file = True
 

	
 
    def notify_msg(self, msg, log=False):
 
        """Make a notification to user, additionally if logger is passed
 
        it logs this action using given logger
 
        
 
        :param msg: message that will be printed to user
 
        :param log: logging instance, to use to additionally log this message
 
        
 
        """
 
        print msg
 
        if log and isinstance(log, logging):
 
            log(msg)
 

	
 

	
 
    def run(self, args):
 
        """
 
        Overrides Command.run
 
        
 
        Checks for a config file argument and loads it.
 
        """
 
        if len(args) < self.min_args:
 
            raise BadCommand(
 
                self.min_args_error % {'min_args': self.min_args,
 
                                       'actual_args': len(args)})
 

	
 
        # Decrement because we're going to lob off the first argument.
 
        # @@ This is hacky
 
        self.min_args -= 1
 
        self.bootstrap_config(args[0])
 
        self.update_parser()
 
        return super(BasePasterCommand, self).run(args[1:])
 

	
 
    def update_parser(self):
 
        """
 
        Abstract method.  Allows for the class's parser to be updated
 
        before the superclass's `run` method is called.  Necessary to
 
        allow options/arguments to be passed through to the underlying
 
        celery command.
 
        """
 
        raise NotImplementedError("Abstract Method.")
 

	
 
    def bootstrap_config(self, conf):
 
        """
 
        Loads the pylons configuration.
 
        """
 
        from pylons import config as pylonsconfig
 

	
 
        path_to_ini_file = os.path.realpath(conf)
 
        conf = paste.deploy.appconfig('config:' + path_to_ini_file)
 
        pylonsconfig.init_app(conf.global_conf, conf.local_conf)
0 comments (0 inline, 0 general)