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