db_manage.py
722 lines
| 25.1 KiB
| text/x-python
|
PythonLexer
r835 | # -*- coding: utf-8 -*- | |||
""" | ||||
rhodecode.lib.db_manage | ||||
~~~~~~~~~~~~~~~~~~~~~~~ | ||||
r838 | Database creation, and setup module for RhodeCode. Used for creation | |||
of database as well as for migration operations | ||||
r1203 | ||||
r835 | :created_on: Apr 10, 2010 | |||
:author: marcink | ||||
r1824 | :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> | |||
r835 | :license: GPLv3, see COPYING for more details. | |||
""" | ||||
r1206 | # 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. | ||||
r1203 | # | |||
r547 | # 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. | ||||
r1203 | # | |||
r547 | # You should have received a copy of the GNU General Public License | |||
r1206 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
r547 | ||||
import os | ||||
import sys | ||||
import uuid | ||||
r835 | import logging | |||
from os.path import dirname as dn, join as jn | ||||
r2827 | from rhodecode import __dbversion__, __py_version__ | |||
r547 | ||||
r1634 | from rhodecode.model.user import UserModel | |||
r547 | from rhodecode.lib.utils import ask_ok | |||
from rhodecode.model import init_model | ||||
r1266 | from rhodecode.model.db import User, Permission, RhodeCodeUi, \ | |||
r2765 | RhodeCodeSetting, UserToPerm, DbMigrateVersion, RepoGroup, \ | |||
r1985 | UserRepoGroupToPerm | |||
r835 | ||||
r547 | from sqlalchemy.engine import create_engine | |||
r1985 | from rhodecode.model.repos_group import ReposGroupModel | |||
r2765 | #from rhodecode.model import meta | |||
from rhodecode.model.meta import Session, Base | ||||
r3309 | from rhodecode.model.repo import RepoModel | |||
r2765 | ||||
r835 | ||||
r547 | log = logging.getLogger(__name__) | |||
r1266 | ||||
r2779 | def notify(msg): | |||
""" | ||||
Notification for migrations messages | ||||
""" | ||||
ml = len(msg) + (4 * 2) | ||||
print >> sys.stdout, ('*** %s ***\n%s' % (msg, '*' * ml)).upper() | ||||
r547 | class DbManage(object): | |||
r2919 | def __init__(self, log_sql, dbconf, root, tests=False, cli_args={}): | |||
r781 | self.dbname = dbconf.split('/')[-1] | |||
r547 | self.tests = tests | |||
r552 | self.root = root | |||
r781 | self.dburi = dbconf | |||
r907 | self.log_sql = log_sql | |||
self.db_exists = False | ||||
r2919 | self.cli_args = cli_args | |||
r907 | self.init_db() | |||
r2919 | global ask_ok | |||
Mads Kiilerich
|
r3625 | if self.cli_args.get('force_ask'): | ||
r2919 | ask_ok = lambda *args, **kwargs: True | |||
Mads Kiilerich
|
r3625 | elif not self.cli_args.get('force_ask'): | ||
r2919 | ask_ok = lambda *args, **kwargs: False | |||
r907 | ||||
def init_db(self): | ||||
engine = create_engine(self.dburi, echo=self.log_sql) | ||||
r547 | init_model(engine) | |||
r2765 | self.sa = Session() | |||
r629 | ||||
r2919 | def create_tables(self, override=False): | |||
r1783 | """ | |||
Create a auth database | ||||
r547 | """ | |||
r2919 | ||||
r1138 | log.info("Any existing database is going to be destroyed") | |||
r2919 | if self.tests: | |||
r1138 | destroy = True | |||
else: | ||||
destroy = ask_ok('Are you sure to destroy old database ? [y/n]') | ||||
if not destroy: | ||||
r2919 | sys.exit('Nothing done') | |||
r1138 | if destroy: | |||
r2765 | Base.metadata.drop_all() | |||
r964 | ||||
r547 | checkfirst = not override | |||
r2765 | Base.metadata.create_all(checkfirst=checkfirst) | |||
r1976 | log.info('Created tables for %s' % self.dbname) | |||
r629 | ||||
r834 | def set_db_version(self): | |||
r1734 | ver = DbMigrateVersion() | |||
ver.version = __dbversion__ | ||||
ver.repository_id = 'rhodecode_db_migrations' | ||||
ver.repository_path = 'versions' | ||||
self.sa.add(ver) | ||||
r1976 | log.info('db version set to: %s' % __dbversion__) | |||
r834 | ||||
r839 | def upgrade(self): | |||
r1783 | """ | |||
Upgrades given database schema to given revision following | ||||
r900 | all needed steps, to perform the upgrade | |||
r1203 | ||||
r839 | """ | |||
r841 | ||||
from rhodecode.lib.dbmigrate.migrate.versioning import api | ||||
from rhodecode.lib.dbmigrate.migrate.exceptions import \ | ||||
DatabaseNotControlledError | ||||
r1835 | if 'sqlite' in self.dburi: | |||
print ( | ||||
'********************** 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' | ||||
) | ||||
r839 | 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('Nothing done') | ||||
r843 | repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))), | |||
'rhodecode/lib/dbmigrate') | ||||
r839 | db_uri = self.dburi | |||
try: | ||||
curr_version = api.db_version(db_uri, repository_path) | ||||
msg = ('Found current database under version' | ||||
' control with version %s' % curr_version) | ||||
r1299 | except (RuntimeError, DatabaseNotControlledError): | |||
r839 | 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) | ||||
r2779 | notify(msg) | |||
r839 | ||||
if curr_version == __dbversion__: | ||||
sys.exit('This database is already at the newest version') | ||||
#====================================================================== | ||||
# UPGRADE STEPS | ||||
#====================================================================== | ||||
r2779 | ||||
r839 | class UpgradeSteps(object): | |||
r1783 | """ | |||
Those steps follow schema versions so for example schema | ||||
r900 | for example schema with seq 002 == step_2 and so on. | |||
""" | ||||
r839 | ||||
def __init__(self, klass): | ||||
self.klass = klass | ||||
def step_0(self): | ||||
r1783 | # step 0 is the schema upgrade, and than follow proper upgrades | |||
r3148 | notify('attempting to do database upgrade from ' | |||
'version %s to version %s' %(curr_version, __dbversion__)) | ||||
r839 | api.upgrade(db_uri, repository_path, __dbversion__) | |||
r2779 | notify('Schema upgrade completed') | |||
r839 | ||||
def step_1(self): | ||||
pass | ||||
def step_2(self): | ||||
r2779 | notify('Patching repo paths for newer version of RhodeCode') | |||
r839 | self.klass.fix_repo_paths() | |||
r2779 | notify('Patching default user of RhodeCode') | |||
r839 | self.klass.fix_default_user() | |||
log.info('Changing ui settings') | ||||
self.klass.create_ui_settings() | ||||
r890 | def step_3(self): | |||
r2779 | notify('Adding additional settings into RhodeCode db') | |||
r890 | self.klass.fix_settings() | |||
r2779 | notify('Adding ldap defaults') | |||
r1510 | self.klass.create_ldap_options(skip_existing=True) | |||
r1734 | ||||
r1835 | def step_4(self): | |||
r2779 | notify('create permissions and fix groups') | |||
r1987 | self.klass.create_permissions() | |||
r1985 | self.klass.fixup_groups() | |||
r1835 | ||||
r2000 | def step_5(self): | |||
pass | ||||
r2006 | ||||
r2214 | def step_6(self): | |||
r2779 | ||||
notify('re-checking permissions') | ||||
r2765 | self.klass.create_permissions() | |||
r2781 | 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) | ||||
r2779 | 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') | ||||
r2765 | hooks4 = RhodeCodeUi() | |||
r2767 | hooks4.ui_section = 'hooks' | |||
r2765 | hooks4.ui_key = RhodeCodeUi.HOOK_PRE_PUSH | |||
hooks4.ui_value = 'python:rhodecode.lib.hooks.pre_push' | ||||
Session().add(hooks4) | ||||
r2779 | notify('installing new pre-pull hook') | |||
r2765 | 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) | ||||
r2779 | notify('installing hgsubversion option') | |||
r2765 | # 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) | ||||
r2779 | notify('installing hg git option') | |||
r2765 | # 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) | ||||
r2779 | notify('re-check default permissions') | |||
r2795 | 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) | ||||
r2765 | ||||
r2797 | def step_7(self): | |||
r2798 | 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') | ||||
r2797 | ||||
r3052 | def step_8(self): | |||
self.klass.populate_default_permissions() | ||||
r3056 | self.klass.create_default_options(skip_existing=True) | |||
r3052 | Session().commit() | |||
r3101 | def step_9(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') | ||||
r3125 | def step_10(self): | |||
pass | ||||
r3309 | def step_11(self): | |||
self.klass.update_repo_info() | ||||
r839 | upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1) | |||
r1783 | # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE | |||
r2779 | _step = None | |||
r839 | for step in upgrade_steps: | |||
r2779 | notify('performing upgrade step %s' % step) | |||
r1716 | getattr(UpgradeSteps(self), 'step_%s' % step)() | |||
r1987 | self.sa.commit() | |||
r2779 | _step = step | |||
notify('upgrade to version %s successful' % _step) | ||||
r2000 | ||||
r837 | def fix_repo_paths(self): | |||
r1783 | """ | |||
Fixes a old rhodecode version path into new one without a '*' | ||||
r837 | """ | |||
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() | ||||
r3631 | except Exception: | |||
r837 | self.sa.rollback() | |||
raise | ||||
r838 | def fix_default_user(self): | |||
r1783 | """ | |||
Fixes a old default user with some 'nicer' default values, | ||||
r838 | used mostly for anonymous access | |||
""" | ||||
def_user = self.sa.query(User)\ | ||||
.filter(User.username == 'default')\ | ||||
.one() | ||||
def_user.name = 'Anonymous' | ||||
def_user.lastname = 'User' | ||||
def_user.email = 'anonymous@rhodecode.org' | ||||
try: | ||||
self.sa.add(def_user) | ||||
self.sa.commit() | ||||
r3631 | except Exception: | |||
r838 | self.sa.rollback() | |||
raise | ||||
r890 | def fix_settings(self): | |||
r1783 | """ | |||
Fixes rhodecode settings adds ga_code key for google analytics | ||||
r890 | """ | |||
r837 | ||||
r1633 | hgsettings3 = RhodeCodeSetting('ga_code', '') | |||
r907 | ||||
r890 | try: | |||
self.sa.add(hgsettings3) | ||||
self.sa.commit() | ||||
r3631 | except Exception: | |||
r890 | self.sa.rollback() | |||
raise | ||||
r837 | ||||
r2919 | def admin_prompt(self, second=False): | |||
r547 | if not self.tests: | |||
import getpass | ||||
r629 | ||||
r2284 | # defaults | |||
r2919 | defaults = self.cli_args | |||
r2284 | username = defaults.get('username') | |||
password = defaults.get('password') | ||||
email = defaults.get('email') | ||||
r597 | def get_password(): | |||
r1266 | password = getpass.getpass('Specify admin password ' | |||
'(min 6 chars):') | ||||
r597 | confirm = getpass.getpass('Confirm password:') | |||
r629 | ||||
r597 | 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 | ||||
r629 | ||||
r597 | return password | |||
r2284 | if username is None: | |||
username = raw_input('Specify admin username:') | ||||
if password is None: | ||||
r597 | password = get_password() | |||
if not password: | ||||
r2284 | #second try | |||
password = get_password() | ||||
if not password: | ||||
sys.exit() | ||||
if email is None: | ||||
email = raw_input('Specify admin email:') | ||||
r547 | self.create_user(username, password, email, True) | |||
else: | ||||
log.info('creating admin and regular test users') | ||||
r2765 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \ | |||
TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \ | ||||
TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \ | ||||
r1783 | TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \ | |||
TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL | ||||
r1758 | ||||
self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, | ||||
TEST_USER_ADMIN_EMAIL, True) | ||||
r1783 | ||||
r1758 | self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, | |||
TEST_USER_REGULAR_EMAIL, False) | ||||
r1783 | ||||
r1758 | self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, | |||
TEST_USER_REGULAR2_EMAIL, False) | ||||
r629 | ||||
r837 | def create_ui_settings(self): | |||
r1783 | """ | |||
Creates ui settings, fills out hooks | ||||
r837 | and disables dotencode | |||
r1783 | """ | |||
r1203 | ||||
r837 | #HOOKS | |||
r1460 | hooks1_key = RhodeCodeUi.HOOK_UPDATE | |||
r837 | hooks1_ = self.sa.query(RhodeCodeUi)\ | |||
.filter(RhodeCodeUi.ui_key == hooks1_key).scalar() | ||||
r629 | ||||
r837 | 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 | ||||
r2726 | self.sa.add(hooks1) | |||
r837 | ||||
r1460 | hooks2_key = RhodeCodeUi.HOOK_REPO_SIZE | |||
r837 | 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' | ||||
r2726 | self.sa.add(hooks2) | |||
r837 | ||||
hooks3 = RhodeCodeUi() | ||||
hooks3.ui_section = 'hooks' | ||||
r1460 | hooks3.ui_key = RhodeCodeUi.HOOK_PUSH | |||
r837 | hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action' | |||
r2726 | self.sa.add(hooks3) | |||
r837 | ||||
hooks4 = RhodeCodeUi() | ||||
hooks4.ui_section = 'hooks' | ||||
r2726 | hooks4.ui_key = RhodeCodeUi.HOOK_PRE_PUSH | |||
hooks4.ui_value = 'python:rhodecode.lib.hooks.pre_push' | ||||
self.sa.add(hooks4) | ||||
r837 | ||||
r2726 | hooks5 = RhodeCodeUi() | |||
hooks5.ui_section = 'hooks' | ||||
hooks5.ui_key = RhodeCodeUi.HOOK_PULL | ||||
hooks5.ui_value = 'python:rhodecode.lib.hooks.log_pull_action' | ||||
self.sa.add(hooks5) | ||||
hooks6 = RhodeCodeUi() | ||||
hooks6.ui_section = 'hooks' | ||||
hooks6.ui_key = RhodeCodeUi.HOOK_PRE_PULL | ||||
hooks6.ui_value = 'python:rhodecode.lib.hooks.pre_pull' | ||||
self.sa.add(hooks6) | ||||
r837 | ||||
r1694 | # enable largefiles | |||
r1734 | largefiles = RhodeCodeUi() | |||
largefiles.ui_section = 'extensions' | ||||
largefiles.ui_key = 'largefiles' | ||||
r1783 | largefiles.ui_value = '' | |||
r2726 | self.sa.add(largefiles) | |||
r1694 | ||||
r2705 | # enable hgsubversion disabled by default | |||
hgsubversion = RhodeCodeUi() | ||||
hgsubversion.ui_section = 'extensions' | ||||
hgsubversion.ui_key = 'hgsubversion' | ||||
hgsubversion.ui_value = '' | ||||
hgsubversion.ui_active = False | ||||
r2726 | self.sa.add(hgsubversion) | |||
r2705 | ||||
r2708 | # enable hggit disabled by default | |||
hggit = RhodeCodeUi() | ||||
hggit.ui_section = 'extensions' | ||||
hggit.ui_key = 'hggit' | ||||
hggit.ui_value = '' | ||||
hggit.ui_active = False | ||||
self.sa.add(hggit) | ||||
r837 | ||||
r1734 | def create_ldap_options(self, skip_existing=False): | |||
r837 | """Creates ldap settings""" | |||
r1734 | 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', '')]: | ||||
r837 | ||||
r1734 | if skip_existing and RhodeCodeSetting.get_by_name(k) != None: | |||
log.debug('Skipping option %s' % k) | ||||
continue | ||||
setting = RhodeCodeSetting(k, v) | ||||
self.sa.add(setting) | ||||
r629 | ||||
r3056 | 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')]: | ||||
if skip_existing and RhodeCodeSetting.get_by_name(k) != None: | ||||
log.debug('Skipping option %s' % k) | ||||
continue | ||||
setting = RhodeCodeSetting(k, v) | ||||
self.sa.add(setting) | ||||
r1985 | def fixup_groups(self): | |||
def_usr = User.get_by_username('default') | ||||
for g in RepoGroup.query().all(): | ||||
g.group_name = g.get_new_name(g.name) | ||||
self.sa.add(g) | ||||
# get default perm | ||||
default = UserRepoGroupToPerm.query()\ | ||||
.filter(UserRepoGroupToPerm.group == g)\ | ||||
.filter(UserRepoGroupToPerm.user == def_usr)\ | ||||
.scalar() | ||||
if default is None: | ||||
log.debug('missing default permission for group %s adding' % g) | ||||
ReposGroupModel()._create_default_perms(g) | ||||
r2798 | def reset_permissions(self, username): | |||
""" | ||||
Resets permissions to default state, usefull when old systems had | ||||
bad permissions, we must clean them up | ||||
:param username: | ||||
:type username: | ||||
""" | ||||
default_user = User.get_by_username(username) | ||||
if not default_user: | ||||
return | ||||
u2p = UserToPerm.query()\ | ||||
.filter(UserToPerm.user == default_user).all() | ||||
fixed = False | ||||
if len(u2p) != len(User.DEFAULT_PERMISSIONS): | ||||
for p in u2p: | ||||
Session().delete(p) | ||||
fixed = True | ||||
self.populate_default_permissions() | ||||
return fixed | ||||
r3309 | def update_repo_info(self): | |||
RepoModel.update_repoinfo() | ||||
r2919 | def config_prompt(self, test_repo_path='', retries=3): | |||
defaults = self.cli_args | ||||
r2284 | _path = defaults.get('repos_location') | |||
r1094 | if retries == 3: | |||
log.info('Setting up repositories config') | ||||
r629 | ||||
r2284 | if _path is not None: | |||
path = _path | ||||
elif not self.tests and not test_repo_path: | ||||
r1896 | path = raw_input( | |||
r2112 | 'Enter a valid absolute path to store repositories. ' | |||
r1896 | 'All repositories in that path will be added automatically:' | |||
) | ||||
r547 | else: | |||
path = test_repo_path | ||||
r1094 | path_ok = True | |||
r629 | ||||
r1783 | # check proper dir | |||
r547 | if not os.path.isdir(path): | |||
r1094 | path_ok = False | |||
r1976 | log.error('Given path %s is not a valid directory' % path) | |||
r1094 | ||||
r2112 | elif not os.path.isabs(path): | |||
path_ok = False | ||||
log.error('Given path %s is not an absolute path' % path) | ||||
r1783 | # check write access | |||
r2112 | elif not os.access(path, os.W_OK) and path_ok: | |||
r1094 | path_ok = False | |||
r1976 | log.error('No write permission to given path %s' % path) | |||
r1094 | ||||
if retries == 0: | ||||
r1399 | sys.exit('max retries reached') | |||
Mads Kiilerich
|
r3625 | if not path_ok: | ||
r1094 | retries -= 1 | |||
return self.config_prompt(test_repo_path, retries) | ||||
r2918 | real_path = os.path.normpath(os.path.realpath(path)) | |||
r2819 | ||||
r2918 | if real_path != os.path.normpath(path): | |||
r2819 | if not ask_ok(('Path looks like a symlink, Rhodecode will store ' | |||
'given path as %s ? [y/n]') % (real_path)): | ||||
log.error('Canceled by user') | ||||
sys.exit(-1) | ||||
return real_path | ||||
r1094 | ||||
def create_settings(self, path): | ||||
r629 | ||||
r837 | self.create_ui_settings() | |||
r673 | ||||
r837 | #HG UI OPTIONS | |||
r549 | web1 = RhodeCodeUi() | |||
r547 | web1.ui_section = 'web' | |||
web1.ui_key = 'push_ssl' | ||||
web1.ui_value = 'false' | ||||
r629 | ||||
r549 | web2 = RhodeCodeUi() | |||
r547 | web2.ui_section = 'web' | |||
web2.ui_key = 'allow_archive' | ||||
web2.ui_value = 'gz zip bz2' | ||||
r629 | ||||
r549 | web3 = RhodeCodeUi() | |||
r547 | web3.ui_section = 'web' | |||
web3.ui_key = 'allow_push' | ||||
web3.ui_value = '*' | ||||
r629 | ||||
r549 | web4 = RhodeCodeUi() | |||
r547 | web4.ui_section = 'web' | |||
web4.ui_key = 'baseurl' | ||||
r629 | web4.ui_value = '/' | |||
r549 | paths = RhodeCodeUi() | |||
r547 | paths.ui_section = 'paths' | |||
paths.ui_key = '/' | ||||
r631 | paths.ui_value = path | |||
r629 | ||||
r2726 | phases = RhodeCodeUi() | |||
phases.ui_section = 'phases' | ||||
phases.ui_key = 'publish' | ||||
phases.ui_value = False | ||||
r2662 | sett1 = RhodeCodeSetting('realm', 'RhodeCode authentication') | |||
sett2 = RhodeCodeSetting('title', 'RhodeCode') | ||||
sett3 = RhodeCodeSetting('ga_code', '') | ||||
sett4 = RhodeCodeSetting('show_public_icon', True) | ||||
sett5 = RhodeCodeSetting('show_private_icon', True) | ||||
sett6 = RhodeCodeSetting('stylify_metatags', False) | ||||
r629 | ||||
r1734 | self.sa.add(web1) | |||
self.sa.add(web2) | ||||
self.sa.add(web3) | ||||
self.sa.add(web4) | ||||
self.sa.add(paths) | ||||
r2662 | self.sa.add(sett1) | |||
self.sa.add(sett2) | ||||
self.sa.add(sett3) | ||||
self.sa.add(sett4) | ||||
self.sa.add(sett5) | ||||
self.sa.add(sett6) | ||||
r837 | ||||
self.create_ldap_options() | ||||
r3056 | self.create_default_options() | |||
r837 | ||||
r547 | log.info('created ui config') | |||
r629 | ||||
r547 | def create_user(self, username, password, email='', admin=False): | |||
r1976 | log.info('creating user %s' % username) | |||
r1734 | UserModel().create_or_update(username, password, email, | |||
r2513 | firstname='RhodeCode', lastname='Admin', | |||
r1634 | active=True, admin=admin) | |||
r547 | ||||
def create_default_user(self): | ||||
log.info('creating default user') | ||||
r1634 | # create default user for handling default permissions. | |||
r1734 | UserModel().create_or_update(username='default', | |||
password=str(uuid.uuid1())[:8], | ||||
email='anonymous@rhodecode.org', | ||||
r2513 | firstname='Anonymous', lastname='User') | |||
r1734 | ||||
r547 | def create_permissions(self): | |||
r1783 | # module.(access|create|change|delete)_[name] | |||
r1982 | # module.(none|read|write|admin) | |||
r1266 | ||||
r2532 | for p in Permission.PERMS: | |||
r1987 | if not Permission.get_by_key(p[0]): | |||
r1986 | new_perm = Permission() | |||
new_perm.permission_name = p[0] | ||||
r2532 | new_perm.permission_longname = p[0] | |||
r1986 | self.sa.add(new_perm) | |||
r547 | ||||
def populate_default_permissions(self): | ||||
log.info('creating default user permissions') | ||||
r629 | ||||
r2709 | default_user = User.get_by_username('default') | |||
r629 | ||||
r2798 | for def_perm in User.DEFAULT_PERMISSIONS: | |||
r2709 | ||||
r2765 | perm = self.sa.query(Permission)\ | |||
.filter(Permission.permission_name == def_perm)\ | ||||
.scalar() | ||||
if not perm: | ||||
raise Exception( | ||||
'CRITICAL: permission %s not found inside database !!' | ||||
% def_perm | ||||
) | ||||
if not UserToPerm.query()\ | ||||
.filter(UserToPerm.permission == perm)\ | ||||
.filter(UserToPerm.user == default_user).scalar(): | ||||
reg_perm = UserToPerm() | ||||
reg_perm.user = default_user | ||||
reg_perm.permission = perm | ||||
self.sa.add(reg_perm) | ||||
r2827 | ||||
r3232 | @staticmethod | |||
def check_waitress(): | ||||
r2827 | """ | |||
Function executed at the end of setup | ||||
""" | ||||
if not __py_version__ >= (2, 6): | ||||
notify('Python2.5 detected, please switch ' | ||||
'egg:waitress#main -> egg:Paste#http ' | ||||
r2907 | 'in your .ini file') | |||