##// END OF EJS Templates
warn user about not using waitress on python2.5
marcink -
r2827:d30c0a98 beta
parent child Browse files
Show More
@@ -1,661 +1,670 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.db_manage
3 rhodecode.lib.db_manage
4 ~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~
5
5
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) 2010-2012 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
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26
26
27 import os
27 import os
28 import sys
28 import sys
29 import uuid
29 import uuid
30 import logging
30 import logging
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__, __py_version__
34
34
35 from rhodecode.model.user import UserModel
35 from rhodecode.model.user import UserModel
36 from rhodecode.lib.utils import ask_ok
36 from rhodecode.lib.utils import ask_ok
37 from rhodecode.model import init_model
37 from rhodecode.model import init_model
38 from rhodecode.model.db import User, Permission, RhodeCodeUi, \
38 from rhodecode.model.db import User, Permission, RhodeCodeUi, \
39 RhodeCodeSetting, UserToPerm, DbMigrateVersion, RepoGroup, \
39 RhodeCodeSetting, UserToPerm, DbMigrateVersion, RepoGroup, \
40 UserRepoGroupToPerm
40 UserRepoGroupToPerm
41
41
42 from sqlalchemy.engine import create_engine
42 from sqlalchemy.engine import create_engine
43 from rhodecode.model.repos_group import ReposGroupModel
43 from rhodecode.model.repos_group import ReposGroupModel
44 #from rhodecode.model import meta
44 #from rhodecode.model import meta
45 from rhodecode.model.meta import Session, Base
45 from rhodecode.model.meta import Session, Base
46
46
47
47
48 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
49
49
50
50
51 def notify(msg):
51 def notify(msg):
52 """
52 """
53 Notification for migrations messages
53 Notification for migrations messages
54 """
54 """
55 ml = len(msg) + (4 * 2)
55 ml = len(msg) + (4 * 2)
56 print >> sys.stdout, ('*** %s ***\n%s' % (msg, '*' * ml)).upper()
56 print >> sys.stdout, ('*** %s ***\n%s' % (msg, '*' * ml)).upper()
57
57
58
58
59 class DbManage(object):
59 class DbManage(object):
60 def __init__(self, log_sql, dbconf, root, tests=False):
60 def __init__(self, log_sql, dbconf, root, tests=False):
61 self.dbname = dbconf.split('/')[-1]
61 self.dbname = dbconf.split('/')[-1]
62 self.tests = tests
62 self.tests = tests
63 self.root = root
63 self.root = root
64 self.dburi = dbconf
64 self.dburi = dbconf
65 self.log_sql = log_sql
65 self.log_sql = log_sql
66 self.db_exists = False
66 self.db_exists = False
67 self.init_db()
67 self.init_db()
68
68
69 def init_db(self):
69 def init_db(self):
70 engine = create_engine(self.dburi, echo=self.log_sql)
70 engine = create_engine(self.dburi, echo=self.log_sql)
71 init_model(engine)
71 init_model(engine)
72 self.sa = Session()
72 self.sa = Session()
73
73
74 def create_tables(self, override=False, defaults={}):
74 def create_tables(self, override=False, defaults={}):
75 """
75 """
76 Create a auth database
76 Create a auth database
77 """
77 """
78 quiet = defaults.get('quiet')
78 quiet = defaults.get('quiet')
79 log.info("Any existing database is going to be destroyed")
79 log.info("Any existing database is going to be destroyed")
80 if self.tests or quiet:
80 if self.tests or quiet:
81 destroy = True
81 destroy = True
82 else:
82 else:
83 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
83 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
84 if not destroy:
84 if not destroy:
85 sys.exit()
85 sys.exit()
86 if destroy:
86 if destroy:
87 Base.metadata.drop_all()
87 Base.metadata.drop_all()
88
88
89 checkfirst = not override
89 checkfirst = not override
90 Base.metadata.create_all(checkfirst=checkfirst)
90 Base.metadata.create_all(checkfirst=checkfirst)
91 log.info('Created tables for %s' % self.dbname)
91 log.info('Created tables for %s' % self.dbname)
92
92
93 def set_db_version(self):
93 def set_db_version(self):
94 ver = DbMigrateVersion()
94 ver = DbMigrateVersion()
95 ver.version = __dbversion__
95 ver.version = __dbversion__
96 ver.repository_id = 'rhodecode_db_migrations'
96 ver.repository_id = 'rhodecode_db_migrations'
97 ver.repository_path = 'versions'
97 ver.repository_path = 'versions'
98 self.sa.add(ver)
98 self.sa.add(ver)
99 log.info('db version set to: %s' % __dbversion__)
99 log.info('db version set to: %s' % __dbversion__)
100
100
101 def upgrade(self):
101 def upgrade(self):
102 """
102 """
103 Upgrades given database schema to given revision following
103 Upgrades given database schema to given revision following
104 all needed steps, to perform the upgrade
104 all needed steps, to perform the upgrade
105
105
106 """
106 """
107
107
108 from rhodecode.lib.dbmigrate.migrate.versioning import api
108 from rhodecode.lib.dbmigrate.migrate.versioning import api
109 from rhodecode.lib.dbmigrate.migrate.exceptions import \
109 from rhodecode.lib.dbmigrate.migrate.exceptions import \
110 DatabaseNotControlledError
110 DatabaseNotControlledError
111
111
112 if 'sqlite' in self.dburi:
112 if 'sqlite' in self.dburi:
113 print (
113 print (
114 '********************** WARNING **********************\n'
114 '********************** WARNING **********************\n'
115 'Make sure your version of sqlite is at least 3.7.X. \n'
115 'Make sure your version of sqlite is at least 3.7.X. \n'
116 'Earlier versions are known to fail on some migrations\n'
116 'Earlier versions are known to fail on some migrations\n'
117 '*****************************************************\n'
117 '*****************************************************\n'
118 )
118 )
119 upgrade = ask_ok('You are about to perform database upgrade, make '
119 upgrade = ask_ok('You are about to perform database upgrade, make '
120 'sure You backed up your database before. '
120 'sure You backed up your database before. '
121 'Continue ? [y/n]')
121 'Continue ? [y/n]')
122 if not upgrade:
122 if not upgrade:
123 sys.exit('Nothing done')
123 sys.exit('Nothing done')
124
124
125 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
125 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
126 'rhodecode/lib/dbmigrate')
126 'rhodecode/lib/dbmigrate')
127 db_uri = self.dburi
127 db_uri = self.dburi
128
128
129 try:
129 try:
130 curr_version = api.db_version(db_uri, repository_path)
130 curr_version = api.db_version(db_uri, repository_path)
131 msg = ('Found current database under version'
131 msg = ('Found current database under version'
132 ' control with version %s' % curr_version)
132 ' control with version %s' % curr_version)
133
133
134 except (RuntimeError, DatabaseNotControlledError):
134 except (RuntimeError, DatabaseNotControlledError):
135 curr_version = 1
135 curr_version = 1
136 msg = ('Current database is not under version control. Setting'
136 msg = ('Current database is not under version control. Setting'
137 ' as version %s' % curr_version)
137 ' as version %s' % curr_version)
138 api.version_control(db_uri, repository_path, curr_version)
138 api.version_control(db_uri, repository_path, curr_version)
139
139
140 notify(msg)
140 notify(msg)
141
141
142 if curr_version == __dbversion__:
142 if curr_version == __dbversion__:
143 sys.exit('This database is already at the newest version')
143 sys.exit('This database is already at the newest version')
144
144
145 #======================================================================
145 #======================================================================
146 # UPGRADE STEPS
146 # UPGRADE STEPS
147 #======================================================================
147 #======================================================================
148
148
149 class UpgradeSteps(object):
149 class UpgradeSteps(object):
150 """
150 """
151 Those steps follow schema versions so for example schema
151 Those steps follow schema versions so for example schema
152 for example schema with seq 002 == step_2 and so on.
152 for example schema with seq 002 == step_2 and so on.
153 """
153 """
154
154
155 def __init__(self, klass):
155 def __init__(self, klass):
156 self.klass = klass
156 self.klass = klass
157
157
158 def step_0(self):
158 def step_0(self):
159 # step 0 is the schema upgrade, and than follow proper upgrades
159 # step 0 is the schema upgrade, and than follow proper upgrades
160 notify('attempting to do database upgrade to version %s' \
160 notify('attempting to do database upgrade to version %s' \
161 % __dbversion__)
161 % __dbversion__)
162 api.upgrade(db_uri, repository_path, __dbversion__)
162 api.upgrade(db_uri, repository_path, __dbversion__)
163 notify('Schema upgrade completed')
163 notify('Schema upgrade completed')
164
164
165 def step_1(self):
165 def step_1(self):
166 pass
166 pass
167
167
168 def step_2(self):
168 def step_2(self):
169 notify('Patching repo paths for newer version of RhodeCode')
169 notify('Patching repo paths for newer version of RhodeCode')
170 self.klass.fix_repo_paths()
170 self.klass.fix_repo_paths()
171
171
172 notify('Patching default user of RhodeCode')
172 notify('Patching default user of RhodeCode')
173 self.klass.fix_default_user()
173 self.klass.fix_default_user()
174
174
175 log.info('Changing ui settings')
175 log.info('Changing ui settings')
176 self.klass.create_ui_settings()
176 self.klass.create_ui_settings()
177
177
178 def step_3(self):
178 def step_3(self):
179 notify('Adding additional settings into RhodeCode db')
179 notify('Adding additional settings into RhodeCode db')
180 self.klass.fix_settings()
180 self.klass.fix_settings()
181 notify('Adding ldap defaults')
181 notify('Adding ldap defaults')
182 self.klass.create_ldap_options(skip_existing=True)
182 self.klass.create_ldap_options(skip_existing=True)
183
183
184 def step_4(self):
184 def step_4(self):
185 notify('create permissions and fix groups')
185 notify('create permissions and fix groups')
186 self.klass.create_permissions()
186 self.klass.create_permissions()
187 self.klass.fixup_groups()
187 self.klass.fixup_groups()
188
188
189 def step_5(self):
189 def step_5(self):
190 pass
190 pass
191
191
192 def step_6(self):
192 def step_6(self):
193
193
194 notify('re-checking permissions')
194 notify('re-checking permissions')
195 self.klass.create_permissions()
195 self.klass.create_permissions()
196
196
197 notify('installing new UI options')
197 notify('installing new UI options')
198 sett4 = RhodeCodeSetting('show_public_icon', True)
198 sett4 = RhodeCodeSetting('show_public_icon', True)
199 Session().add(sett4)
199 Session().add(sett4)
200 sett5 = RhodeCodeSetting('show_private_icon', True)
200 sett5 = RhodeCodeSetting('show_private_icon', True)
201 Session().add(sett5)
201 Session().add(sett5)
202 sett6 = RhodeCodeSetting('stylify_metatags', False)
202 sett6 = RhodeCodeSetting('stylify_metatags', False)
203 Session().add(sett6)
203 Session().add(sett6)
204
204
205 notify('fixing old PULL hook')
205 notify('fixing old PULL hook')
206 _pull = RhodeCodeUi.get_by_key('preoutgoing.pull_logger')
206 _pull = RhodeCodeUi.get_by_key('preoutgoing.pull_logger')
207 if _pull:
207 if _pull:
208 _pull.ui_key = RhodeCodeUi.HOOK_PULL
208 _pull.ui_key = RhodeCodeUi.HOOK_PULL
209 Session().add(_pull)
209 Session().add(_pull)
210
210
211 notify('fixing old PUSH hook')
211 notify('fixing old PUSH hook')
212 _push = RhodeCodeUi.get_by_key('pretxnchangegroup.push_logger')
212 _push = RhodeCodeUi.get_by_key('pretxnchangegroup.push_logger')
213 if _push:
213 if _push:
214 _push.ui_key = RhodeCodeUi.HOOK_PUSH
214 _push.ui_key = RhodeCodeUi.HOOK_PUSH
215 Session().add(_push)
215 Session().add(_push)
216
216
217 notify('installing new pre-push hook')
217 notify('installing new pre-push hook')
218 hooks4 = RhodeCodeUi()
218 hooks4 = RhodeCodeUi()
219 hooks4.ui_section = 'hooks'
219 hooks4.ui_section = 'hooks'
220 hooks4.ui_key = RhodeCodeUi.HOOK_PRE_PUSH
220 hooks4.ui_key = RhodeCodeUi.HOOK_PRE_PUSH
221 hooks4.ui_value = 'python:rhodecode.lib.hooks.pre_push'
221 hooks4.ui_value = 'python:rhodecode.lib.hooks.pre_push'
222 Session().add(hooks4)
222 Session().add(hooks4)
223
223
224 notify('installing new pre-pull hook')
224 notify('installing new pre-pull hook')
225 hooks6 = RhodeCodeUi()
225 hooks6 = RhodeCodeUi()
226 hooks6.ui_section = 'hooks'
226 hooks6.ui_section = 'hooks'
227 hooks6.ui_key = RhodeCodeUi.HOOK_PRE_PULL
227 hooks6.ui_key = RhodeCodeUi.HOOK_PRE_PULL
228 hooks6.ui_value = 'python:rhodecode.lib.hooks.pre_pull'
228 hooks6.ui_value = 'python:rhodecode.lib.hooks.pre_pull'
229 Session().add(hooks6)
229 Session().add(hooks6)
230
230
231 notify('installing hgsubversion option')
231 notify('installing hgsubversion option')
232 # enable hgsubversion disabled by default
232 # enable hgsubversion disabled by default
233 hgsubversion = RhodeCodeUi()
233 hgsubversion = RhodeCodeUi()
234 hgsubversion.ui_section = 'extensions'
234 hgsubversion.ui_section = 'extensions'
235 hgsubversion.ui_key = 'hgsubversion'
235 hgsubversion.ui_key = 'hgsubversion'
236 hgsubversion.ui_value = ''
236 hgsubversion.ui_value = ''
237 hgsubversion.ui_active = False
237 hgsubversion.ui_active = False
238 Session().add(hgsubversion)
238 Session().add(hgsubversion)
239
239
240 notify('installing hg git option')
240 notify('installing hg git option')
241 # enable hggit disabled by default
241 # enable hggit disabled by default
242 hggit = RhodeCodeUi()
242 hggit = RhodeCodeUi()
243 hggit.ui_section = 'extensions'
243 hggit.ui_section = 'extensions'
244 hggit.ui_key = 'hggit'
244 hggit.ui_key = 'hggit'
245 hggit.ui_value = ''
245 hggit.ui_value = ''
246 hggit.ui_active = False
246 hggit.ui_active = False
247 Session().add(hggit)
247 Session().add(hggit)
248
248
249 notify('re-check default permissions')
249 notify('re-check default permissions')
250 default_user = User.get_by_username(User.DEFAULT_USER)
250 default_user = User.get_by_username(User.DEFAULT_USER)
251 perm = Permission.get_by_key('hg.fork.repository')
251 perm = Permission.get_by_key('hg.fork.repository')
252 reg_perm = UserToPerm()
252 reg_perm = UserToPerm()
253 reg_perm.user = default_user
253 reg_perm.user = default_user
254 reg_perm.permission = perm
254 reg_perm.permission = perm
255 Session().add(reg_perm)
255 Session().add(reg_perm)
256
256
257 def step_7(self):
257 def step_7(self):
258 perm_fixes = self.klass.reset_permissions(User.DEFAULT_USER)
258 perm_fixes = self.klass.reset_permissions(User.DEFAULT_USER)
259 Session().commit()
259 Session().commit()
260 if perm_fixes:
260 if perm_fixes:
261 notify('There was an inconsistent state of permissions '
261 notify('There was an inconsistent state of permissions '
262 'detected for default user. Permissions are now '
262 'detected for default user. Permissions are now '
263 'reset to the default value for default user. '
263 'reset to the default value for default user. '
264 'Please validate and check default permissions '
264 'Please validate and check default permissions '
265 'in admin panel')
265 'in admin panel')
266
266
267 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
267 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
268
268
269 # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
269 # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
270 _step = None
270 _step = None
271 for step in upgrade_steps:
271 for step in upgrade_steps:
272 notify('performing upgrade step %s' % step)
272 notify('performing upgrade step %s' % step)
273 getattr(UpgradeSteps(self), 'step_%s' % step)()
273 getattr(UpgradeSteps(self), 'step_%s' % step)()
274 self.sa.commit()
274 self.sa.commit()
275 _step = step
275 _step = step
276
276
277 notify('upgrade to version %s successful' % _step)
277 notify('upgrade to version %s successful' % _step)
278
278
279 def fix_repo_paths(self):
279 def fix_repo_paths(self):
280 """
280 """
281 Fixes a old rhodecode version path into new one without a '*'
281 Fixes a old rhodecode version path into new one without a '*'
282 """
282 """
283
283
284 paths = self.sa.query(RhodeCodeUi)\
284 paths = self.sa.query(RhodeCodeUi)\
285 .filter(RhodeCodeUi.ui_key == '/')\
285 .filter(RhodeCodeUi.ui_key == '/')\
286 .scalar()
286 .scalar()
287
287
288 paths.ui_value = paths.ui_value.replace('*', '')
288 paths.ui_value = paths.ui_value.replace('*', '')
289
289
290 try:
290 try:
291 self.sa.add(paths)
291 self.sa.add(paths)
292 self.sa.commit()
292 self.sa.commit()
293 except:
293 except:
294 self.sa.rollback()
294 self.sa.rollback()
295 raise
295 raise
296
296
297 def fix_default_user(self):
297 def fix_default_user(self):
298 """
298 """
299 Fixes a old default user with some 'nicer' default values,
299 Fixes a old default user with some 'nicer' default values,
300 used mostly for anonymous access
300 used mostly for anonymous access
301 """
301 """
302 def_user = self.sa.query(User)\
302 def_user = self.sa.query(User)\
303 .filter(User.username == 'default')\
303 .filter(User.username == 'default')\
304 .one()
304 .one()
305
305
306 def_user.name = 'Anonymous'
306 def_user.name = 'Anonymous'
307 def_user.lastname = 'User'
307 def_user.lastname = 'User'
308 def_user.email = 'anonymous@rhodecode.org'
308 def_user.email = 'anonymous@rhodecode.org'
309
309
310 try:
310 try:
311 self.sa.add(def_user)
311 self.sa.add(def_user)
312 self.sa.commit()
312 self.sa.commit()
313 except:
313 except:
314 self.sa.rollback()
314 self.sa.rollback()
315 raise
315 raise
316
316
317 def fix_settings(self):
317 def fix_settings(self):
318 """
318 """
319 Fixes rhodecode settings adds ga_code key for google analytics
319 Fixes rhodecode settings adds ga_code key for google analytics
320 """
320 """
321
321
322 hgsettings3 = RhodeCodeSetting('ga_code', '')
322 hgsettings3 = RhodeCodeSetting('ga_code', '')
323
323
324 try:
324 try:
325 self.sa.add(hgsettings3)
325 self.sa.add(hgsettings3)
326 self.sa.commit()
326 self.sa.commit()
327 except:
327 except:
328 self.sa.rollback()
328 self.sa.rollback()
329 raise
329 raise
330
330
331 def admin_prompt(self, second=False, defaults={}):
331 def admin_prompt(self, second=False, defaults={}):
332 if not self.tests:
332 if not self.tests:
333 import getpass
333 import getpass
334
334
335 # defaults
335 # defaults
336 username = defaults.get('username')
336 username = defaults.get('username')
337 password = defaults.get('password')
337 password = defaults.get('password')
338 email = defaults.get('email')
338 email = defaults.get('email')
339
339
340 def get_password():
340 def get_password():
341 password = getpass.getpass('Specify admin password '
341 password = getpass.getpass('Specify admin password '
342 '(min 6 chars):')
342 '(min 6 chars):')
343 confirm = getpass.getpass('Confirm password:')
343 confirm = getpass.getpass('Confirm password:')
344
344
345 if password != confirm:
345 if password != confirm:
346 log.error('passwords mismatch')
346 log.error('passwords mismatch')
347 return False
347 return False
348 if len(password) < 6:
348 if len(password) < 6:
349 log.error('password is to short use at least 6 characters')
349 log.error('password is to short use at least 6 characters')
350 return False
350 return False
351
351
352 return password
352 return password
353 if username is None:
353 if username is None:
354 username = raw_input('Specify admin username:')
354 username = raw_input('Specify admin username:')
355 if password is None:
355 if password is None:
356 password = get_password()
356 password = get_password()
357 if not password:
357 if not password:
358 #second try
358 #second try
359 password = get_password()
359 password = get_password()
360 if not password:
360 if not password:
361 sys.exit()
361 sys.exit()
362 if email is None:
362 if email is None:
363 email = raw_input('Specify admin email:')
363 email = raw_input('Specify admin email:')
364 self.create_user(username, password, email, True)
364 self.create_user(username, password, email, True)
365 else:
365 else:
366 log.info('creating admin and regular test users')
366 log.info('creating admin and regular test users')
367 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \
367 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \
368 TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \
368 TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \
369 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \
369 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \
370 TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \
370 TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \
371 TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL
371 TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL
372
372
373 self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,
373 self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,
374 TEST_USER_ADMIN_EMAIL, True)
374 TEST_USER_ADMIN_EMAIL, True)
375
375
376 self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
376 self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
377 TEST_USER_REGULAR_EMAIL, False)
377 TEST_USER_REGULAR_EMAIL, False)
378
378
379 self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS,
379 self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS,
380 TEST_USER_REGULAR2_EMAIL, False)
380 TEST_USER_REGULAR2_EMAIL, False)
381
381
382 def create_ui_settings(self):
382 def create_ui_settings(self):
383 """
383 """
384 Creates ui settings, fills out hooks
384 Creates ui settings, fills out hooks
385 and disables dotencode
385 and disables dotencode
386 """
386 """
387
387
388 #HOOKS
388 #HOOKS
389 hooks1_key = RhodeCodeUi.HOOK_UPDATE
389 hooks1_key = RhodeCodeUi.HOOK_UPDATE
390 hooks1_ = self.sa.query(RhodeCodeUi)\
390 hooks1_ = self.sa.query(RhodeCodeUi)\
391 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
391 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
392
392
393 hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
393 hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
394 hooks1.ui_section = 'hooks'
394 hooks1.ui_section = 'hooks'
395 hooks1.ui_key = hooks1_key
395 hooks1.ui_key = hooks1_key
396 hooks1.ui_value = 'hg update >&2'
396 hooks1.ui_value = 'hg update >&2'
397 hooks1.ui_active = False
397 hooks1.ui_active = False
398 self.sa.add(hooks1)
398 self.sa.add(hooks1)
399
399
400 hooks2_key = RhodeCodeUi.HOOK_REPO_SIZE
400 hooks2_key = RhodeCodeUi.HOOK_REPO_SIZE
401 hooks2_ = self.sa.query(RhodeCodeUi)\
401 hooks2_ = self.sa.query(RhodeCodeUi)\
402 .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
402 .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
403 hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
403 hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
404 hooks2.ui_section = 'hooks'
404 hooks2.ui_section = 'hooks'
405 hooks2.ui_key = hooks2_key
405 hooks2.ui_key = hooks2_key
406 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
406 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
407 self.sa.add(hooks2)
407 self.sa.add(hooks2)
408
408
409 hooks3 = RhodeCodeUi()
409 hooks3 = RhodeCodeUi()
410 hooks3.ui_section = 'hooks'
410 hooks3.ui_section = 'hooks'
411 hooks3.ui_key = RhodeCodeUi.HOOK_PUSH
411 hooks3.ui_key = RhodeCodeUi.HOOK_PUSH
412 hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
412 hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
413 self.sa.add(hooks3)
413 self.sa.add(hooks3)
414
414
415 hooks4 = RhodeCodeUi()
415 hooks4 = RhodeCodeUi()
416 hooks4.ui_section = 'hooks'
416 hooks4.ui_section = 'hooks'
417 hooks4.ui_key = RhodeCodeUi.HOOK_PRE_PUSH
417 hooks4.ui_key = RhodeCodeUi.HOOK_PRE_PUSH
418 hooks4.ui_value = 'python:rhodecode.lib.hooks.pre_push'
418 hooks4.ui_value = 'python:rhodecode.lib.hooks.pre_push'
419 self.sa.add(hooks4)
419 self.sa.add(hooks4)
420
420
421 hooks5 = RhodeCodeUi()
421 hooks5 = RhodeCodeUi()
422 hooks5.ui_section = 'hooks'
422 hooks5.ui_section = 'hooks'
423 hooks5.ui_key = RhodeCodeUi.HOOK_PULL
423 hooks5.ui_key = RhodeCodeUi.HOOK_PULL
424 hooks5.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
424 hooks5.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
425 self.sa.add(hooks5)
425 self.sa.add(hooks5)
426
426
427 hooks6 = RhodeCodeUi()
427 hooks6 = RhodeCodeUi()
428 hooks6.ui_section = 'hooks'
428 hooks6.ui_section = 'hooks'
429 hooks6.ui_key = RhodeCodeUi.HOOK_PRE_PULL
429 hooks6.ui_key = RhodeCodeUi.HOOK_PRE_PULL
430 hooks6.ui_value = 'python:rhodecode.lib.hooks.pre_pull'
430 hooks6.ui_value = 'python:rhodecode.lib.hooks.pre_pull'
431 self.sa.add(hooks6)
431 self.sa.add(hooks6)
432
432
433 # enable largefiles
433 # enable largefiles
434 largefiles = RhodeCodeUi()
434 largefiles = RhodeCodeUi()
435 largefiles.ui_section = 'extensions'
435 largefiles.ui_section = 'extensions'
436 largefiles.ui_key = 'largefiles'
436 largefiles.ui_key = 'largefiles'
437 largefiles.ui_value = ''
437 largefiles.ui_value = ''
438 self.sa.add(largefiles)
438 self.sa.add(largefiles)
439
439
440 # enable hgsubversion disabled by default
440 # enable hgsubversion disabled by default
441 hgsubversion = RhodeCodeUi()
441 hgsubversion = RhodeCodeUi()
442 hgsubversion.ui_section = 'extensions'
442 hgsubversion.ui_section = 'extensions'
443 hgsubversion.ui_key = 'hgsubversion'
443 hgsubversion.ui_key = 'hgsubversion'
444 hgsubversion.ui_value = ''
444 hgsubversion.ui_value = ''
445 hgsubversion.ui_active = False
445 hgsubversion.ui_active = False
446 self.sa.add(hgsubversion)
446 self.sa.add(hgsubversion)
447
447
448 # enable hggit disabled by default
448 # enable hggit disabled by default
449 hggit = RhodeCodeUi()
449 hggit = RhodeCodeUi()
450 hggit.ui_section = 'extensions'
450 hggit.ui_section = 'extensions'
451 hggit.ui_key = 'hggit'
451 hggit.ui_key = 'hggit'
452 hggit.ui_value = ''
452 hggit.ui_value = ''
453 hggit.ui_active = False
453 hggit.ui_active = False
454 self.sa.add(hggit)
454 self.sa.add(hggit)
455
455
456 def create_ldap_options(self, skip_existing=False):
456 def create_ldap_options(self, skip_existing=False):
457 """Creates ldap settings"""
457 """Creates ldap settings"""
458
458
459 for k, v in [('ldap_active', 'false'), ('ldap_host', ''),
459 for k, v in [('ldap_active', 'false'), ('ldap_host', ''),
460 ('ldap_port', '389'), ('ldap_tls_kind', 'PLAIN'),
460 ('ldap_port', '389'), ('ldap_tls_kind', 'PLAIN'),
461 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''),
461 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''),
462 ('ldap_dn_pass', ''), ('ldap_base_dn', ''),
462 ('ldap_dn_pass', ''), ('ldap_base_dn', ''),
463 ('ldap_filter', ''), ('ldap_search_scope', ''),
463 ('ldap_filter', ''), ('ldap_search_scope', ''),
464 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
464 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
465 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
465 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
466
466
467 if skip_existing and RhodeCodeSetting.get_by_name(k) != None:
467 if skip_existing and RhodeCodeSetting.get_by_name(k) != None:
468 log.debug('Skipping option %s' % k)
468 log.debug('Skipping option %s' % k)
469 continue
469 continue
470 setting = RhodeCodeSetting(k, v)
470 setting = RhodeCodeSetting(k, v)
471 self.sa.add(setting)
471 self.sa.add(setting)
472
472
473 def fixup_groups(self):
473 def fixup_groups(self):
474 def_usr = User.get_by_username('default')
474 def_usr = User.get_by_username('default')
475 for g in RepoGroup.query().all():
475 for g in RepoGroup.query().all():
476 g.group_name = g.get_new_name(g.name)
476 g.group_name = g.get_new_name(g.name)
477 self.sa.add(g)
477 self.sa.add(g)
478 # get default perm
478 # get default perm
479 default = UserRepoGroupToPerm.query()\
479 default = UserRepoGroupToPerm.query()\
480 .filter(UserRepoGroupToPerm.group == g)\
480 .filter(UserRepoGroupToPerm.group == g)\
481 .filter(UserRepoGroupToPerm.user == def_usr)\
481 .filter(UserRepoGroupToPerm.user == def_usr)\
482 .scalar()
482 .scalar()
483
483
484 if default is None:
484 if default is None:
485 log.debug('missing default permission for group %s adding' % g)
485 log.debug('missing default permission for group %s adding' % g)
486 ReposGroupModel()._create_default_perms(g)
486 ReposGroupModel()._create_default_perms(g)
487
487
488 def reset_permissions(self, username):
488 def reset_permissions(self, username):
489 """
489 """
490 Resets permissions to default state, usefull when old systems had
490 Resets permissions to default state, usefull when old systems had
491 bad permissions, we must clean them up
491 bad permissions, we must clean them up
492
492
493 :param username:
493 :param username:
494 :type username:
494 :type username:
495 """
495 """
496 default_user = User.get_by_username(username)
496 default_user = User.get_by_username(username)
497 if not default_user:
497 if not default_user:
498 return
498 return
499
499
500 u2p = UserToPerm.query()\
500 u2p = UserToPerm.query()\
501 .filter(UserToPerm.user == default_user).all()
501 .filter(UserToPerm.user == default_user).all()
502 fixed = False
502 fixed = False
503 if len(u2p) != len(User.DEFAULT_PERMISSIONS):
503 if len(u2p) != len(User.DEFAULT_PERMISSIONS):
504 for p in u2p:
504 for p in u2p:
505 Session().delete(p)
505 Session().delete(p)
506 fixed = True
506 fixed = True
507 self.populate_default_permissions()
507 self.populate_default_permissions()
508 return fixed
508 return fixed
509
509
510 def config_prompt(self, test_repo_path='', retries=3, defaults={}):
510 def config_prompt(self, test_repo_path='', retries=3, defaults={}):
511 _path = defaults.get('repos_location')
511 _path = defaults.get('repos_location')
512 if retries == 3:
512 if retries == 3:
513 log.info('Setting up repositories config')
513 log.info('Setting up repositories config')
514
514
515 if _path is not None:
515 if _path is not None:
516 path = _path
516 path = _path
517 elif not self.tests and not test_repo_path:
517 elif not self.tests and not test_repo_path:
518 path = raw_input(
518 path = raw_input(
519 'Enter a valid absolute path to store repositories. '
519 'Enter a valid absolute path to store repositories. '
520 'All repositories in that path will be added automatically:'
520 'All repositories in that path will be added automatically:'
521 )
521 )
522 else:
522 else:
523 path = test_repo_path
523 path = test_repo_path
524 path_ok = True
524 path_ok = True
525
525
526 # check proper dir
526 # check proper dir
527 if not os.path.isdir(path):
527 if not os.path.isdir(path):
528 path_ok = False
528 path_ok = False
529 log.error('Given path %s is not a valid directory' % path)
529 log.error('Given path %s is not a valid directory' % path)
530
530
531 elif not os.path.isabs(path):
531 elif not os.path.isabs(path):
532 path_ok = False
532 path_ok = False
533 log.error('Given path %s is not an absolute path' % path)
533 log.error('Given path %s is not an absolute path' % path)
534
534
535 # check write access
535 # check write access
536 elif not os.access(path, os.W_OK) and path_ok:
536 elif not os.access(path, os.W_OK) and path_ok:
537 path_ok = False
537 path_ok = False
538 log.error('No write permission to given path %s' % path)
538 log.error('No write permission to given path %s' % path)
539
539
540 if retries == 0:
540 if retries == 0:
541 sys.exit('max retries reached')
541 sys.exit('max retries reached')
542 if path_ok is False:
542 if path_ok is False:
543 retries -= 1
543 retries -= 1
544 return self.config_prompt(test_repo_path, retries)
544 return self.config_prompt(test_repo_path, retries)
545
545
546 real_path = os.path.realpath(path)
546 real_path = os.path.realpath(path)
547
547
548 if real_path != path:
548 if real_path != path:
549 if not ask_ok(('Path looks like a symlink, Rhodecode will store '
549 if not ask_ok(('Path looks like a symlink, Rhodecode will store '
550 'given path as %s ? [y/n]') % (real_path)):
550 'given path as %s ? [y/n]') % (real_path)):
551 log.error('Canceled by user')
551 log.error('Canceled by user')
552 sys.exit(-1)
552 sys.exit(-1)
553
553
554 return real_path
554 return real_path
555
555
556 def create_settings(self, path):
556 def create_settings(self, path):
557
557
558 self.create_ui_settings()
558 self.create_ui_settings()
559
559
560 #HG UI OPTIONS
560 #HG UI OPTIONS
561 web1 = RhodeCodeUi()
561 web1 = RhodeCodeUi()
562 web1.ui_section = 'web'
562 web1.ui_section = 'web'
563 web1.ui_key = 'push_ssl'
563 web1.ui_key = 'push_ssl'
564 web1.ui_value = 'false'
564 web1.ui_value = 'false'
565
565
566 web2 = RhodeCodeUi()
566 web2 = RhodeCodeUi()
567 web2.ui_section = 'web'
567 web2.ui_section = 'web'
568 web2.ui_key = 'allow_archive'
568 web2.ui_key = 'allow_archive'
569 web2.ui_value = 'gz zip bz2'
569 web2.ui_value = 'gz zip bz2'
570
570
571 web3 = RhodeCodeUi()
571 web3 = RhodeCodeUi()
572 web3.ui_section = 'web'
572 web3.ui_section = 'web'
573 web3.ui_key = 'allow_push'
573 web3.ui_key = 'allow_push'
574 web3.ui_value = '*'
574 web3.ui_value = '*'
575
575
576 web4 = RhodeCodeUi()
576 web4 = RhodeCodeUi()
577 web4.ui_section = 'web'
577 web4.ui_section = 'web'
578 web4.ui_key = 'baseurl'
578 web4.ui_key = 'baseurl'
579 web4.ui_value = '/'
579 web4.ui_value = '/'
580
580
581 paths = RhodeCodeUi()
581 paths = RhodeCodeUi()
582 paths.ui_section = 'paths'
582 paths.ui_section = 'paths'
583 paths.ui_key = '/'
583 paths.ui_key = '/'
584 paths.ui_value = path
584 paths.ui_value = path
585
585
586 phases = RhodeCodeUi()
586 phases = RhodeCodeUi()
587 phases.ui_section = 'phases'
587 phases.ui_section = 'phases'
588 phases.ui_key = 'publish'
588 phases.ui_key = 'publish'
589 phases.ui_value = False
589 phases.ui_value = False
590
590
591 sett1 = RhodeCodeSetting('realm', 'RhodeCode authentication')
591 sett1 = RhodeCodeSetting('realm', 'RhodeCode authentication')
592 sett2 = RhodeCodeSetting('title', 'RhodeCode')
592 sett2 = RhodeCodeSetting('title', 'RhodeCode')
593 sett3 = RhodeCodeSetting('ga_code', '')
593 sett3 = RhodeCodeSetting('ga_code', '')
594
594
595 sett4 = RhodeCodeSetting('show_public_icon', True)
595 sett4 = RhodeCodeSetting('show_public_icon', True)
596 sett5 = RhodeCodeSetting('show_private_icon', True)
596 sett5 = RhodeCodeSetting('show_private_icon', True)
597 sett6 = RhodeCodeSetting('stylify_metatags', False)
597 sett6 = RhodeCodeSetting('stylify_metatags', False)
598
598
599 self.sa.add(web1)
599 self.sa.add(web1)
600 self.sa.add(web2)
600 self.sa.add(web2)
601 self.sa.add(web3)
601 self.sa.add(web3)
602 self.sa.add(web4)
602 self.sa.add(web4)
603 self.sa.add(paths)
603 self.sa.add(paths)
604 self.sa.add(sett1)
604 self.sa.add(sett1)
605 self.sa.add(sett2)
605 self.sa.add(sett2)
606 self.sa.add(sett3)
606 self.sa.add(sett3)
607 self.sa.add(sett4)
607 self.sa.add(sett4)
608 self.sa.add(sett5)
608 self.sa.add(sett5)
609 self.sa.add(sett6)
609 self.sa.add(sett6)
610
610
611 self.create_ldap_options()
611 self.create_ldap_options()
612
612
613 log.info('created ui config')
613 log.info('created ui config')
614
614
615 def create_user(self, username, password, email='', admin=False):
615 def create_user(self, username, password, email='', admin=False):
616 log.info('creating user %s' % username)
616 log.info('creating user %s' % username)
617 UserModel().create_or_update(username, password, email,
617 UserModel().create_or_update(username, password, email,
618 firstname='RhodeCode', lastname='Admin',
618 firstname='RhodeCode', lastname='Admin',
619 active=True, admin=admin)
619 active=True, admin=admin)
620
620
621 def create_default_user(self):
621 def create_default_user(self):
622 log.info('creating default user')
622 log.info('creating default user')
623 # create default user for handling default permissions.
623 # create default user for handling default permissions.
624 UserModel().create_or_update(username='default',
624 UserModel().create_or_update(username='default',
625 password=str(uuid.uuid1())[:8],
625 password=str(uuid.uuid1())[:8],
626 email='anonymous@rhodecode.org',
626 email='anonymous@rhodecode.org',
627 firstname='Anonymous', lastname='User')
627 firstname='Anonymous', lastname='User')
628
628
629 def create_permissions(self):
629 def create_permissions(self):
630 # module.(access|create|change|delete)_[name]
630 # module.(access|create|change|delete)_[name]
631 # module.(none|read|write|admin)
631 # module.(none|read|write|admin)
632
632
633 for p in Permission.PERMS:
633 for p in Permission.PERMS:
634 if not Permission.get_by_key(p[0]):
634 if not Permission.get_by_key(p[0]):
635 new_perm = Permission()
635 new_perm = Permission()
636 new_perm.permission_name = p[0]
636 new_perm.permission_name = p[0]
637 new_perm.permission_longname = p[0]
637 new_perm.permission_longname = p[0]
638 self.sa.add(new_perm)
638 self.sa.add(new_perm)
639
639
640 def populate_default_permissions(self):
640 def populate_default_permissions(self):
641 log.info('creating default user permissions')
641 log.info('creating default user permissions')
642
642
643 default_user = User.get_by_username('default')
643 default_user = User.get_by_username('default')
644
644
645 for def_perm in User.DEFAULT_PERMISSIONS:
645 for def_perm in User.DEFAULT_PERMISSIONS:
646
646
647 perm = self.sa.query(Permission)\
647 perm = self.sa.query(Permission)\
648 .filter(Permission.permission_name == def_perm)\
648 .filter(Permission.permission_name == def_perm)\
649 .scalar()
649 .scalar()
650 if not perm:
650 if not perm:
651 raise Exception(
651 raise Exception(
652 'CRITICAL: permission %s not found inside database !!'
652 'CRITICAL: permission %s not found inside database !!'
653 % def_perm
653 % def_perm
654 )
654 )
655 if not UserToPerm.query()\
655 if not UserToPerm.query()\
656 .filter(UserToPerm.permission == perm)\
656 .filter(UserToPerm.permission == perm)\
657 .filter(UserToPerm.user == default_user).scalar():
657 .filter(UserToPerm.user == default_user).scalar():
658 reg_perm = UserToPerm()
658 reg_perm = UserToPerm()
659 reg_perm.user = default_user
659 reg_perm.user = default_user
660 reg_perm.permission = perm
660 reg_perm.permission = perm
661 self.sa.add(reg_perm)
661 self.sa.add(reg_perm)
662
663 def finish(self):
664 """
665 Function executed at the end of setup
666 """
667 if not __py_version__ >= (2, 6):
668 notify('Python2.5 detected, please switch '
669 'egg:waitress#main -> egg:Paste#http '
670 'in your .ini file') No newline at end of file
@@ -1,50 +1,51 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.websetup
3 rhodecode.websetup
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 Weboperations and setup for rhodecode
6 Weboperations and setup for rhodecode
7
7
8 :created_on: Dec 11, 2010
8 :created_on: Dec 11, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27
27
28 from rhodecode.config.environment import load_environment
28 from rhodecode.config.environment import load_environment
29 from rhodecode.lib.db_manage import DbManage
29 from rhodecode.lib.db_manage import DbManage
30 from rhodecode.model.meta import Session
30 from rhodecode.model.meta import Session
31
31
32
32
33 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
34
34
35
35
36 def setup_app(command, conf, vars):
36 def setup_app(command, conf, vars):
37 """Place any commands to setup rhodecode here"""
37 """Place any commands to setup rhodecode here"""
38 dbconf = conf['sqlalchemy.db1.url']
38 dbconf = conf['sqlalchemy.db1.url']
39 dbmanage = DbManage(log_sql=True, dbconf=dbconf, root=conf['here'],
39 dbmanage = DbManage(log_sql=True, dbconf=dbconf, root=conf['here'],
40 tests=False)
40 tests=False)
41 dbmanage.create_tables(override=True, defaults=command.options.__dict__)
41 dbmanage.create_tables(override=True, defaults=command.options.__dict__)
42 dbmanage.set_db_version()
42 dbmanage.set_db_version()
43 opts = dbmanage.config_prompt(None, defaults=command.options.__dict__)
43 opts = dbmanage.config_prompt(None, defaults=command.options.__dict__)
44 dbmanage.create_settings(opts)
44 dbmanage.create_settings(opts)
45 dbmanage.create_default_user()
45 dbmanage.create_default_user()
46 dbmanage.admin_prompt(defaults=command.options.__dict__)
46 dbmanage.admin_prompt(defaults=command.options.__dict__)
47 dbmanage.create_permissions()
47 dbmanage.create_permissions()
48 dbmanage.populate_default_permissions()
48 dbmanage.populate_default_permissions()
49 Session.commit()
49 Session.commit()
50 load_environment(conf.global_conf, conf.local_conf, initial=True)
50 load_environment(conf.global_conf, conf.local_conf, initial=True)
51 dbmanage.finish()
General Comments 0
You need to be logged in to leave comments. Login now