Mercurial > kallithea
comparison rhodecode/lib/db_manage.py @ 2031:82a88013a3fd
merge 1.3 into stable
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 26 Feb 2012 17:25:09 +0200 |
parents | a7a282a902b2 34d009e5147a |
children | dc2584ba5fbc |
comparison
equal
deleted
inserted
replaced
2005:ab0e122b38a7 | 2031:82a88013a3fd |
---|---|
6 Database creation, and setup module for RhodeCode. Used for creation | 6 Database creation, and setup module for RhodeCode. Used for creation |
7 of database as well as for migration operations | 7 of database as well as for migration operations |
8 | 8 |
9 :created_on: Apr 10, 2010 | 9 :created_on: Apr 10, 2010 |
10 :author: marcink | 10 :author: marcink |
11 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com> | 11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> |
12 :license: GPLv3, see COPYING for more details. | 12 :license: GPLv3, see COPYING for more details. |
13 """ | 13 """ |
14 # This program is free software: you can redistribute it and/or modify | 14 # This program is free software: you can redistribute it and/or modify |
15 # it under the terms of the GNU General Public License as published by | 15 # it under the terms of the GNU General Public License as published by |
16 # the Free Software Foundation, either version 3 of the License, or | 16 # the Free Software Foundation, either version 3 of the License, or |
31 from os.path import dirname as dn, join as jn | 31 from os.path import dirname as dn, join as jn |
32 | 32 |
33 from rhodecode import __dbversion__ | 33 from rhodecode import __dbversion__ |
34 from rhodecode.model import meta | 34 from rhodecode.model import meta |
35 | 35 |
36 from rhodecode.lib.auth import get_crypt_password, generate_api_key | 36 from rhodecode.model.user import UserModel |
37 from rhodecode.lib.utils import ask_ok | 37 from rhodecode.lib.utils import ask_ok |
38 from rhodecode.model import init_model | 38 from rhodecode.model import init_model |
39 from rhodecode.model.db import User, Permission, RhodeCodeUi, \ | 39 from rhodecode.model.db import User, Permission, RhodeCodeUi, \ |
40 RhodeCodeSettings, UserToPerm, DbMigrateVersion | 40 RhodeCodeSetting, UserToPerm, DbMigrateVersion, RepoGroup,\ |
41 UserRepoGroupToPerm | |
41 | 42 |
42 from sqlalchemy.engine import create_engine | 43 from sqlalchemy.engine import create_engine |
44 from rhodecode.model.repos_group import ReposGroupModel | |
43 | 45 |
44 log = logging.getLogger(__name__) | 46 log = logging.getLogger(__name__) |
45 | 47 |
46 | 48 |
47 class DbManage(object): | 49 class DbManage(object): |
55 self.init_db() | 57 self.init_db() |
56 | 58 |
57 def init_db(self): | 59 def init_db(self): |
58 engine = create_engine(self.dburi, echo=self.log_sql) | 60 engine = create_engine(self.dburi, echo=self.log_sql) |
59 init_model(engine) | 61 init_model(engine) |
60 self.sa = meta.Session() | 62 self.sa = meta.Session |
61 | 63 |
62 def create_tables(self, override=False): | 64 def create_tables(self, override=False): |
63 """Create a auth database | 65 """ |
66 Create a auth database | |
64 """ | 67 """ |
65 | 68 |
66 log.info("Any existing database is going to be destroyed") | 69 log.info("Any existing database is going to be destroyed") |
67 if self.tests: | 70 if self.tests: |
68 destroy = True | 71 destroy = True |
73 if destroy: | 76 if destroy: |
74 meta.Base.metadata.drop_all() | 77 meta.Base.metadata.drop_all() |
75 | 78 |
76 checkfirst = not override | 79 checkfirst = not override |
77 meta.Base.metadata.create_all(checkfirst=checkfirst) | 80 meta.Base.metadata.create_all(checkfirst=checkfirst) |
78 log.info('Created tables for %s', self.dbname) | 81 log.info('Created tables for %s' % self.dbname) |
79 | 82 |
80 def set_db_version(self): | 83 def set_db_version(self): |
81 try: | 84 ver = DbMigrateVersion() |
82 ver = DbMigrateVersion() | 85 ver.version = __dbversion__ |
83 ver.version = __dbversion__ | 86 ver.repository_id = 'rhodecode_db_migrations' |
84 ver.repository_id = 'rhodecode_db_migrations' | 87 ver.repository_path = 'versions' |
85 ver.repository_path = 'versions' | 88 self.sa.add(ver) |
86 self.sa.add(ver) | 89 log.info('db version set to: %s' % __dbversion__) |
87 self.sa.commit() | |
88 except: | |
89 self.sa.rollback() | |
90 raise | |
91 log.info('db version set to: %s', __dbversion__) | |
92 | 90 |
93 def upgrade(self): | 91 def upgrade(self): |
94 """Upgrades given database schema to given revision following | 92 """ |
93 Upgrades given database schema to given revision following | |
95 all needed steps, to perform the upgrade | 94 all needed steps, to perform the upgrade |
96 | 95 |
97 """ | 96 """ |
98 | 97 |
99 from rhodecode.lib.dbmigrate.migrate.versioning import api | 98 from rhodecode.lib.dbmigrate.migrate.versioning import api |
144 | 143 |
145 def __init__(self, klass): | 144 def __init__(self, klass): |
146 self.klass = klass | 145 self.klass = klass |
147 | 146 |
148 def step_0(self): | 147 def step_0(self): |
149 #step 0 is the schema upgrade, and than follow proper upgrades | 148 # step 0 is the schema upgrade, and than follow proper upgrades |
150 print ('attempting to do database upgrade to version %s' \ | 149 print ('attempting to do database upgrade to version %s' \ |
151 % __dbversion__) | 150 % __dbversion__) |
152 api.upgrade(db_uri, repository_path, __dbversion__) | 151 api.upgrade(db_uri, repository_path, __dbversion__) |
153 print ('Schema upgrade completed') | 152 print ('Schema upgrade completed') |
154 | 153 |
168 def step_3(self): | 167 def step_3(self): |
169 print ('Adding additional settings into RhodeCode db') | 168 print ('Adding additional settings into RhodeCode db') |
170 self.klass.fix_settings() | 169 self.klass.fix_settings() |
171 print ('Adding ldap defaults') | 170 print ('Adding ldap defaults') |
172 self.klass.create_ldap_options(skip_existing=True) | 171 self.klass.create_ldap_options(skip_existing=True) |
173 | 172 |
173 def step_4(self): | |
174 print ('create permissions and fix groups') | |
175 self.klass.create_permissions() | |
176 self.klass.fixup_groups() | |
177 | |
178 def step_5(self): | |
179 pass | |
180 | |
174 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1) | 181 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1) |
175 | 182 |
176 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE | 183 # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE |
177 for step in upgrade_steps: | 184 for step in upgrade_steps: |
178 print ('performing upgrade step %s' % step) | 185 print ('performing upgrade step %s' % step) |
179 getattr(UpgradeSteps(self), 'step_%s' % step)() | 186 getattr(UpgradeSteps(self), 'step_%s' % step)() |
187 self.sa.commit() | |
180 | 188 |
181 def fix_repo_paths(self): | 189 def fix_repo_paths(self): |
182 """Fixes a old rhodecode version path into new one without a '*' | 190 """ |
191 Fixes a old rhodecode version path into new one without a '*' | |
183 """ | 192 """ |
184 | 193 |
185 paths = self.sa.query(RhodeCodeUi)\ | 194 paths = self.sa.query(RhodeCodeUi)\ |
186 .filter(RhodeCodeUi.ui_key == '/')\ | 195 .filter(RhodeCodeUi.ui_key == '/')\ |
187 .scalar() | 196 .scalar() |
194 except: | 203 except: |
195 self.sa.rollback() | 204 self.sa.rollback() |
196 raise | 205 raise |
197 | 206 |
198 def fix_default_user(self): | 207 def fix_default_user(self): |
199 """Fixes a old default user with some 'nicer' default values, | 208 """ |
209 Fixes a old default user with some 'nicer' default values, | |
200 used mostly for anonymous access | 210 used mostly for anonymous access |
201 """ | 211 """ |
202 def_user = self.sa.query(User)\ | 212 def_user = self.sa.query(User)\ |
203 .filter(User.username == 'default')\ | 213 .filter(User.username == 'default')\ |
204 .one() | 214 .one() |
213 except: | 223 except: |
214 self.sa.rollback() | 224 self.sa.rollback() |
215 raise | 225 raise |
216 | 226 |
217 def fix_settings(self): | 227 def fix_settings(self): |
218 """Fixes rhodecode settings adds ga_code key for google analytics | 228 """ |
219 """ | 229 Fixes rhodecode settings adds ga_code key for google analytics |
220 | 230 """ |
221 hgsettings3 = RhodeCodeSettings('ga_code', '') | 231 |
232 hgsettings3 = RhodeCodeSetting('ga_code', '') | |
222 | 233 |
223 try: | 234 try: |
224 self.sa.add(hgsettings3) | 235 self.sa.add(hgsettings3) |
225 self.sa.commit() | 236 self.sa.commit() |
226 except: | 237 except: |
256 | 267 |
257 email = raw_input('Specify admin email:') | 268 email = raw_input('Specify admin email:') |
258 self.create_user(username, password, email, True) | 269 self.create_user(username, password, email, True) |
259 else: | 270 else: |
260 log.info('creating admin and regular test users') | 271 log.info('creating admin and regular test users') |
261 self.create_user('test_admin', 'test12', | 272 from rhodecode.tests import TEST_USER_ADMIN_LOGIN,\ |
262 'test_admin@mail.com', True) | 273 TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL,\ |
263 self.create_user('test_regular', 'test12', | 274 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,\ |
264 'test_regular@mail.com', False) | 275 TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \ |
265 self.create_user('test_regular2', 'test12', | 276 TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL |
266 'test_regular2@mail.com', False) | 277 |
278 self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, | |
279 TEST_USER_ADMIN_EMAIL, True) | |
280 | |
281 self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, | |
282 TEST_USER_REGULAR_EMAIL, False) | |
283 | |
284 self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, | |
285 TEST_USER_REGULAR2_EMAIL, False) | |
267 | 286 |
268 def create_ui_settings(self): | 287 def create_ui_settings(self): |
269 """Creates ui settings, fills out hooks | 288 """ |
289 Creates ui settings, fills out hooks | |
270 and disables dotencode | 290 and disables dotencode |
271 | 291 """ |
272 """ | 292 |
273 #HOOKS | 293 #HOOKS |
274 hooks1_key = RhodeCodeUi.HOOK_UPDATE | 294 hooks1_key = RhodeCodeUi.HOOK_UPDATE |
275 hooks1_ = self.sa.query(RhodeCodeUi)\ | 295 hooks1_ = self.sa.query(RhodeCodeUi)\ |
276 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar() | 296 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar() |
277 | 297 |
298 hooks4 = RhodeCodeUi() | 318 hooks4 = RhodeCodeUi() |
299 hooks4.ui_section = 'hooks' | 319 hooks4.ui_section = 'hooks' |
300 hooks4.ui_key = RhodeCodeUi.HOOK_PULL | 320 hooks4.ui_key = RhodeCodeUi.HOOK_PULL |
301 hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action' | 321 hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action' |
302 | 322 |
303 #For mercurial 1.7 set backward comapatibility with format | 323 # For mercurial 1.7 set backward comapatibility with format |
304 dotencode_disable = RhodeCodeUi() | 324 dotencode_disable = RhodeCodeUi() |
305 dotencode_disable.ui_section = 'format' | 325 dotencode_disable.ui_section = 'format' |
306 dotencode_disable.ui_key = 'dotencode' | 326 dotencode_disable.ui_key = 'dotencode' |
307 dotencode_disable.ui_value = 'false' | 327 dotencode_disable.ui_value = 'false' |
308 | 328 |
310 largefiles = RhodeCodeUi() | 330 largefiles = RhodeCodeUi() |
311 largefiles.ui_section = 'extensions' | 331 largefiles.ui_section = 'extensions' |
312 largefiles.ui_key = 'largefiles' | 332 largefiles.ui_key = 'largefiles' |
313 largefiles.ui_value = '' | 333 largefiles.ui_value = '' |
314 | 334 |
315 try: | 335 self.sa.add(hooks1) |
316 self.sa.add(hooks1) | 336 self.sa.add(hooks2) |
317 self.sa.add(hooks2) | 337 self.sa.add(hooks3) |
318 self.sa.add(hooks3) | 338 self.sa.add(hooks4) |
319 self.sa.add(hooks4) | 339 self.sa.add(largefiles) |
320 self.sa.add(dotencode_disable) | 340 |
321 self.sa.add(largefiles) | 341 def create_ldap_options(self, skip_existing=False): |
322 self.sa.commit() | |
323 except: | |
324 self.sa.rollback() | |
325 raise | |
326 | |
327 def create_ldap_options(self,skip_existing=False): | |
328 """Creates ldap settings""" | 342 """Creates ldap settings""" |
329 | 343 |
330 try: | 344 for k, v in [('ldap_active', 'false'), ('ldap_host', ''), |
331 for k, v in [('ldap_active', 'false'), ('ldap_host', ''), | 345 ('ldap_port', '389'), ('ldap_tls_kind', 'PLAIN'), |
332 ('ldap_port', '389'), ('ldap_tls_kind', 'PLAIN'), | 346 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''), |
333 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''), | 347 ('ldap_dn_pass', ''), ('ldap_base_dn', ''), |
334 ('ldap_dn_pass', ''), ('ldap_base_dn', ''), | 348 ('ldap_filter', ''), ('ldap_search_scope', ''), |
335 ('ldap_filter', ''), ('ldap_search_scope', ''), | 349 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''), |
336 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''), | 350 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]: |
337 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]: | 351 |
338 | 352 if skip_existing and RhodeCodeSetting.get_by_name(k) != None: |
339 if skip_existing and RhodeCodeSettings.get_by_name(k) != None: | 353 log.debug('Skipping option %s' % k) |
340 log.debug('Skipping option %s' % k) | 354 continue |
341 continue | 355 setting = RhodeCodeSetting(k, v) |
342 setting = RhodeCodeSettings(k, v) | 356 self.sa.add(setting) |
343 self.sa.add(setting) | 357 |
344 self.sa.commit() | 358 def fixup_groups(self): |
345 except: | 359 def_usr = User.get_by_username('default') |
346 self.sa.rollback() | 360 for g in RepoGroup.query().all(): |
347 raise | 361 g.group_name = g.get_new_name(g.name) |
362 self.sa.add(g) | |
363 # get default perm | |
364 default = UserRepoGroupToPerm.query()\ | |
365 .filter(UserRepoGroupToPerm.group == g)\ | |
366 .filter(UserRepoGroupToPerm.user == def_usr)\ | |
367 .scalar() | |
368 | |
369 if default is None: | |
370 log.debug('missing default permission for group %s adding' % g) | |
371 ReposGroupModel()._create_default_perms(g) | |
348 | 372 |
349 def config_prompt(self, test_repo_path='', retries=3): | 373 def config_prompt(self, test_repo_path='', retries=3): |
350 if retries == 3: | 374 if retries == 3: |
351 log.info('Setting up repositories config') | 375 log.info('Setting up repositories config') |
352 | 376 |
357 ) | 381 ) |
358 else: | 382 else: |
359 path = test_repo_path | 383 path = test_repo_path |
360 path_ok = True | 384 path_ok = True |
361 | 385 |
362 #check proper dir | 386 # check proper dir |
363 if not os.path.isdir(path): | 387 if not os.path.isdir(path): |
364 path_ok = False | 388 path_ok = False |
365 log.error('Given path %s is not a valid directory', path) | 389 log.error('Given path %s is not a valid directory' % path) |
366 | 390 |
367 #check write access | 391 # check write access |
368 if not os.access(path, os.W_OK) and path_ok: | 392 if not os.access(path, os.W_OK) and path_ok: |
369 path_ok = False | 393 path_ok = False |
370 log.error('No write permission to given path %s', path) | 394 log.error('No write permission to given path %s' % path) |
371 | |
372 | 395 |
373 if retries == 0: | 396 if retries == 0: |
374 sys.exit('max retries reached') | 397 sys.exit('max retries reached') |
375 if path_ok is False: | 398 if path_ok is False: |
376 retries -= 1 | 399 retries -= 1 |
406 paths = RhodeCodeUi() | 429 paths = RhodeCodeUi() |
407 paths.ui_section = 'paths' | 430 paths.ui_section = 'paths' |
408 paths.ui_key = '/' | 431 paths.ui_key = '/' |
409 paths.ui_value = path | 432 paths.ui_value = path |
410 | 433 |
411 hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication') | 434 hgsettings1 = RhodeCodeSetting('realm', 'RhodeCode authentication') |
412 hgsettings2 = RhodeCodeSettings('title', 'RhodeCode') | 435 hgsettings2 = RhodeCodeSetting('title', 'RhodeCode') |
413 hgsettings3 = RhodeCodeSettings('ga_code', '') | 436 hgsettings3 = RhodeCodeSetting('ga_code', '') |
414 | 437 |
415 try: | 438 self.sa.add(web1) |
416 self.sa.add(web1) | 439 self.sa.add(web2) |
417 self.sa.add(web2) | 440 self.sa.add(web3) |
418 self.sa.add(web3) | 441 self.sa.add(web4) |
419 self.sa.add(web4) | 442 self.sa.add(paths) |
420 self.sa.add(paths) | 443 self.sa.add(hgsettings1) |
421 self.sa.add(hgsettings1) | 444 self.sa.add(hgsettings2) |
422 self.sa.add(hgsettings2) | 445 self.sa.add(hgsettings3) |
423 self.sa.add(hgsettings3) | |
424 | |
425 self.sa.commit() | |
426 except: | |
427 self.sa.rollback() | |
428 raise | |
429 | 446 |
430 self.create_ldap_options() | 447 self.create_ldap_options() |
431 | 448 |
432 log.info('created ui config') | 449 log.info('created ui config') |
433 | 450 |
434 def create_user(self, username, password, email='', admin=False): | 451 def create_user(self, username, password, email='', admin=False): |
435 log.info('creating administrator user %s', username) | 452 log.info('creating user %s' % username) |
436 | 453 UserModel().create_or_update(username, password, email, |
437 form_data = dict(username=username, | 454 name='RhodeCode', lastname='Admin', |
438 password=password, | 455 active=True, admin=admin) |
439 active=True, | |
440 admin=admin, | |
441 name='RhodeCode', | |
442 lastname='Admin', | |
443 email=email) | |
444 User.create(form_data) | |
445 | |
446 | 456 |
447 def create_default_user(self): | 457 def create_default_user(self): |
448 log.info('creating default user') | 458 log.info('creating default user') |
449 #create default user for handling default permissions. | 459 # create default user for handling default permissions. |
450 | 460 UserModel().create_or_update(username='default', |
451 form_data = dict(username='default', | 461 password=str(uuid.uuid1())[:8], |
452 password=str(uuid.uuid1())[:8], | 462 email='anonymous@rhodecode.org', |
453 active=False, | 463 name='Anonymous', lastname='User') |
454 admin=False, | 464 |
455 name='Anonymous', | |
456 lastname='User', | |
457 email='anonymous@rhodecode.org') | |
458 User.create(form_data) | |
459 | |
460 def create_permissions(self): | 465 def create_permissions(self): |
461 #module.(access|create|change|delete)_[name] | 466 # module.(access|create|change|delete)_[name] |
462 #module.(read|write|owner) | 467 # module.(none|read|write|admin) |
463 perms = [('repository.none', 'Repository no access'), | 468 perms = [ |
464 ('repository.read', 'Repository read access'), | 469 ('repository.none', 'Repository no access'), |
465 ('repository.write', 'Repository write access'), | 470 ('repository.read', 'Repository read access'), |
466 ('repository.admin', 'Repository admin access'), | 471 ('repository.write', 'Repository write access'), |
467 ('hg.admin', 'Hg Administrator'), | 472 ('repository.admin', 'Repository admin access'), |
468 ('hg.create.repository', 'Repository create'), | 473 |
469 ('hg.create.none', 'Repository creation disabled'), | 474 ('group.none', 'Repositories Group no access'), |
470 ('hg.register.none', 'Register disabled'), | 475 ('group.read', 'Repositories Group read access'), |
471 ('hg.register.manual_activate', 'Register new user with ' | 476 ('group.write', 'Repositories Group write access'), |
472 'RhodeCode without manual' | 477 ('group.admin', 'Repositories Group admin access'), |
473 'activation'), | 478 |
474 | 479 ('hg.admin', 'Hg Administrator'), |
475 ('hg.register.auto_activate', 'Register new user with ' | 480 ('hg.create.repository', 'Repository create'), |
476 'RhodeCode without auto ' | 481 ('hg.create.none', 'Repository creation disabled'), |
477 'activation'), | 482 ('hg.register.none', 'Register disabled'), |
478 ] | 483 ('hg.register.manual_activate', 'Register new user with RhodeCode ' |
484 'without manual activation'), | |
485 | |
486 ('hg.register.auto_activate', 'Register new user with RhodeCode ' | |
487 'without auto activation'), | |
488 ] | |
479 | 489 |
480 for p in perms: | 490 for p in perms: |
481 new_perm = Permission() | 491 if not Permission.get_by_key(p[0]): |
482 new_perm.permission_name = p[0] | 492 new_perm = Permission() |
483 new_perm.permission_longname = p[1] | 493 new_perm.permission_name = p[0] |
484 try: | 494 new_perm.permission_longname = p[1] |
485 self.sa.add(new_perm) | 495 self.sa.add(new_perm) |
486 self.sa.commit() | |
487 except: | |
488 self.sa.rollback() | |
489 raise | |
490 | 496 |
491 def populate_default_permissions(self): | 497 def populate_default_permissions(self): |
492 log.info('creating default user permissions') | 498 log.info('creating default user permissions') |
493 | 499 |
494 default_user = self.sa.query(User)\ | 500 default_user = self.sa.query(User)\ |
510 default_repo_perm.user = default_user | 516 default_repo_perm.user = default_user |
511 default_repo_perm.permission = self.sa.query(Permission)\ | 517 default_repo_perm.permission = self.sa.query(Permission)\ |
512 .filter(Permission.permission_name == 'repository.read')\ | 518 .filter(Permission.permission_name == 'repository.read')\ |
513 .scalar() | 519 .scalar() |
514 | 520 |
515 try: | 521 self.sa.add(reg_perm) |
516 self.sa.add(reg_perm) | 522 self.sa.add(create_repo_perm) |
517 self.sa.add(create_repo_perm) | 523 self.sa.add(default_repo_perm) |
518 self.sa.add(default_repo_perm) | |
519 self.sa.commit() | |
520 except: | |
521 self.sa.rollback() | |
522 raise |