##// END OF EJS Templates
db-migration: we run cleanup of cache keys AFTER upgrade....
marcink -
r3847:73b9614c default
parent child Browse files
Show More
@@ -1,642 +1,642 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Database creation, and setup module for RhodeCode Enterprise. Used for creation
22 Database creation, and setup module for RhodeCode Enterprise. Used for creation
23 of database as well as for migration operations
23 of database as well as for migration operations
24 """
24 """
25
25
26 import os
26 import os
27 import sys
27 import sys
28 import time
28 import time
29 import uuid
29 import uuid
30 import logging
30 import logging
31 import getpass
31 import getpass
32 from os.path import dirname as dn, join as jn
32 from os.path import dirname as dn, join as jn
33
33
34 from sqlalchemy.engine import create_engine
34 from sqlalchemy.engine import create_engine
35
35
36 from rhodecode import __dbversion__
36 from rhodecode import __dbversion__
37 from rhodecode.model import init_model
37 from rhodecode.model import init_model
38 from rhodecode.model.user import UserModel
38 from rhodecode.model.user import UserModel
39 from rhodecode.model.db import (
39 from rhodecode.model.db import (
40 User, Permission, RhodeCodeUi, RhodeCodeSetting, UserToPerm,
40 User, Permission, RhodeCodeUi, RhodeCodeSetting, UserToPerm,
41 DbMigrateVersion, RepoGroup, UserRepoGroupToPerm, CacheKey, Repository)
41 DbMigrateVersion, RepoGroup, UserRepoGroupToPerm, CacheKey, Repository)
42 from rhodecode.model.meta import Session, Base
42 from rhodecode.model.meta import Session, Base
43 from rhodecode.model.permission import PermissionModel
43 from rhodecode.model.permission import PermissionModel
44 from rhodecode.model.repo import RepoModel
44 from rhodecode.model.repo import RepoModel
45 from rhodecode.model.repo_group import RepoGroupModel
45 from rhodecode.model.repo_group import RepoGroupModel
46 from rhodecode.model.settings import SettingsModel
46 from rhodecode.model.settings import SettingsModel
47
47
48
48
49 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
50
50
51
51
52 def notify(msg):
52 def notify(msg):
53 """
53 """
54 Notification for migrations messages
54 Notification for migrations messages
55 """
55 """
56 ml = len(msg) + (4 * 2)
56 ml = len(msg) + (4 * 2)
57 print(('\n%s\n*** %s ***\n%s' % ('*' * ml, msg, '*' * ml)).upper())
57 print(('\n%s\n*** %s ***\n%s' % ('*' * ml, msg, '*' * ml)).upper())
58
58
59
59
60 class DbManage(object):
60 class DbManage(object):
61
61
62 def __init__(self, log_sql, dbconf, root, tests=False,
62 def __init__(self, log_sql, dbconf, root, tests=False,
63 SESSION=None, cli_args=None):
63 SESSION=None, cli_args=None):
64 self.dbname = dbconf.split('/')[-1]
64 self.dbname = dbconf.split('/')[-1]
65 self.tests = tests
65 self.tests = tests
66 self.root = root
66 self.root = root
67 self.dburi = dbconf
67 self.dburi = dbconf
68 self.log_sql = log_sql
68 self.log_sql = log_sql
69 self.db_exists = False
69 self.db_exists = False
70 self.cli_args = cli_args or {}
70 self.cli_args = cli_args or {}
71 self.init_db(SESSION=SESSION)
71 self.init_db(SESSION=SESSION)
72 self.ask_ok = self.get_ask_ok_func(self.cli_args.get('force_ask'))
72 self.ask_ok = self.get_ask_ok_func(self.cli_args.get('force_ask'))
73
73
74 def get_ask_ok_func(self, param):
74 def get_ask_ok_func(self, param):
75 if param not in [None]:
75 if param not in [None]:
76 # return a function lambda that has a default set to param
76 # return a function lambda that has a default set to param
77 return lambda *args, **kwargs: param
77 return lambda *args, **kwargs: param
78 else:
78 else:
79 from rhodecode.lib.utils import ask_ok
79 from rhodecode.lib.utils import ask_ok
80 return ask_ok
80 return ask_ok
81
81
82 def init_db(self, SESSION=None):
82 def init_db(self, SESSION=None):
83 if SESSION:
83 if SESSION:
84 self.sa = SESSION
84 self.sa = SESSION
85 else:
85 else:
86 # init new sessions
86 # init new sessions
87 engine = create_engine(self.dburi, echo=self.log_sql)
87 engine = create_engine(self.dburi, echo=self.log_sql)
88 init_model(engine)
88 init_model(engine)
89 self.sa = Session()
89 self.sa = Session()
90
90
91 def create_tables(self, override=False):
91 def create_tables(self, override=False):
92 """
92 """
93 Create a auth database
93 Create a auth database
94 """
94 """
95
95
96 log.info("Existing database with the same name is going to be destroyed.")
96 log.info("Existing database with the same name is going to be destroyed.")
97 log.info("Setup command will run DROP ALL command on that database.")
97 log.info("Setup command will run DROP ALL command on that database.")
98 if self.tests:
98 if self.tests:
99 destroy = True
99 destroy = True
100 else:
100 else:
101 destroy = self.ask_ok('Are you sure that you want to destroy the old database? [y/n]')
101 destroy = self.ask_ok('Are you sure that you want to destroy the old database? [y/n]')
102 if not destroy:
102 if not destroy:
103 log.info('Nothing done.')
103 log.info('Nothing done.')
104 sys.exit(0)
104 sys.exit(0)
105 if destroy:
105 if destroy:
106 Base.metadata.drop_all()
106 Base.metadata.drop_all()
107
107
108 checkfirst = not override
108 checkfirst = not override
109 Base.metadata.create_all(checkfirst=checkfirst)
109 Base.metadata.create_all(checkfirst=checkfirst)
110 log.info('Created tables for %s', self.dbname)
110 log.info('Created tables for %s', self.dbname)
111
111
112 def set_db_version(self):
112 def set_db_version(self):
113 ver = DbMigrateVersion()
113 ver = DbMigrateVersion()
114 ver.version = __dbversion__
114 ver.version = __dbversion__
115 ver.repository_id = 'rhodecode_db_migrations'
115 ver.repository_id = 'rhodecode_db_migrations'
116 ver.repository_path = 'versions'
116 ver.repository_path = 'versions'
117 self.sa.add(ver)
117 self.sa.add(ver)
118 log.info('db version set to: %s', __dbversion__)
118 log.info('db version set to: %s', __dbversion__)
119
119
120 def run_pre_migration_tasks(self):
120 def run_post_migration_tasks(self):
121 """
121 """
122 Run various tasks before actually doing migrations
122 Run various tasks before actually doing migrations
123 """
123 """
124 # delete cache keys on each upgrade
124 # delete cache keys on each upgrade
125 total = CacheKey.query().count()
125 total = CacheKey.query().count()
126 log.info("Deleting (%s) cache keys now...", total)
126 log.info("Deleting (%s) cache keys now...", total)
127 CacheKey.delete_all_cache()
127 CacheKey.delete_all_cache()
128
128
129 def upgrade(self, version=None):
129 def upgrade(self, version=None):
130 """
130 """
131 Upgrades given database schema to given revision following
131 Upgrades given database schema to given revision following
132 all needed steps, to perform the upgrade
132 all needed steps, to perform the upgrade
133
133
134 """
134 """
135
135
136 from rhodecode.lib.dbmigrate.migrate.versioning import api
136 from rhodecode.lib.dbmigrate.migrate.versioning import api
137 from rhodecode.lib.dbmigrate.migrate.exceptions import \
137 from rhodecode.lib.dbmigrate.migrate.exceptions import \
138 DatabaseNotControlledError
138 DatabaseNotControlledError
139
139
140 if 'sqlite' in self.dburi:
140 if 'sqlite' in self.dburi:
141 print(
141 print(
142 '********************** WARNING **********************\n'
142 '********************** WARNING **********************\n'
143 'Make sure your version of sqlite is at least 3.7.X. \n'
143 'Make sure your version of sqlite is at least 3.7.X. \n'
144 'Earlier versions are known to fail on some migrations\n'
144 'Earlier versions are known to fail on some migrations\n'
145 '*****************************************************\n')
145 '*****************************************************\n')
146
146
147 upgrade = self.ask_ok(
147 upgrade = self.ask_ok(
148 'You are about to perform a database upgrade. Make '
148 'You are about to perform a database upgrade. Make '
149 'sure you have backed up your database. '
149 'sure you have backed up your database. '
150 'Continue ? [y/n]')
150 'Continue ? [y/n]')
151 if not upgrade:
151 if not upgrade:
152 log.info('No upgrade performed')
152 log.info('No upgrade performed')
153 sys.exit(0)
153 sys.exit(0)
154
154
155 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
155 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
156 'rhodecode/lib/dbmigrate')
156 'rhodecode/lib/dbmigrate')
157 db_uri = self.dburi
157 db_uri = self.dburi
158
158
159 if version:
159 if version:
160 DbMigrateVersion.set_version(version)
160 DbMigrateVersion.set_version(version)
161
161
162 try:
162 try:
163 curr_version = api.db_version(db_uri, repository_path)
163 curr_version = api.db_version(db_uri, repository_path)
164 msg = ('Found current database db_uri under version '
164 msg = ('Found current database db_uri under version '
165 'control with version {}'.format(curr_version))
165 'control with version {}'.format(curr_version))
166
166
167 except (RuntimeError, DatabaseNotControlledError):
167 except (RuntimeError, DatabaseNotControlledError):
168 curr_version = 1
168 curr_version = 1
169 msg = ('Current database is not under version control. Setting '
169 msg = ('Current database is not under version control. Setting '
170 'as version %s' % curr_version)
170 'as version %s' % curr_version)
171 api.version_control(db_uri, repository_path, curr_version)
171 api.version_control(db_uri, repository_path, curr_version)
172
172
173 notify(msg)
173 notify(msg)
174
174
175 self.run_pre_migration_tasks()
176
175
177 if curr_version == __dbversion__:
176 if curr_version == __dbversion__:
178 log.info('This database is already at the newest version')
177 log.info('This database is already at the newest version')
179 sys.exit(0)
178 sys.exit(0)
180
179
181 upgrade_steps = range(curr_version + 1, __dbversion__ + 1)
180 upgrade_steps = range(curr_version + 1, __dbversion__ + 1)
182 notify('attempting to upgrade database from '
181 notify('attempting to upgrade database from '
183 'version %s to version %s' % (curr_version, __dbversion__))
182 'version %s to version %s' % (curr_version, __dbversion__))
184
183
185 # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
184 # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
186 _step = None
185 _step = None
187 for step in upgrade_steps:
186 for step in upgrade_steps:
188 notify('performing upgrade step %s' % step)
187 notify('performing upgrade step %s' % step)
189 time.sleep(0.5)
188 time.sleep(0.5)
190
189
191 api.upgrade(db_uri, repository_path, step)
190 api.upgrade(db_uri, repository_path, step)
192 self.sa.rollback()
191 self.sa.rollback()
193 notify('schema upgrade for step %s completed' % (step,))
192 notify('schema upgrade for step %s completed' % (step,))
194
193
195 _step = step
194 _step = step
196
195
196 self.run_post_migration_tasks()
197 notify('upgrade to version %s successful' % _step)
197 notify('upgrade to version %s successful' % _step)
198
198
199 def fix_repo_paths(self):
199 def fix_repo_paths(self):
200 """
200 """
201 Fixes an old RhodeCode version path into new one without a '*'
201 Fixes an old RhodeCode version path into new one without a '*'
202 """
202 """
203
203
204 paths = self.sa.query(RhodeCodeUi)\
204 paths = self.sa.query(RhodeCodeUi)\
205 .filter(RhodeCodeUi.ui_key == '/')\
205 .filter(RhodeCodeUi.ui_key == '/')\
206 .scalar()
206 .scalar()
207
207
208 paths.ui_value = paths.ui_value.replace('*', '')
208 paths.ui_value = paths.ui_value.replace('*', '')
209
209
210 try:
210 try:
211 self.sa.add(paths)
211 self.sa.add(paths)
212 self.sa.commit()
212 self.sa.commit()
213 except Exception:
213 except Exception:
214 self.sa.rollback()
214 self.sa.rollback()
215 raise
215 raise
216
216
217 def fix_default_user(self):
217 def fix_default_user(self):
218 """
218 """
219 Fixes an old default user with some 'nicer' default values,
219 Fixes an old default user with some 'nicer' default values,
220 used mostly for anonymous access
220 used mostly for anonymous access
221 """
221 """
222 def_user = self.sa.query(User)\
222 def_user = self.sa.query(User)\
223 .filter(User.username == User.DEFAULT_USER)\
223 .filter(User.username == User.DEFAULT_USER)\
224 .one()
224 .one()
225
225
226 def_user.name = 'Anonymous'
226 def_user.name = 'Anonymous'
227 def_user.lastname = 'User'
227 def_user.lastname = 'User'
228 def_user.email = User.DEFAULT_USER_EMAIL
228 def_user.email = User.DEFAULT_USER_EMAIL
229
229
230 try:
230 try:
231 self.sa.add(def_user)
231 self.sa.add(def_user)
232 self.sa.commit()
232 self.sa.commit()
233 except Exception:
233 except Exception:
234 self.sa.rollback()
234 self.sa.rollback()
235 raise
235 raise
236
236
237 def fix_settings(self):
237 def fix_settings(self):
238 """
238 """
239 Fixes rhodecode settings and adds ga_code key for google analytics
239 Fixes rhodecode settings and adds ga_code key for google analytics
240 """
240 """
241
241
242 hgsettings3 = RhodeCodeSetting('ga_code', '')
242 hgsettings3 = RhodeCodeSetting('ga_code', '')
243
243
244 try:
244 try:
245 self.sa.add(hgsettings3)
245 self.sa.add(hgsettings3)
246 self.sa.commit()
246 self.sa.commit()
247 except Exception:
247 except Exception:
248 self.sa.rollback()
248 self.sa.rollback()
249 raise
249 raise
250
250
251 def create_admin_and_prompt(self):
251 def create_admin_and_prompt(self):
252
252
253 # defaults
253 # defaults
254 defaults = self.cli_args
254 defaults = self.cli_args
255 username = defaults.get('username')
255 username = defaults.get('username')
256 password = defaults.get('password')
256 password = defaults.get('password')
257 email = defaults.get('email')
257 email = defaults.get('email')
258
258
259 if username is None:
259 if username is None:
260 username = raw_input('Specify admin username:')
260 username = raw_input('Specify admin username:')
261 if password is None:
261 if password is None:
262 password = self._get_admin_password()
262 password = self._get_admin_password()
263 if not password:
263 if not password:
264 # second try
264 # second try
265 password = self._get_admin_password()
265 password = self._get_admin_password()
266 if not password:
266 if not password:
267 sys.exit()
267 sys.exit()
268 if email is None:
268 if email is None:
269 email = raw_input('Specify admin email:')
269 email = raw_input('Specify admin email:')
270 api_key = self.cli_args.get('api_key')
270 api_key = self.cli_args.get('api_key')
271 self.create_user(username, password, email, True,
271 self.create_user(username, password, email, True,
272 strict_creation_check=False,
272 strict_creation_check=False,
273 api_key=api_key)
273 api_key=api_key)
274
274
275 def _get_admin_password(self):
275 def _get_admin_password(self):
276 password = getpass.getpass('Specify admin password '
276 password = getpass.getpass('Specify admin password '
277 '(min 6 chars):')
277 '(min 6 chars):')
278 confirm = getpass.getpass('Confirm password:')
278 confirm = getpass.getpass('Confirm password:')
279
279
280 if password != confirm:
280 if password != confirm:
281 log.error('passwords mismatch')
281 log.error('passwords mismatch')
282 return False
282 return False
283 if len(password) < 6:
283 if len(password) < 6:
284 log.error('password is too short - use at least 6 characters')
284 log.error('password is too short - use at least 6 characters')
285 return False
285 return False
286
286
287 return password
287 return password
288
288
289 def create_test_admin_and_users(self):
289 def create_test_admin_and_users(self):
290 log.info('creating admin and regular test users')
290 log.info('creating admin and regular test users')
291 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \
291 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \
292 TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \
292 TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \
293 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \
293 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \
294 TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \
294 TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \
295 TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL
295 TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL
296
296
297 self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,
297 self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,
298 TEST_USER_ADMIN_EMAIL, True, api_key=True)
298 TEST_USER_ADMIN_EMAIL, True, api_key=True)
299
299
300 self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
300 self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
301 TEST_USER_REGULAR_EMAIL, False, api_key=True)
301 TEST_USER_REGULAR_EMAIL, False, api_key=True)
302
302
303 self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS,
303 self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS,
304 TEST_USER_REGULAR2_EMAIL, False, api_key=True)
304 TEST_USER_REGULAR2_EMAIL, False, api_key=True)
305
305
306 def create_ui_settings(self, repo_store_path):
306 def create_ui_settings(self, repo_store_path):
307 """
307 """
308 Creates ui settings, fills out hooks
308 Creates ui settings, fills out hooks
309 and disables dotencode
309 and disables dotencode
310 """
310 """
311 settings_model = SettingsModel(sa=self.sa)
311 settings_model = SettingsModel(sa=self.sa)
312 from rhodecode.lib.vcs.backends.hg import largefiles_store
312 from rhodecode.lib.vcs.backends.hg import largefiles_store
313 from rhodecode.lib.vcs.backends.git import lfs_store
313 from rhodecode.lib.vcs.backends.git import lfs_store
314
314
315 # Build HOOKS
315 # Build HOOKS
316 hooks = [
316 hooks = [
317 (RhodeCodeUi.HOOK_REPO_SIZE, 'python:vcsserver.hooks.repo_size'),
317 (RhodeCodeUi.HOOK_REPO_SIZE, 'python:vcsserver.hooks.repo_size'),
318
318
319 # HG
319 # HG
320 (RhodeCodeUi.HOOK_PRE_PULL, 'python:vcsserver.hooks.pre_pull'),
320 (RhodeCodeUi.HOOK_PRE_PULL, 'python:vcsserver.hooks.pre_pull'),
321 (RhodeCodeUi.HOOK_PULL, 'python:vcsserver.hooks.log_pull_action'),
321 (RhodeCodeUi.HOOK_PULL, 'python:vcsserver.hooks.log_pull_action'),
322 (RhodeCodeUi.HOOK_PRE_PUSH, 'python:vcsserver.hooks.pre_push'),
322 (RhodeCodeUi.HOOK_PRE_PUSH, 'python:vcsserver.hooks.pre_push'),
323 (RhodeCodeUi.HOOK_PRETX_PUSH, 'python:vcsserver.hooks.pre_push'),
323 (RhodeCodeUi.HOOK_PRETX_PUSH, 'python:vcsserver.hooks.pre_push'),
324 (RhodeCodeUi.HOOK_PUSH, 'python:vcsserver.hooks.log_push_action'),
324 (RhodeCodeUi.HOOK_PUSH, 'python:vcsserver.hooks.log_push_action'),
325 (RhodeCodeUi.HOOK_PUSH_KEY, 'python:vcsserver.hooks.key_push'),
325 (RhodeCodeUi.HOOK_PUSH_KEY, 'python:vcsserver.hooks.key_push'),
326
326
327 ]
327 ]
328
328
329 for key, value in hooks:
329 for key, value in hooks:
330 hook_obj = settings_model.get_ui_by_key(key)
330 hook_obj = settings_model.get_ui_by_key(key)
331 hooks2 = hook_obj if hook_obj else RhodeCodeUi()
331 hooks2 = hook_obj if hook_obj else RhodeCodeUi()
332 hooks2.ui_section = 'hooks'
332 hooks2.ui_section = 'hooks'
333 hooks2.ui_key = key
333 hooks2.ui_key = key
334 hooks2.ui_value = value
334 hooks2.ui_value = value
335 self.sa.add(hooks2)
335 self.sa.add(hooks2)
336
336
337 # enable largefiles
337 # enable largefiles
338 largefiles = RhodeCodeUi()
338 largefiles = RhodeCodeUi()
339 largefiles.ui_section = 'extensions'
339 largefiles.ui_section = 'extensions'
340 largefiles.ui_key = 'largefiles'
340 largefiles.ui_key = 'largefiles'
341 largefiles.ui_value = ''
341 largefiles.ui_value = ''
342 self.sa.add(largefiles)
342 self.sa.add(largefiles)
343
343
344 # set default largefiles cache dir, defaults to
344 # set default largefiles cache dir, defaults to
345 # /repo_store_location/.cache/largefiles
345 # /repo_store_location/.cache/largefiles
346 largefiles = RhodeCodeUi()
346 largefiles = RhodeCodeUi()
347 largefiles.ui_section = 'largefiles'
347 largefiles.ui_section = 'largefiles'
348 largefiles.ui_key = 'usercache'
348 largefiles.ui_key = 'usercache'
349 largefiles.ui_value = largefiles_store(repo_store_path)
349 largefiles.ui_value = largefiles_store(repo_store_path)
350
350
351 self.sa.add(largefiles)
351 self.sa.add(largefiles)
352
352
353 # set default lfs cache dir, defaults to
353 # set default lfs cache dir, defaults to
354 # /repo_store_location/.cache/lfs_store
354 # /repo_store_location/.cache/lfs_store
355 lfsstore = RhodeCodeUi()
355 lfsstore = RhodeCodeUi()
356 lfsstore.ui_section = 'vcs_git_lfs'
356 lfsstore.ui_section = 'vcs_git_lfs'
357 lfsstore.ui_key = 'store_location'
357 lfsstore.ui_key = 'store_location'
358 lfsstore.ui_value = lfs_store(repo_store_path)
358 lfsstore.ui_value = lfs_store(repo_store_path)
359
359
360 self.sa.add(lfsstore)
360 self.sa.add(lfsstore)
361
361
362 # enable hgsubversion disabled by default
362 # enable hgsubversion disabled by default
363 hgsubversion = RhodeCodeUi()
363 hgsubversion = RhodeCodeUi()
364 hgsubversion.ui_section = 'extensions'
364 hgsubversion.ui_section = 'extensions'
365 hgsubversion.ui_key = 'hgsubversion'
365 hgsubversion.ui_key = 'hgsubversion'
366 hgsubversion.ui_value = ''
366 hgsubversion.ui_value = ''
367 hgsubversion.ui_active = False
367 hgsubversion.ui_active = False
368 self.sa.add(hgsubversion)
368 self.sa.add(hgsubversion)
369
369
370 # enable hgevolve disabled by default
370 # enable hgevolve disabled by default
371 hgevolve = RhodeCodeUi()
371 hgevolve = RhodeCodeUi()
372 hgevolve.ui_section = 'extensions'
372 hgevolve.ui_section = 'extensions'
373 hgevolve.ui_key = 'evolve'
373 hgevolve.ui_key = 'evolve'
374 hgevolve.ui_value = ''
374 hgevolve.ui_value = ''
375 hgevolve.ui_active = False
375 hgevolve.ui_active = False
376 self.sa.add(hgevolve)
376 self.sa.add(hgevolve)
377
377
378 hgevolve = RhodeCodeUi()
378 hgevolve = RhodeCodeUi()
379 hgevolve.ui_section = 'experimental'
379 hgevolve.ui_section = 'experimental'
380 hgevolve.ui_key = 'evolution'
380 hgevolve.ui_key = 'evolution'
381 hgevolve.ui_value = ''
381 hgevolve.ui_value = ''
382 hgevolve.ui_active = False
382 hgevolve.ui_active = False
383 self.sa.add(hgevolve)
383 self.sa.add(hgevolve)
384
384
385 hgevolve = RhodeCodeUi()
385 hgevolve = RhodeCodeUi()
386 hgevolve.ui_section = 'experimental'
386 hgevolve.ui_section = 'experimental'
387 hgevolve.ui_key = 'evolution.exchange'
387 hgevolve.ui_key = 'evolution.exchange'
388 hgevolve.ui_value = ''
388 hgevolve.ui_value = ''
389 hgevolve.ui_active = False
389 hgevolve.ui_active = False
390 self.sa.add(hgevolve)
390 self.sa.add(hgevolve)
391
391
392 hgevolve = RhodeCodeUi()
392 hgevolve = RhodeCodeUi()
393 hgevolve.ui_section = 'extensions'
393 hgevolve.ui_section = 'extensions'
394 hgevolve.ui_key = 'topic'
394 hgevolve.ui_key = 'topic'
395 hgevolve.ui_value = ''
395 hgevolve.ui_value = ''
396 hgevolve.ui_active = False
396 hgevolve.ui_active = False
397 self.sa.add(hgevolve)
397 self.sa.add(hgevolve)
398
398
399 # enable hggit disabled by default
399 # enable hggit disabled by default
400 hggit = RhodeCodeUi()
400 hggit = RhodeCodeUi()
401 hggit.ui_section = 'extensions'
401 hggit.ui_section = 'extensions'
402 hggit.ui_key = 'hggit'
402 hggit.ui_key = 'hggit'
403 hggit.ui_value = ''
403 hggit.ui_value = ''
404 hggit.ui_active = False
404 hggit.ui_active = False
405 self.sa.add(hggit)
405 self.sa.add(hggit)
406
406
407 # set svn branch defaults
407 # set svn branch defaults
408 branches = ["/branches/*", "/trunk"]
408 branches = ["/branches/*", "/trunk"]
409 tags = ["/tags/*"]
409 tags = ["/tags/*"]
410
410
411 for branch in branches:
411 for branch in branches:
412 settings_model.create_ui_section_value(
412 settings_model.create_ui_section_value(
413 RhodeCodeUi.SVN_BRANCH_ID, branch)
413 RhodeCodeUi.SVN_BRANCH_ID, branch)
414
414
415 for tag in tags:
415 for tag in tags:
416 settings_model.create_ui_section_value(RhodeCodeUi.SVN_TAG_ID, tag)
416 settings_model.create_ui_section_value(RhodeCodeUi.SVN_TAG_ID, tag)
417
417
418 def create_auth_plugin_options(self, skip_existing=False):
418 def create_auth_plugin_options(self, skip_existing=False):
419 """
419 """
420 Create default auth plugin settings, and make it active
420 Create default auth plugin settings, and make it active
421
421
422 :param skip_existing:
422 :param skip_existing:
423 """
423 """
424
424
425 for k, v, t in [('auth_plugins', 'egg:rhodecode-enterprise-ce#rhodecode', 'list'),
425 for k, v, t in [('auth_plugins', 'egg:rhodecode-enterprise-ce#rhodecode', 'list'),
426 ('auth_rhodecode_enabled', 'True', 'bool')]:
426 ('auth_rhodecode_enabled', 'True', 'bool')]:
427 if (skip_existing and
427 if (skip_existing and
428 SettingsModel().get_setting_by_name(k) is not None):
428 SettingsModel().get_setting_by_name(k) is not None):
429 log.debug('Skipping option %s', k)
429 log.debug('Skipping option %s', k)
430 continue
430 continue
431 setting = RhodeCodeSetting(k, v, t)
431 setting = RhodeCodeSetting(k, v, t)
432 self.sa.add(setting)
432 self.sa.add(setting)
433
433
434 def create_default_options(self, skip_existing=False):
434 def create_default_options(self, skip_existing=False):
435 """Creates default settings"""
435 """Creates default settings"""
436
436
437 for k, v, t in [
437 for k, v, t in [
438 ('default_repo_enable_locking', False, 'bool'),
438 ('default_repo_enable_locking', False, 'bool'),
439 ('default_repo_enable_downloads', False, 'bool'),
439 ('default_repo_enable_downloads', False, 'bool'),
440 ('default_repo_enable_statistics', False, 'bool'),
440 ('default_repo_enable_statistics', False, 'bool'),
441 ('default_repo_private', False, 'bool'),
441 ('default_repo_private', False, 'bool'),
442 ('default_repo_type', 'hg', 'unicode')]:
442 ('default_repo_type', 'hg', 'unicode')]:
443
443
444 if (skip_existing and
444 if (skip_existing and
445 SettingsModel().get_setting_by_name(k) is not None):
445 SettingsModel().get_setting_by_name(k) is not None):
446 log.debug('Skipping option %s', k)
446 log.debug('Skipping option %s', k)
447 continue
447 continue
448 setting = RhodeCodeSetting(k, v, t)
448 setting = RhodeCodeSetting(k, v, t)
449 self.sa.add(setting)
449 self.sa.add(setting)
450
450
451 def fixup_groups(self):
451 def fixup_groups(self):
452 def_usr = User.get_default_user()
452 def_usr = User.get_default_user()
453 for g in RepoGroup.query().all():
453 for g in RepoGroup.query().all():
454 g.group_name = g.get_new_name(g.name)
454 g.group_name = g.get_new_name(g.name)
455 self.sa.add(g)
455 self.sa.add(g)
456 # get default perm
456 # get default perm
457 default = UserRepoGroupToPerm.query()\
457 default = UserRepoGroupToPerm.query()\
458 .filter(UserRepoGroupToPerm.group == g)\
458 .filter(UserRepoGroupToPerm.group == g)\
459 .filter(UserRepoGroupToPerm.user == def_usr)\
459 .filter(UserRepoGroupToPerm.user == def_usr)\
460 .scalar()
460 .scalar()
461
461
462 if default is None:
462 if default is None:
463 log.debug('missing default permission for group %s adding', g)
463 log.debug('missing default permission for group %s adding', g)
464 perm_obj = RepoGroupModel()._create_default_perms(g)
464 perm_obj = RepoGroupModel()._create_default_perms(g)
465 self.sa.add(perm_obj)
465 self.sa.add(perm_obj)
466
466
467 def reset_permissions(self, username):
467 def reset_permissions(self, username):
468 """
468 """
469 Resets permissions to default state, useful when old systems had
469 Resets permissions to default state, useful when old systems had
470 bad permissions, we must clean them up
470 bad permissions, we must clean them up
471
471
472 :param username:
472 :param username:
473 """
473 """
474 default_user = User.get_by_username(username)
474 default_user = User.get_by_username(username)
475 if not default_user:
475 if not default_user:
476 return
476 return
477
477
478 u2p = UserToPerm.query()\
478 u2p = UserToPerm.query()\
479 .filter(UserToPerm.user == default_user).all()
479 .filter(UserToPerm.user == default_user).all()
480 fixed = False
480 fixed = False
481 if len(u2p) != len(Permission.DEFAULT_USER_PERMISSIONS):
481 if len(u2p) != len(Permission.DEFAULT_USER_PERMISSIONS):
482 for p in u2p:
482 for p in u2p:
483 Session().delete(p)
483 Session().delete(p)
484 fixed = True
484 fixed = True
485 self.populate_default_permissions()
485 self.populate_default_permissions()
486 return fixed
486 return fixed
487
487
488 def config_prompt(self, test_repo_path='', retries=3):
488 def config_prompt(self, test_repo_path='', retries=3):
489 defaults = self.cli_args
489 defaults = self.cli_args
490 _path = defaults.get('repos_location')
490 _path = defaults.get('repos_location')
491 if retries == 3:
491 if retries == 3:
492 log.info('Setting up repositories config')
492 log.info('Setting up repositories config')
493
493
494 if _path is not None:
494 if _path is not None:
495 path = _path
495 path = _path
496 elif not self.tests and not test_repo_path:
496 elif not self.tests and not test_repo_path:
497 path = raw_input(
497 path = raw_input(
498 'Enter a valid absolute path to store repositories. '
498 'Enter a valid absolute path to store repositories. '
499 'All repositories in that path will be added automatically:'
499 'All repositories in that path will be added automatically:'
500 )
500 )
501 else:
501 else:
502 path = test_repo_path
502 path = test_repo_path
503 path_ok = True
503 path_ok = True
504
504
505 # check proper dir
505 # check proper dir
506 if not os.path.isdir(path):
506 if not os.path.isdir(path):
507 path_ok = False
507 path_ok = False
508 log.error('Given path %s is not a valid directory', path)
508 log.error('Given path %s is not a valid directory', path)
509
509
510 elif not os.path.isabs(path):
510 elif not os.path.isabs(path):
511 path_ok = False
511 path_ok = False
512 log.error('Given path %s is not an absolute path', path)
512 log.error('Given path %s is not an absolute path', path)
513
513
514 # check if path is at least readable.
514 # check if path is at least readable.
515 if not os.access(path, os.R_OK):
515 if not os.access(path, os.R_OK):
516 path_ok = False
516 path_ok = False
517 log.error('Given path %s is not readable', path)
517 log.error('Given path %s is not readable', path)
518
518
519 # check write access, warn user about non writeable paths
519 # check write access, warn user about non writeable paths
520 elif not os.access(path, os.W_OK) and path_ok:
520 elif not os.access(path, os.W_OK) and path_ok:
521 log.warning('No write permission to given path %s', path)
521 log.warning('No write permission to given path %s', path)
522
522
523 q = ('Given path %s is not writeable, do you want to '
523 q = ('Given path %s is not writeable, do you want to '
524 'continue with read only mode ? [y/n]' % (path,))
524 'continue with read only mode ? [y/n]' % (path,))
525 if not self.ask_ok(q):
525 if not self.ask_ok(q):
526 log.error('Canceled by user')
526 log.error('Canceled by user')
527 sys.exit(-1)
527 sys.exit(-1)
528
528
529 if retries == 0:
529 if retries == 0:
530 sys.exit('max retries reached')
530 sys.exit('max retries reached')
531 if not path_ok:
531 if not path_ok:
532 retries -= 1
532 retries -= 1
533 return self.config_prompt(test_repo_path, retries)
533 return self.config_prompt(test_repo_path, retries)
534
534
535 real_path = os.path.normpath(os.path.realpath(path))
535 real_path = os.path.normpath(os.path.realpath(path))
536
536
537 if real_path != os.path.normpath(path):
537 if real_path != os.path.normpath(path):
538 q = ('Path looks like a symlink, RhodeCode Enterprise will store '
538 q = ('Path looks like a symlink, RhodeCode Enterprise will store '
539 'given path as %s ? [y/n]') % (real_path,)
539 'given path as %s ? [y/n]') % (real_path,)
540 if not self.ask_ok(q):
540 if not self.ask_ok(q):
541 log.error('Canceled by user')
541 log.error('Canceled by user')
542 sys.exit(-1)
542 sys.exit(-1)
543
543
544 return real_path
544 return real_path
545
545
546 def create_settings(self, path):
546 def create_settings(self, path):
547
547
548 self.create_ui_settings(path)
548 self.create_ui_settings(path)
549
549
550 ui_config = [
550 ui_config = [
551 ('web', 'push_ssl', 'False'),
551 ('web', 'push_ssl', 'False'),
552 ('web', 'allow_archive', 'gz zip bz2'),
552 ('web', 'allow_archive', 'gz zip bz2'),
553 ('web', 'allow_push', '*'),
553 ('web', 'allow_push', '*'),
554 ('web', 'baseurl', '/'),
554 ('web', 'baseurl', '/'),
555 ('paths', '/', path),
555 ('paths', '/', path),
556 ('phases', 'publish', 'True')
556 ('phases', 'publish', 'True')
557 ]
557 ]
558 for section, key, value in ui_config:
558 for section, key, value in ui_config:
559 ui_conf = RhodeCodeUi()
559 ui_conf = RhodeCodeUi()
560 setattr(ui_conf, 'ui_section', section)
560 setattr(ui_conf, 'ui_section', section)
561 setattr(ui_conf, 'ui_key', key)
561 setattr(ui_conf, 'ui_key', key)
562 setattr(ui_conf, 'ui_value', value)
562 setattr(ui_conf, 'ui_value', value)
563 self.sa.add(ui_conf)
563 self.sa.add(ui_conf)
564
564
565 # rhodecode app settings
565 # rhodecode app settings
566 settings = [
566 settings = [
567 ('realm', 'RhodeCode', 'unicode'),
567 ('realm', 'RhodeCode', 'unicode'),
568 ('title', '', 'unicode'),
568 ('title', '', 'unicode'),
569 ('pre_code', '', 'unicode'),
569 ('pre_code', '', 'unicode'),
570 ('post_code', '', 'unicode'),
570 ('post_code', '', 'unicode'),
571 ('show_public_icon', True, 'bool'),
571 ('show_public_icon', True, 'bool'),
572 ('show_private_icon', True, 'bool'),
572 ('show_private_icon', True, 'bool'),
573 ('stylify_metatags', False, 'bool'),
573 ('stylify_metatags', False, 'bool'),
574 ('dashboard_items', 100, 'int'),
574 ('dashboard_items', 100, 'int'),
575 ('admin_grid_items', 25, 'int'),
575 ('admin_grid_items', 25, 'int'),
576 ('show_version', True, 'bool'),
576 ('show_version', True, 'bool'),
577 ('use_gravatar', False, 'bool'),
577 ('use_gravatar', False, 'bool'),
578 ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'),
578 ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'),
579 ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'),
579 ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'),
580 ('support_url', '', 'unicode'),
580 ('support_url', '', 'unicode'),
581 ('update_url', RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode'),
581 ('update_url', RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode'),
582 ('show_revision_number', True, 'bool'),
582 ('show_revision_number', True, 'bool'),
583 ('show_sha_length', 12, 'int'),
583 ('show_sha_length', 12, 'int'),
584 ]
584 ]
585
585
586 for key, val, type_ in settings:
586 for key, val, type_ in settings:
587 sett = RhodeCodeSetting(key, val, type_)
587 sett = RhodeCodeSetting(key, val, type_)
588 self.sa.add(sett)
588 self.sa.add(sett)
589
589
590 self.create_auth_plugin_options()
590 self.create_auth_plugin_options()
591 self.create_default_options()
591 self.create_default_options()
592
592
593 log.info('created ui config')
593 log.info('created ui config')
594
594
595 def create_user(self, username, password, email='', admin=False,
595 def create_user(self, username, password, email='', admin=False,
596 strict_creation_check=True, api_key=None):
596 strict_creation_check=True, api_key=None):
597 log.info('creating user `%s`', username)
597 log.info('creating user `%s`', username)
598 user = UserModel().create_or_update(
598 user = UserModel().create_or_update(
599 username, password, email, firstname=u'RhodeCode', lastname=u'Admin',
599 username, password, email, firstname=u'RhodeCode', lastname=u'Admin',
600 active=True, admin=admin, extern_type="rhodecode",
600 active=True, admin=admin, extern_type="rhodecode",
601 strict_creation_check=strict_creation_check)
601 strict_creation_check=strict_creation_check)
602
602
603 if api_key:
603 if api_key:
604 log.info('setting a new default auth token for user `%s`', username)
604 log.info('setting a new default auth token for user `%s`', username)
605 UserModel().add_auth_token(
605 UserModel().add_auth_token(
606 user=user, lifetime_minutes=-1,
606 user=user, lifetime_minutes=-1,
607 role=UserModel.auth_token_role.ROLE_ALL,
607 role=UserModel.auth_token_role.ROLE_ALL,
608 description=u'BUILTIN TOKEN')
608 description=u'BUILTIN TOKEN')
609
609
610 def create_default_user(self):
610 def create_default_user(self):
611 log.info('creating default user')
611 log.info('creating default user')
612 # create default user for handling default permissions.
612 # create default user for handling default permissions.
613 user = UserModel().create_or_update(username=User.DEFAULT_USER,
613 user = UserModel().create_or_update(username=User.DEFAULT_USER,
614 password=str(uuid.uuid1())[:20],
614 password=str(uuid.uuid1())[:20],
615 email=User.DEFAULT_USER_EMAIL,
615 email=User.DEFAULT_USER_EMAIL,
616 firstname=u'Anonymous',
616 firstname=u'Anonymous',
617 lastname=u'User',
617 lastname=u'User',
618 strict_creation_check=False)
618 strict_creation_check=False)
619 # based on configuration options activate/de-activate this user which
619 # based on configuration options activate/de-activate this user which
620 # controlls anonymous access
620 # controlls anonymous access
621 if self.cli_args.get('public_access') is False:
621 if self.cli_args.get('public_access') is False:
622 log.info('Public access disabled')
622 log.info('Public access disabled')
623 user.active = False
623 user.active = False
624 Session().add(user)
624 Session().add(user)
625 Session().commit()
625 Session().commit()
626
626
627 def create_permissions(self):
627 def create_permissions(self):
628 """
628 """
629 Creates all permissions defined in the system
629 Creates all permissions defined in the system
630 """
630 """
631 # module.(access|create|change|delete)_[name]
631 # module.(access|create|change|delete)_[name]
632 # module.(none|read|write|admin)
632 # module.(none|read|write|admin)
633 log.info('creating permissions')
633 log.info('creating permissions')
634 PermissionModel(self.sa).create_permissions()
634 PermissionModel(self.sa).create_permissions()
635
635
636 def populate_default_permissions(self):
636 def populate_default_permissions(self):
637 """
637 """
638 Populate default permissions. It will create only the default
638 Populate default permissions. It will create only the default
639 permissions that are missing, and not alter already defined ones
639 permissions that are missing, and not alter already defined ones
640 """
640 """
641 log.info('creating default user permissions')
641 log.info('creating default user permissions')
642 PermissionModel(self.sa).create_default_user_permissions(user=User.DEFAULT_USER)
642 PermissionModel(self.sa).create_default_user_permissions(user=User.DEFAULT_USER)
General Comments 0
You need to be logged in to leave comments. Login now