##// END OF EJS Templates
fixed path issues in upgrade script
marcink -
r843:3b21ba5f beta
parent child Browse files
Show More
@@ -1,476 +1,477 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.lib.db_manage
4 4 ~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Database creation, and setup module for RhodeCode. Used for creation
7 7 of database as well as for migration operations
8 8
9 9 :created_on: Apr 10, 2010
10 10 :author: marcink
11 11 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
12 12 :license: GPLv3, see COPYING for more details.
13 13 """
14 14 # This program is free software; you can redistribute it and/or
15 15 # modify it under the terms of the GNU General Public License
16 16 # as published by the Free Software Foundation; version 2
17 17 # of the License or (at your opinion) any later version of the license.
18 18 #
19 19 # This program is distributed in the hope that it will be useful,
20 20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 22 # GNU General Public License for more details.
23 23 #
24 24 # You should have received a copy of the GNU General Public License
25 25 # along with this program; if not, write to the Free Software
26 26 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 27 # MA 02110-1301, USA.
28 28
29 29 import os
30 30 import sys
31 31 import uuid
32 32 import logging
33 33 from os.path import dirname as dn, join as jn
34 34
35 35 from rhodecode import __dbversion__
36 36 from rhodecode.model import meta
37 37
38 38 from rhodecode.lib.auth import get_crypt_password
39 39 from rhodecode.lib.utils import ask_ok
40 40 from rhodecode.model import init_model
41 41 from rhodecode.model.db import User, Permission, RhodeCodeUi, RhodeCodeSettings, \
42 42 UserToPerm, DbMigrateVersion
43 43
44 44 from sqlalchemy.engine import create_engine
45 45
46 46 log = logging.getLogger(__name__)
47 47
48 48 class DbManage(object):
49 49 def __init__(self, log_sql, dbconf, root, tests=False):
50 50 self.dbname = dbconf.split('/')[-1]
51 51 self.tests = tests
52 52 self.root = root
53 53 self.dburi = dbconf
54 54 engine = create_engine(self.dburi, echo=log_sql)
55 55 init_model(engine)
56 56 self.sa = meta.Session()
57 57 self.db_exists = False
58 58
59 59 def check_for_db(self, override):
60 60 db_path = jn(self.root, self.dbname)
61 61 if self.dburi.startswith('sqlite'):
62 62 log.info('checking for existing db in %s', db_path)
63 63 if os.path.isfile(db_path):
64 64
65 65 self.db_exists = True
66 66 if not override:
67 67 raise Exception('database already exists')
68 68
69 69 def create_tables(self, override=False):
70 70 """Create a auth database
71 71 """
72 72
73 73 self.check_for_db(override)
74 74 if self.db_exists:
75 75 log.info("database exist and it's going to be destroyed")
76 76 if self.tests:
77 77 destroy = True
78 78 else:
79 79 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
80 80 if not destroy:
81 81 sys.exit()
82 82 if self.db_exists and destroy:
83 83 os.remove(jn(self.root, self.dbname))
84 84 checkfirst = not override
85 85 meta.Base.metadata.create_all(checkfirst=checkfirst)
86 86 log.info('Created tables for %s', self.dbname)
87 87
88 88
89 89
90 90 def set_db_version(self):
91 91 try:
92 92 ver = DbMigrateVersion()
93 93 ver.version = __dbversion__
94 94 ver.repository_id = 'rhodecode_db_migrations'
95 95 ver.repository_path = 'versions'
96 96 self.sa.add(ver)
97 97 self.sa.commit()
98 98 except:
99 99 self.sa.rollback()
100 100 raise
101 101 log.info('db version set to: %s', __dbversion__)
102 102
103 103
104 104 def upgrade(self):
105 105 """Upgrades given database schema to given revision following
106 106 all needed steps,
107 107
108 108 :param revision: revision to upgrade to
109 109 """
110 110
111 111 from rhodecode.lib.dbmigrate.migrate.versioning import api
112 112 from rhodecode.lib.dbmigrate.migrate.exceptions import \
113 113 DatabaseNotControlledError
114 114
115 115 upgrade = ask_ok('You are about to perform database upgrade, make '
116 116 'sure You backed up your database before. '
117 117 'Continue ? [y/n]')
118 118 if not upgrade:
119 119 sys.exit('Nothing done')
120 120
121 repository_path = 'rhodecode/lib/dbmigrate'
121 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
122 'rhodecode/lib/dbmigrate')
122 123 db_uri = self.dburi
123 124
124 125 try:
125 126 curr_version = api.db_version(db_uri, repository_path)
126 127 msg = ('Found current database under version'
127 128 ' control with version %s' % curr_version)
128 129
129 130 except (RuntimeError, DatabaseNotControlledError), e:
130 131 curr_version = 1
131 132 msg = ('Current database is not under version control. Setting'
132 133 ' as version %s' % curr_version)
133 134 api.version_control(db_uri, repository_path, curr_version)
134 135
135 136 print (msg)
136 137
137 138 if curr_version == __dbversion__:
138 139 sys.exit('This database is already at the newest version')
139 140
140 141 #======================================================================
141 142 # UPGRADE STEPS
142 143 #======================================================================
143 144 class UpgradeSteps(object):
144 145
145 146 def __init__(self, klass):
146 147 self.klass = klass
147 148
148 149 def step_0(self):
149 150 #step 0 is the schema upgrade, and than follow proper upgrades
150 151 print ('attempting to do database upgrade to version %s' \
151 152 % __dbversion__)
152 153 api.upgrade(db_uri, repository_path, __dbversion__)
153 154 print ('Schema upgrade completed')
154 155
155 156 def step_1(self):
156 157 pass
157 158
158 159 def step_2(self):
159 160 print ('Patching repo paths for newer version of RhodeCode')
160 161 self.klass.fix_repo_paths()
161 162
162 163 print ('Patching default user of RhodeCode')
163 164 self.klass.fix_default_user()
164 165
165 166 log.info('Changing ui settings')
166 167 self.klass.create_ui_settings()
167 168
168 169
169 170 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
170 171
171 172 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
172 173 for step in upgrade_steps:
173 174 print ('performing upgrade step %s' % step)
174 175 callable = getattr(UpgradeSteps(self), 'step_%s' % step)()
175 176
176 177
177 178
178 179 def fix_repo_paths(self):
179 180 """Fixes a old rhodecode version path into new one without a '*'
180 181 """
181 182
182 183 paths = self.sa.query(RhodeCodeUi)\
183 184 .filter(RhodeCodeUi.ui_key == '/')\
184 185 .scalar()
185 186
186 187 paths.ui_value = paths.ui_value.replace('*', '')
187 188
188 189 try:
189 190 self.sa.add(paths)
190 191 self.sa.commit()
191 192 except:
192 193 self.sa.rollback()
193 194 raise
194 195
195 196 def fix_default_user(self):
196 197 """Fixes a old default user with some 'nicer' default values,
197 198 used mostly for anonymous access
198 199 """
199 200 def_user = self.sa.query(User)\
200 201 .filter(User.username == 'default')\
201 202 .one()
202 203
203 204 def_user.name = 'Anonymous'
204 205 def_user.lastname = 'User'
205 206 def_user.email = 'anonymous@rhodecode.org'
206 207
207 208 try:
208 209 self.sa.add(def_user)
209 210 self.sa.commit()
210 211 except:
211 212 self.sa.rollback()
212 213 raise
213 214
214 215
215 216
216 217 def admin_prompt(self, second=False):
217 218 if not self.tests:
218 219 import getpass
219 220
220 221
221 222 def get_password():
222 223 password = getpass.getpass('Specify admin password (min 6 chars):')
223 224 confirm = getpass.getpass('Confirm password:')
224 225
225 226 if password != confirm:
226 227 log.error('passwords mismatch')
227 228 return False
228 229 if len(password) < 6:
229 230 log.error('password is to short use at least 6 characters')
230 231 return False
231 232
232 233 return password
233 234
234 235 username = raw_input('Specify admin username:')
235 236
236 237 password = get_password()
237 238 if not password:
238 239 #second try
239 240 password = get_password()
240 241 if not password:
241 242 sys.exit()
242 243
243 244 email = raw_input('Specify admin email:')
244 245 self.create_user(username, password, email, True)
245 246 else:
246 247 log.info('creating admin and regular test users')
247 248 self.create_user('test_admin', 'test12', 'test_admin@mail.com', True)
248 249 self.create_user('test_regular', 'test12', 'test_regular@mail.com', False)
249 250 self.create_user('test_regular2', 'test12', 'test_regular2@mail.com', False)
250 251
251 252 def create_ui_settings(self):
252 253 """Creates ui settings, fills out hooks
253 254 and disables dotencode
254 255
255 256 """
256 257 #HOOKS
257 258 hooks1_key = 'changegroup.update'
258 259 hooks1_ = self.sa.query(RhodeCodeUi)\
259 260 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
260 261
261 262 hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
262 263 hooks1.ui_section = 'hooks'
263 264 hooks1.ui_key = hooks1_key
264 265 hooks1.ui_value = 'hg update >&2'
265 266 hooks1.ui_active = False
266 267
267 268 hooks2_key = 'changegroup.repo_size'
268 269 hooks2_ = self.sa.query(RhodeCodeUi)\
269 270 .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
270 271
271 272 hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
272 273 hooks2.ui_section = 'hooks'
273 274 hooks2.ui_key = hooks2_key
274 275 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
275 276
276 277 hooks3 = RhodeCodeUi()
277 278 hooks3.ui_section = 'hooks'
278 279 hooks3.ui_key = 'pretxnchangegroup.push_logger'
279 280 hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
280 281
281 282 hooks4 = RhodeCodeUi()
282 283 hooks4.ui_section = 'hooks'
283 284 hooks4.ui_key = 'preoutgoing.pull_logger'
284 285 hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
285 286
286 287 #For mercurial 1.7 set backward comapatibility with format
287 288 dotencode_disable = RhodeCodeUi()
288 289 dotencode_disable.ui_section = 'format'
289 290 dotencode_disable.ui_key = 'dotencode'
290 291 dotencode_disable.ui_value = 'false'
291 292
292 293 try:
293 294 self.sa.add(hooks1)
294 295 self.sa.add(hooks2)
295 296 self.sa.add(hooks3)
296 297 self.sa.add(hooks4)
297 298 self.sa.add(dotencode_disable)
298 299 self.sa.commit()
299 300 except:
300 301 self.sa.rollback()
301 302 raise
302 303
303 304
304 305 def create_ldap_options(self):
305 306 """Creates ldap settings"""
306 307
307 308 try:
308 309 for k in ['ldap_active', 'ldap_host', 'ldap_port', 'ldap_ldaps',
309 310 'ldap_dn_user', 'ldap_dn_pass', 'ldap_base_dn']:
310 311
311 312 setting = RhodeCodeSettings(k, '')
312 313 self.sa.add(setting)
313 314 self.sa.commit()
314 315 except:
315 316 self.sa.rollback()
316 317 raise
317 318
318 319 def config_prompt(self, test_repo_path=''):
319 320 log.info('Setting up repositories config')
320 321
321 322 if not self.tests and not test_repo_path:
322 323 path = raw_input('Specify valid full path to your repositories'
323 324 ' you can change this later in application settings:')
324 325 else:
325 326 path = test_repo_path
326 327
327 328 if not os.path.isdir(path):
328 329 log.error('You entered wrong path: %s', path)
329 330 sys.exit()
330 331
331 332 self.create_ui_settings()
332 333
333 334 #HG UI OPTIONS
334 335 web1 = RhodeCodeUi()
335 336 web1.ui_section = 'web'
336 337 web1.ui_key = 'push_ssl'
337 338 web1.ui_value = 'false'
338 339
339 340 web2 = RhodeCodeUi()
340 341 web2.ui_section = 'web'
341 342 web2.ui_key = 'allow_archive'
342 343 web2.ui_value = 'gz zip bz2'
343 344
344 345 web3 = RhodeCodeUi()
345 346 web3.ui_section = 'web'
346 347 web3.ui_key = 'allow_push'
347 348 web3.ui_value = '*'
348 349
349 350 web4 = RhodeCodeUi()
350 351 web4.ui_section = 'web'
351 352 web4.ui_key = 'baseurl'
352 353 web4.ui_value = '/'
353 354
354 355 paths = RhodeCodeUi()
355 356 paths.ui_section = 'paths'
356 357 paths.ui_key = '/'
357 358 paths.ui_value = path
358 359
359 360
360 361 hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication')
361 362 hgsettings2 = RhodeCodeSettings('title', 'RhodeCode')
362 363
363 364
364 365 try:
365 366 self.sa.add(web1)
366 367 self.sa.add(web2)
367 368 self.sa.add(web3)
368 369 self.sa.add(web4)
369 370 self.sa.add(paths)
370 371 self.sa.add(hgsettings1)
371 372 self.sa.add(hgsettings2)
372 373
373 374 self.sa.commit()
374 375 except:
375 376 self.sa.rollback()
376 377 raise
377 378
378 379 self.create_ldap_options()
379 380
380 381 log.info('created ui config')
381 382
382 383 def create_user(self, username, password, email='', admin=False):
383 384 log.info('creating administrator user %s', username)
384 385 new_user = User()
385 386 new_user.username = username
386 387 new_user.password = get_crypt_password(password)
387 388 new_user.name = 'RhodeCode'
388 389 new_user.lastname = 'Admin'
389 390 new_user.email = email
390 391 new_user.admin = admin
391 392 new_user.active = True
392 393
393 394 try:
394 395 self.sa.add(new_user)
395 396 self.sa.commit()
396 397 except:
397 398 self.sa.rollback()
398 399 raise
399 400
400 401 def create_default_user(self):
401 402 log.info('creating default user')
402 403 #create default user for handling default permissions.
403 404 def_user = User()
404 405 def_user.username = 'default'
405 406 def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
406 407 def_user.name = 'Anonymous'
407 408 def_user.lastname = 'User'
408 409 def_user.email = 'anonymous@rhodecode.org'
409 410 def_user.admin = False
410 411 def_user.active = False
411 412 try:
412 413 self.sa.add(def_user)
413 414 self.sa.commit()
414 415 except:
415 416 self.sa.rollback()
416 417 raise
417 418
418 419 def create_permissions(self):
419 420 #module.(access|create|change|delete)_[name]
420 421 #module.(read|write|owner)
421 422 perms = [('repository.none', 'Repository no access'),
422 423 ('repository.read', 'Repository read access'),
423 424 ('repository.write', 'Repository write access'),
424 425 ('repository.admin', 'Repository admin access'),
425 426 ('hg.admin', 'Hg Administrator'),
426 427 ('hg.create.repository', 'Repository create'),
427 428 ('hg.create.none', 'Repository creation disabled'),
428 429 ('hg.register.none', 'Register disabled'),
429 430 ('hg.register.manual_activate', 'Register new user with rhodecode without manual activation'),
430 431 ('hg.register.auto_activate', 'Register new user with rhodecode without auto activation'),
431 432 ]
432 433
433 434 for p in perms:
434 435 new_perm = Permission()
435 436 new_perm.permission_name = p[0]
436 437 new_perm.permission_longname = p[1]
437 438 try:
438 439 self.sa.add(new_perm)
439 440 self.sa.commit()
440 441 except:
441 442 self.sa.rollback()
442 443 raise
443 444
444 445 def populate_default_permissions(self):
445 446 log.info('creating default user permissions')
446 447
447 448 default_user = self.sa.query(User)\
448 449 .filter(User.username == 'default').scalar()
449 450
450 451 reg_perm = UserToPerm()
451 452 reg_perm.user = default_user
452 453 reg_perm.permission = self.sa.query(Permission)\
453 454 .filter(Permission.permission_name == 'hg.register.manual_activate')\
454 455 .scalar()
455 456
456 457 create_repo_perm = UserToPerm()
457 458 create_repo_perm.user = default_user
458 459 create_repo_perm.permission = self.sa.query(Permission)\
459 460 .filter(Permission.permission_name == 'hg.create.repository')\
460 461 .scalar()
461 462
462 463 default_repo_perm = UserToPerm()
463 464 default_repo_perm.user = default_user
464 465 default_repo_perm.permission = self.sa.query(Permission)\
465 466 .filter(Permission.permission_name == 'repository.read')\
466 467 .scalar()
467 468
468 469 try:
469 470 self.sa.add(reg_perm)
470 471 self.sa.add(create_repo_perm)
471 472 self.sa.add(default_repo_perm)
472 473 self.sa.commit()
473 474 except:
474 475 self.sa.rollback()
475 476 raise
476 477
General Comments 0
You need to be logged in to leave comments. Login now