##// END OF EJS Templates
Merge with upstream
Nicolas VINOT -
r1588:8ac66733 merge beta
parent child Browse files
Show More
@@ -1,500 +1,505
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) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2009-2011 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__
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.lib.auth import get_crypt_password, generate_api_key
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 RhodeCodeSettings, UserToPerm, DbMigrateVersion
41
41
42 from sqlalchemy.engine import create_engine
42 from sqlalchemy.engine import create_engine
43
43
44 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
45
45
46
46
47 class DbManage(object):
47 class DbManage(object):
48 def __init__(self, log_sql, dbconf, root, tests=False):
48 def __init__(self, log_sql, dbconf, root, tests=False):
49 self.dbname = dbconf.split('/')[-1]
49 self.dbname = dbconf.split('/')[-1]
50 self.tests = tests
50 self.tests = tests
51 self.root = root
51 self.root = root
52 self.dburi = dbconf
52 self.dburi = dbconf
53 self.log_sql = log_sql
53 self.log_sql = log_sql
54 self.db_exists = False
54 self.db_exists = False
55 self.init_db()
55 self.init_db()
56
56
57 def init_db(self):
57 def init_db(self):
58 engine = create_engine(self.dburi, echo=self.log_sql)
58 engine = create_engine(self.dburi, echo=self.log_sql)
59 init_model(engine)
59 init_model(engine)
60 self.sa = meta.Session()
60 self.sa = meta.Session()
61
61
62 def create_tables(self, override=False):
62 def create_tables(self, override=False):
63 """Create a auth database
63 """Create a auth database
64 """
64 """
65
65
66 log.info("Any existing database is going to be destroyed")
66 log.info("Any existing database is going to be destroyed")
67 if self.tests:
67 if self.tests:
68 destroy = True
68 destroy = True
69 else:
69 else:
70 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
70 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
71 if not destroy:
71 if not destroy:
72 sys.exit()
72 sys.exit()
73 if destroy:
73 if destroy:
74 meta.Base.metadata.drop_all()
74 meta.Base.metadata.drop_all()
75
75
76 checkfirst = not override
76 checkfirst = not override
77 meta.Base.metadata.create_all(checkfirst=checkfirst)
77 meta.Base.metadata.create_all(checkfirst=checkfirst)
78 log.info('Created tables for %s', self.dbname)
78 log.info('Created tables for %s', self.dbname)
79
79
80 def set_db_version(self):
80 def set_db_version(self):
81 try:
81 try:
82 ver = DbMigrateVersion()
82 ver = DbMigrateVersion()
83 ver.version = __dbversion__
83 ver.version = __dbversion__
84 ver.repository_id = 'rhodecode_db_migrations'
84 ver.repository_id = 'rhodecode_db_migrations'
85 ver.repository_path = 'versions'
85 ver.repository_path = 'versions'
86 self.sa.add(ver)
86 self.sa.add(ver)
87 self.sa.commit()
87 self.sa.commit()
88 except:
88 except:
89 self.sa.rollback()
89 self.sa.rollback()
90 raise
90 raise
91 log.info('db version set to: %s', __dbversion__)
91 log.info('db version set to: %s', __dbversion__)
92
92
93 def upgrade(self):
93 def upgrade(self):
94 """Upgrades given database schema to given revision following
94 """Upgrades given database schema to given revision following
95 all needed steps, to perform the upgrade
95 all needed steps, to perform the upgrade
96
96
97 """
97 """
98
98
99 from rhodecode.lib.dbmigrate.migrate.versioning import api
99 from rhodecode.lib.dbmigrate.migrate.versioning import api
100 from rhodecode.lib.dbmigrate.migrate.exceptions import \
100 from rhodecode.lib.dbmigrate.migrate.exceptions import \
101 DatabaseNotControlledError
101 DatabaseNotControlledError
102
102
103 upgrade = ask_ok('You are about to perform database upgrade, make '
103 upgrade = ask_ok('You are about to perform database upgrade, make '
104 'sure You backed up your database before. '
104 'sure You backed up your database before. '
105 'Continue ? [y/n]')
105 'Continue ? [y/n]')
106 if not upgrade:
106 if not upgrade:
107 sys.exit('Nothing done')
107 sys.exit('Nothing done')
108
108
109 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
109 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
110 'rhodecode/lib/dbmigrate')
110 'rhodecode/lib/dbmigrate')
111 db_uri = self.dburi
111 db_uri = self.dburi
112
112
113 try:
113 try:
114 curr_version = api.db_version(db_uri, repository_path)
114 curr_version = api.db_version(db_uri, repository_path)
115 msg = ('Found current database under version'
115 msg = ('Found current database under version'
116 ' control with version %s' % curr_version)
116 ' control with version %s' % curr_version)
117
117
118 except (RuntimeError, DatabaseNotControlledError):
118 except (RuntimeError, DatabaseNotControlledError):
119 curr_version = 1
119 curr_version = 1
120 msg = ('Current database is not under version control. Setting'
120 msg = ('Current database is not under version control. Setting'
121 ' as version %s' % curr_version)
121 ' as version %s' % curr_version)
122 api.version_control(db_uri, repository_path, curr_version)
122 api.version_control(db_uri, repository_path, curr_version)
123
123
124 print (msg)
124 print (msg)
125
125
126 if curr_version == __dbversion__:
126 if curr_version == __dbversion__:
127 sys.exit('This database is already at the newest version')
127 sys.exit('This database is already at the newest version')
128
128
129 #======================================================================
129 #======================================================================
130 # UPGRADE STEPS
130 # UPGRADE STEPS
131 #======================================================================
131 #======================================================================
132 class UpgradeSteps(object):
132 class UpgradeSteps(object):
133 """Those steps follow schema versions so for example schema
133 """Those steps follow schema versions so for example schema
134 for example schema with seq 002 == step_2 and so on.
134 for example schema with seq 002 == step_2 and so on.
135 """
135 """
136
136
137 def __init__(self, klass):
137 def __init__(self, klass):
138 self.klass = klass
138 self.klass = klass
139
139
140 def step_0(self):
140 def step_0(self):
141 #step 0 is the schema upgrade, and than follow proper upgrades
141 #step 0 is the schema upgrade, and than follow proper upgrades
142 print ('attempting to do database upgrade to version %s' \
142 print ('attempting to do database upgrade to version %s' \
143 % __dbversion__)
143 % __dbversion__)
144 api.upgrade(db_uri, repository_path, __dbversion__)
144 api.upgrade(db_uri, repository_path, __dbversion__)
145 print ('Schema upgrade completed')
145 print ('Schema upgrade completed')
146
146
147 def step_1(self):
147 def step_1(self):
148 pass
148 pass
149
149
150 def step_2(self):
150 def step_2(self):
151 print ('Patching repo paths for newer version of RhodeCode')
151 print ('Patching repo paths for newer version of RhodeCode')
152 self.klass.fix_repo_paths()
152 self.klass.fix_repo_paths()
153
153
154 print ('Patching default user of RhodeCode')
154 print ('Patching default user of RhodeCode')
155 self.klass.fix_default_user()
155 self.klass.fix_default_user()
156
156
157 log.info('Changing ui settings')
157 log.info('Changing ui settings')
158 self.klass.create_ui_settings()
158 self.klass.create_ui_settings()
159
159
160 def step_3(self):
160 def step_3(self):
161 print ('Adding additional settings into RhodeCode db')
161 print ('Adding additional settings into RhodeCode db')
162 self.klass.fix_settings()
162 self.klass.fix_settings()
163
163 print ('Adding ldap defaults')
164 self.klass.create_ldap_options(skip_existing=True)
165
164 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
166 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
165
167
166 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
168 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
167 for step in upgrade_steps:
169 for step in upgrade_steps:
168 print ('performing upgrade step %s' % step)
170 print ('performing upgrade step %s' % step)
169 callable = getattr(UpgradeSteps(self), 'step_%s' % step)()
171 callable = getattr(UpgradeSteps(self), 'step_%s' % step)()
170
172
171 def fix_repo_paths(self):
173 def fix_repo_paths(self):
172 """Fixes a old rhodecode version path into new one without a '*'
174 """Fixes a old rhodecode version path into new one without a '*'
173 """
175 """
174
176
175 paths = self.sa.query(RhodeCodeUi)\
177 paths = self.sa.query(RhodeCodeUi)\
176 .filter(RhodeCodeUi.ui_key == '/')\
178 .filter(RhodeCodeUi.ui_key == '/')\
177 .scalar()
179 .scalar()
178
180
179 paths.ui_value = paths.ui_value.replace('*', '')
181 paths.ui_value = paths.ui_value.replace('*', '')
180
182
181 try:
183 try:
182 self.sa.add(paths)
184 self.sa.add(paths)
183 self.sa.commit()
185 self.sa.commit()
184 except:
186 except:
185 self.sa.rollback()
187 self.sa.rollback()
186 raise
188 raise
187
189
188 def fix_default_user(self):
190 def fix_default_user(self):
189 """Fixes a old default user with some 'nicer' default values,
191 """Fixes a old default user with some 'nicer' default values,
190 used mostly for anonymous access
192 used mostly for anonymous access
191 """
193 """
192 def_user = self.sa.query(User)\
194 def_user = self.sa.query(User)\
193 .filter(User.username == 'default')\
195 .filter(User.username == 'default')\
194 .one()
196 .one()
195
197
196 def_user.name = 'Anonymous'
198 def_user.name = 'Anonymous'
197 def_user.lastname = 'User'
199 def_user.lastname = 'User'
198 def_user.email = 'anonymous@rhodecode.org'
200 def_user.email = 'anonymous@rhodecode.org'
199
201
200 try:
202 try:
201 self.sa.add(def_user)
203 self.sa.add(def_user)
202 self.sa.commit()
204 self.sa.commit()
203 except:
205 except:
204 self.sa.rollback()
206 self.sa.rollback()
205 raise
207 raise
206
208
207 def fix_settings(self):
209 def fix_settings(self):
208 """Fixes rhodecode settings adds ga_code key for google analytics
210 """Fixes rhodecode settings adds ga_code key for google analytics
209 """
211 """
210
212
211 hgsettings3 = RhodeCodeSettings('ga_code', '')
213 hgsettings3 = RhodeCodeSettings('ga_code', '')
212
214
213 try:
215 try:
214 self.sa.add(hgsettings3)
216 self.sa.add(hgsettings3)
215 self.sa.commit()
217 self.sa.commit()
216 except:
218 except:
217 self.sa.rollback()
219 self.sa.rollback()
218 raise
220 raise
219
221
220 def admin_prompt(self, second=False):
222 def admin_prompt(self, second=False):
221 if not self.tests:
223 if not self.tests:
222 import getpass
224 import getpass
223
225
224 def get_password():
226 def get_password():
225 password = getpass.getpass('Specify admin password '
227 password = getpass.getpass('Specify admin password '
226 '(min 6 chars):')
228 '(min 6 chars):')
227 confirm = getpass.getpass('Confirm password:')
229 confirm = getpass.getpass('Confirm password:')
228
230
229 if password != confirm:
231 if password != confirm:
230 log.error('passwords mismatch')
232 log.error('passwords mismatch')
231 return False
233 return False
232 if len(password) < 6:
234 if len(password) < 6:
233 log.error('password is to short use at least 6 characters')
235 log.error('password is to short use at least 6 characters')
234 return False
236 return False
235
237
236 return password
238 return password
237
239
238 username = raw_input('Specify admin username:')
240 username = raw_input('Specify admin username:')
239
241
240 password = get_password()
242 password = get_password()
241 if not password:
243 if not password:
242 #second try
244 #second try
243 password = get_password()
245 password = get_password()
244 if not password:
246 if not password:
245 sys.exit()
247 sys.exit()
246
248
247 email = raw_input('Specify admin email:')
249 email = raw_input('Specify admin email:')
248 self.create_user(username, password, email, True)
250 self.create_user(username, password, email, True)
249 else:
251 else:
250 log.info('creating admin and regular test users')
252 log.info('creating admin and regular test users')
251 self.create_user('test_admin', 'test12',
253 self.create_user('test_admin', 'test12',
252 'test_admin@mail.com', True)
254 'test_admin@mail.com', True)
253 self.create_user('test_regular', 'test12',
255 self.create_user('test_regular', 'test12',
254 'test_regular@mail.com', False)
256 'test_regular@mail.com', False)
255 self.create_user('test_regular2', 'test12',
257 self.create_user('test_regular2', 'test12',
256 'test_regular2@mail.com', False)
258 'test_regular2@mail.com', False)
257
259
258 def create_ui_settings(self):
260 def create_ui_settings(self):
259 """Creates ui settings, fills out hooks
261 """Creates ui settings, fills out hooks
260 and disables dotencode
262 and disables dotencode
261
263
262 """
264 """
263 #HOOKS
265 #HOOKS
264 hooks1_key = RhodeCodeUi.HOOK_UPDATE
266 hooks1_key = RhodeCodeUi.HOOK_UPDATE
265 hooks1_ = self.sa.query(RhodeCodeUi)\
267 hooks1_ = self.sa.query(RhodeCodeUi)\
266 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
268 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
267
269
268 hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
270 hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
269 hooks1.ui_section = 'hooks'
271 hooks1.ui_section = 'hooks'
270 hooks1.ui_key = hooks1_key
272 hooks1.ui_key = hooks1_key
271 hooks1.ui_value = 'hg update >&2'
273 hooks1.ui_value = 'hg update >&2'
272 hooks1.ui_active = False
274 hooks1.ui_active = False
273
275
274 hooks2_key = RhodeCodeUi.HOOK_REPO_SIZE
276 hooks2_key = RhodeCodeUi.HOOK_REPO_SIZE
275 hooks2_ = self.sa.query(RhodeCodeUi)\
277 hooks2_ = self.sa.query(RhodeCodeUi)\
276 .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
278 .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
277
279
278 hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
280 hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
279 hooks2.ui_section = 'hooks'
281 hooks2.ui_section = 'hooks'
280 hooks2.ui_key = hooks2_key
282 hooks2.ui_key = hooks2_key
281 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
283 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
282
284
283 hooks3 = RhodeCodeUi()
285 hooks3 = RhodeCodeUi()
284 hooks3.ui_section = 'hooks'
286 hooks3.ui_section = 'hooks'
285 hooks3.ui_key = RhodeCodeUi.HOOK_PUSH
287 hooks3.ui_key = RhodeCodeUi.HOOK_PUSH
286 hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
288 hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
287
289
288 hooks4 = RhodeCodeUi()
290 hooks4 = RhodeCodeUi()
289 hooks4.ui_section = 'hooks'
291 hooks4.ui_section = 'hooks'
290 hooks4.ui_key = RhodeCodeUi.HOOK_PULL
292 hooks4.ui_key = RhodeCodeUi.HOOK_PULL
291 hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
293 hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
292
294
293 #For mercurial 1.7 set backward comapatibility with format
295 #For mercurial 1.7 set backward comapatibility with format
294 dotencode_disable = RhodeCodeUi()
296 dotencode_disable = RhodeCodeUi()
295 dotencode_disable.ui_section = 'format'
297 dotencode_disable.ui_section = 'format'
296 dotencode_disable.ui_key = 'dotencode'
298 dotencode_disable.ui_key = 'dotencode'
297 dotencode_disable.ui_value = 'false'
299 dotencode_disable.ui_value = 'false'
298
300
299 try:
301 try:
300 self.sa.add(hooks1)
302 self.sa.add(hooks1)
301 self.sa.add(hooks2)
303 self.sa.add(hooks2)
302 self.sa.add(hooks3)
304 self.sa.add(hooks3)
303 self.sa.add(hooks4)
305 self.sa.add(hooks4)
304 self.sa.add(dotencode_disable)
306 self.sa.add(dotencode_disable)
305 self.sa.commit()
307 self.sa.commit()
306 except:
308 except:
307 self.sa.rollback()
309 self.sa.rollback()
308 raise
310 raise
309
311
310 def create_ldap_options(self):
312 def create_ldap_options(self,skip_existing=False):
311 """Creates ldap settings"""
313 """Creates ldap settings"""
312
314
313 try:
315 try:
314 for k, v in [('ldap_active', 'false'), ('ldap_host', ''),
316 for k, v in [('ldap_active', 'false'), ('ldap_host', ''),
315 ('ldap_port', '389'), ('ldap_tls_kind', 'PLAIN'),
317 ('ldap_port', '389'), ('ldap_tls_kind', 'PLAIN'),
316 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''),
318 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''),
317 ('ldap_dn_pass', ''), ('ldap_base_dn', ''),
319 ('ldap_dn_pass', ''), ('ldap_base_dn', ''),
318 ('ldap_filter', ''), ('ldap_search_scope', ''),
320 ('ldap_filter', ''), ('ldap_search_scope', ''),
319 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
321 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
320 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
322 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
321
323
324 if skip_existing and RhodeCodeSettings.get_by_name(k) != None:
325 log.debug('Skipping option %s' % k)
326 continue
322 setting = RhodeCodeSettings(k, v)
327 setting = RhodeCodeSettings(k, v)
323 self.sa.add(setting)
328 self.sa.add(setting)
324 self.sa.commit()
329 self.sa.commit()
325 except:
330 except:
326 self.sa.rollback()
331 self.sa.rollback()
327 raise
332 raise
328
333
329 def config_prompt(self, test_repo_path='', retries=3):
334 def config_prompt(self, test_repo_path='', retries=3):
330 if retries == 3:
335 if retries == 3:
331 log.info('Setting up repositories config')
336 log.info('Setting up repositories config')
332
337
333 if not self.tests and not test_repo_path:
338 if not self.tests and not test_repo_path:
334 path = raw_input('Specify valid full path to your repositories'
339 path = raw_input('Specify valid full path to your repositories'
335 ' you can change this later in application settings:')
340 ' you can change this later in application settings:')
336 else:
341 else:
337 path = test_repo_path
342 path = test_repo_path
338 path_ok = True
343 path_ok = True
339
344
340 #check proper dir
345 #check proper dir
341 if not os.path.isdir(path):
346 if not os.path.isdir(path):
342 path_ok = False
347 path_ok = False
343 log.error('Given path %s is not a valid directory', path)
348 log.error('Given path %s is not a valid directory', path)
344
349
345 #check write access
350 #check write access
346 if not os.access(path, os.W_OK) and path_ok:
351 if not os.access(path, os.W_OK) and path_ok:
347 path_ok = False
352 path_ok = False
348 log.error('No write permission to given path %s', path)
353 log.error('No write permission to given path %s', path)
349
354
350
355
351 if retries == 0:
356 if retries == 0:
352 sys.exit('max retries reached')
357 sys.exit('max retries reached')
353 if path_ok is False:
358 if path_ok is False:
354 retries -= 1
359 retries -= 1
355 return self.config_prompt(test_repo_path, retries)
360 return self.config_prompt(test_repo_path, retries)
356
361
357 return path
362 return path
358
363
359 def create_settings(self, path):
364 def create_settings(self, path):
360
365
361 self.create_ui_settings()
366 self.create_ui_settings()
362
367
363 #HG UI OPTIONS
368 #HG UI OPTIONS
364 web1 = RhodeCodeUi()
369 web1 = RhodeCodeUi()
365 web1.ui_section = 'web'
370 web1.ui_section = 'web'
366 web1.ui_key = 'push_ssl'
371 web1.ui_key = 'push_ssl'
367 web1.ui_value = 'false'
372 web1.ui_value = 'false'
368
373
369 web2 = RhodeCodeUi()
374 web2 = RhodeCodeUi()
370 web2.ui_section = 'web'
375 web2.ui_section = 'web'
371 web2.ui_key = 'allow_archive'
376 web2.ui_key = 'allow_archive'
372 web2.ui_value = 'gz zip bz2'
377 web2.ui_value = 'gz zip bz2'
373
378
374 web3 = RhodeCodeUi()
379 web3 = RhodeCodeUi()
375 web3.ui_section = 'web'
380 web3.ui_section = 'web'
376 web3.ui_key = 'allow_push'
381 web3.ui_key = 'allow_push'
377 web3.ui_value = '*'
382 web3.ui_value = '*'
378
383
379 web4 = RhodeCodeUi()
384 web4 = RhodeCodeUi()
380 web4.ui_section = 'web'
385 web4.ui_section = 'web'
381 web4.ui_key = 'baseurl'
386 web4.ui_key = 'baseurl'
382 web4.ui_value = '/'
387 web4.ui_value = '/'
383
388
384 paths = RhodeCodeUi()
389 paths = RhodeCodeUi()
385 paths.ui_section = 'paths'
390 paths.ui_section = 'paths'
386 paths.ui_key = '/'
391 paths.ui_key = '/'
387 paths.ui_value = path
392 paths.ui_value = path
388
393
389 hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication')
394 hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication')
390 hgsettings2 = RhodeCodeSettings('title', 'RhodeCode')
395 hgsettings2 = RhodeCodeSettings('title', 'RhodeCode')
391 hgsettings3 = RhodeCodeSettings('ga_code', '')
396 hgsettings3 = RhodeCodeSettings('ga_code', '')
392
397
393 try:
398 try:
394 self.sa.add(web1)
399 self.sa.add(web1)
395 self.sa.add(web2)
400 self.sa.add(web2)
396 self.sa.add(web3)
401 self.sa.add(web3)
397 self.sa.add(web4)
402 self.sa.add(web4)
398 self.sa.add(paths)
403 self.sa.add(paths)
399 self.sa.add(hgsettings1)
404 self.sa.add(hgsettings1)
400 self.sa.add(hgsettings2)
405 self.sa.add(hgsettings2)
401 self.sa.add(hgsettings3)
406 self.sa.add(hgsettings3)
402
407
403 self.sa.commit()
408 self.sa.commit()
404 except:
409 except:
405 self.sa.rollback()
410 self.sa.rollback()
406 raise
411 raise
407
412
408 self.create_ldap_options()
413 self.create_ldap_options()
409
414
410 log.info('created ui config')
415 log.info('created ui config')
411
416
412 def create_user(self, username, password, email='', admin=False):
417 def create_user(self, username, password, email='', admin=False):
413 log.info('creating administrator user %s', username)
418 log.info('creating administrator user %s', username)
414
419
415 form_data = dict(username=username,
420 form_data = dict(username=username,
416 password=password,
421 password=password,
417 active=True,
422 active=True,
418 admin=admin,
423 admin=admin,
419 name='RhodeCode',
424 name='RhodeCode',
420 lastname='Admin',
425 lastname='Admin',
421 email=email)
426 email=email)
422 User.create(form_data)
427 User.create(form_data)
423
428
424
429
425 def create_default_user(self):
430 def create_default_user(self):
426 log.info('creating default user')
431 log.info('creating default user')
427 #create default user for handling default permissions.
432 #create default user for handling default permissions.
428
433
429 form_data = dict(username='default',
434 form_data = dict(username='default',
430 password=str(uuid.uuid1())[:8],
435 password=str(uuid.uuid1())[:8],
431 active=False,
436 active=False,
432 admin=False,
437 admin=False,
433 name='Anonymous',
438 name='Anonymous',
434 lastname='User',
439 lastname='User',
435 email='anonymous@rhodecode.org')
440 email='anonymous@rhodecode.org')
436 User.create(form_data)
441 User.create(form_data)
437
442
438 def create_permissions(self):
443 def create_permissions(self):
439 #module.(access|create|change|delete)_[name]
444 #module.(access|create|change|delete)_[name]
440 #module.(read|write|owner)
445 #module.(read|write|owner)
441 perms = [('repository.none', 'Repository no access'),
446 perms = [('repository.none', 'Repository no access'),
442 ('repository.read', 'Repository read access'),
447 ('repository.read', 'Repository read access'),
443 ('repository.write', 'Repository write access'),
448 ('repository.write', 'Repository write access'),
444 ('repository.admin', 'Repository admin access'),
449 ('repository.admin', 'Repository admin access'),
445 ('hg.admin', 'Hg Administrator'),
450 ('hg.admin', 'Hg Administrator'),
446 ('hg.create.repository', 'Repository create'),
451 ('hg.create.repository', 'Repository create'),
447 ('hg.create.none', 'Repository creation disabled'),
452 ('hg.create.none', 'Repository creation disabled'),
448 ('hg.register.none', 'Register disabled'),
453 ('hg.register.none', 'Register disabled'),
449 ('hg.register.manual_activate', 'Register new user with '
454 ('hg.register.manual_activate', 'Register new user with '
450 'RhodeCode without manual'
455 'RhodeCode without manual'
451 'activation'),
456 'activation'),
452
457
453 ('hg.register.auto_activate', 'Register new user with '
458 ('hg.register.auto_activate', 'Register new user with '
454 'RhodeCode without auto '
459 'RhodeCode without auto '
455 'activation'),
460 'activation'),
456 ]
461 ]
457
462
458 for p in perms:
463 for p in perms:
459 new_perm = Permission()
464 new_perm = Permission()
460 new_perm.permission_name = p[0]
465 new_perm.permission_name = p[0]
461 new_perm.permission_longname = p[1]
466 new_perm.permission_longname = p[1]
462 try:
467 try:
463 self.sa.add(new_perm)
468 self.sa.add(new_perm)
464 self.sa.commit()
469 self.sa.commit()
465 except:
470 except:
466 self.sa.rollback()
471 self.sa.rollback()
467 raise
472 raise
468
473
469 def populate_default_permissions(self):
474 def populate_default_permissions(self):
470 log.info('creating default user permissions')
475 log.info('creating default user permissions')
471
476
472 default_user = self.sa.query(User)\
477 default_user = self.sa.query(User)\
473 .filter(User.username == 'default').scalar()
478 .filter(User.username == 'default').scalar()
474
479
475 reg_perm = UserToPerm()
480 reg_perm = UserToPerm()
476 reg_perm.user = default_user
481 reg_perm.user = default_user
477 reg_perm.permission = self.sa.query(Permission)\
482 reg_perm.permission = self.sa.query(Permission)\
478 .filter(Permission.permission_name == 'hg.register.manual_activate')\
483 .filter(Permission.permission_name == 'hg.register.manual_activate')\
479 .scalar()
484 .scalar()
480
485
481 create_repo_perm = UserToPerm()
486 create_repo_perm = UserToPerm()
482 create_repo_perm.user = default_user
487 create_repo_perm.user = default_user
483 create_repo_perm.permission = self.sa.query(Permission)\
488 create_repo_perm.permission = self.sa.query(Permission)\
484 .filter(Permission.permission_name == 'hg.create.repository')\
489 .filter(Permission.permission_name == 'hg.create.repository')\
485 .scalar()
490 .scalar()
486
491
487 default_repo_perm = UserToPerm()
492 default_repo_perm = UserToPerm()
488 default_repo_perm.user = default_user
493 default_repo_perm.user = default_user
489 default_repo_perm.permission = self.sa.query(Permission)\
494 default_repo_perm.permission = self.sa.query(Permission)\
490 .filter(Permission.permission_name == 'repository.read')\
495 .filter(Permission.permission_name == 'repository.read')\
491 .scalar()
496 .scalar()
492
497
493 try:
498 try:
494 self.sa.add(reg_perm)
499 self.sa.add(reg_perm)
495 self.sa.add(create_repo_perm)
500 self.sa.add(create_repo_perm)
496 self.sa.add(default_repo_perm)
501 self.sa.add(default_repo_perm)
497 self.sa.commit()
502 self.sa.commit()
498 except:
503 except:
499 self.sa.rollback()
504 self.sa.rollback()
500 raise
505 raise
@@ -1,116 +1,119
1 import logging
1 import logging
2 import datetime
2 import datetime
3
3
4 from sqlalchemy import *
4 from sqlalchemy import *
5 from sqlalchemy.exc import DatabaseError
5 from sqlalchemy.exc import DatabaseError
6 from sqlalchemy.orm import relation, backref, class_mapper
6 from sqlalchemy.orm import relation, backref, class_mapper
7 from sqlalchemy.orm.session import Session
7 from sqlalchemy.orm.session import Session
8
8
9 from rhodecode.lib.dbmigrate.migrate import *
9 from rhodecode.lib.dbmigrate.migrate import *
10 from rhodecode.lib.dbmigrate.migrate.changeset import *
10 from rhodecode.lib.dbmigrate.migrate.changeset import *
11
11
12 from rhodecode.model.meta import Base
12 from rhodecode.model.meta import Base
13
13
14 log = logging.getLogger(__name__)
14 log = logging.getLogger(__name__)
15
15
16 def upgrade(migrate_engine):
16 def upgrade(migrate_engine):
17 """ Upgrade operations go here.
17 """ Upgrade operations go here.
18 Don't create your own engine; bind migrate_engine to your metadata
18 Don't create your own engine; bind migrate_engine to your metadata
19 """
19 """
20
20
21 #==========================================================================
21 #==========================================================================
22 # Add table `groups``
22 # Add table `groups``
23 #==========================================================================
23 #==========================================================================
24 from rhodecode.model.db import Group
24 from rhodecode.model.db import Group
25 Group().__table__.create()
25 Group().__table__.create()
26
26
27 #==========================================================================
27 #==========================================================================
28 # Add table `group_to_perm`
28 # Add table `group_to_perm`
29 #==========================================================================
29 #==========================================================================
30 from rhodecode.model.db import GroupToPerm
30 from rhodecode.model.db import GroupToPerm
31 GroupToPerm().__table__.create()
31 GroupToPerm().__table__.create()
32
32
33 #==========================================================================
33 #==========================================================================
34 # Add table `users_groups`
34 # Add table `users_groups`
35 #==========================================================================
35 #==========================================================================
36 from rhodecode.model.db import UsersGroup
36 from rhodecode.model.db import UsersGroup
37 UsersGroup().__table__.create()
37 UsersGroup().__table__.create()
38
38
39 #==========================================================================
39 #==========================================================================
40 # Add table `users_groups_members`
40 # Add table `users_groups_members`
41 #==========================================================================
41 #==========================================================================
42 from rhodecode.model.db import UsersGroupMember
42 from rhodecode.model.db import UsersGroupMember
43 UsersGroupMember().__table__.create()
43 UsersGroupMember().__table__.create()
44
44
45 #==========================================================================
45 #==========================================================================
46 # Add table `users_group_repo_to_perm`
46 # Add table `users_group_repo_to_perm`
47 #==========================================================================
47 #==========================================================================
48 from rhodecode.model.db import UsersGroupRepoToPerm
48 from rhodecode.model.db import UsersGroupRepoToPerm
49 UsersGroupRepoToPerm().__table__.create()
49 UsersGroupRepoToPerm().__table__.create()
50
50
51 #==========================================================================
51 #==========================================================================
52 # Add table `users_group_to_perm`
52 # Add table `users_group_to_perm`
53 #==========================================================================
53 #==========================================================================
54 from rhodecode.model.db import UsersGroupToPerm
54 from rhodecode.model.db import UsersGroupToPerm
55 UsersGroupToPerm().__table__.create()
55 UsersGroupToPerm().__table__.create()
56
56
57 #==========================================================================
57 #==========================================================================
58 # Upgrade of `users` table
58 # Upgrade of `users` table
59 #==========================================================================
59 #==========================================================================
60 from rhodecode.model.db import User
60 from rhodecode.model.db import User
61
61
62 #add column
62 #add column
63 ldap_dn = Column("ldap_dn", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
63 ldap_dn = Column("ldap_dn", String(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
64 ldap_dn.create(User().__table__)
64 ldap_dn.create(User().__table__)
65
65
66 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
66 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
67 api_key.create(User().__table__)
67 api_key.create(User().__table__)
68
68
69 #remove old column
69 #remove old column
70 is_ldap = Column("is_ldap", Boolean(), nullable=False, unique=None, default=False)
70 is_ldap = Column("is_ldap", Boolean(), nullable=False, unique=None, default=False)
71 is_ldap.drop(User().__table__)
71 is_ldap.drop(User().__table__)
72
72
73
73
74 #==========================================================================
74 #==========================================================================
75 # Upgrade of `repositories` table
75 # Upgrade of `repositories` table
76 #==========================================================================
76 #==========================================================================
77 from rhodecode.model.db import Repository
77 from rhodecode.model.db import Repository
78
78
79 #ADD clone_uri column#
80
81 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False,
82 assert_unicode=None),
83 nullable=True, unique=False, default=None)
84
85 clone_uri.create(Repository().__table__)
86
79 #ADD downloads column#
87 #ADD downloads column#
80 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
88 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
81 enable_downloads.create(Repository().__table__)
89 enable_downloads.create(Repository().__table__)
82
90
83 #ADD column created_on
91 #ADD column created_on
84 created_on = Column('created_on', DateTime(timezone=False), nullable=True,
92 created_on = Column('created_on', DateTime(timezone=False), nullable=True,
85 unique=None, default=datetime.datetime.now)
93 unique=None, default=datetime.datetime.now)
86 created_on.create(Repository().__table__)
94 created_on.create(Repository().__table__)
87
95
88 #ADD group_id column#
96 #ADD group_id column#
89 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'),
97 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'),
90 nullable=True, unique=False, default=None)
98 nullable=True, unique=False, default=None)
91
99
92 group_id.create(Repository().__table__)
100 group_id.create(Repository().__table__)
93
101
94
102
95 #ADD clone_uri column#
96
97 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False,
98 assert_unicode=None),
99 nullable=True, unique=False, default=None)
100
101 clone_uri.create(Repository().__table__)
102
103
104 #==========================================================================
103 #==========================================================================
105 # Upgrade of `user_followings` table
104 # Upgrade of `user_followings` table
106 #==========================================================================
105 #==========================================================================
107
106
108 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
107 from rhodecode.model.db import UserFollowing
109 follows_from.create(Repository().__table__)
108
109 follows_from = Column('follows_from', DateTime(timezone=False),
110 nullable=True, unique=None,
111 default=datetime.datetime.now)
112 follows_from.create(UserFollowing().__table__)
110
113
111 return
114 return
112
115
113
116
114 def downgrade(migrate_engine):
117 def downgrade(migrate_engine):
115 meta = MetaData()
118 meta = MetaData()
116 meta.bind = migrate_engine
119 meta.bind = migrate_engine
@@ -1,124 +1,125
1 import sys
1 import sys
2 from rhodecode import get_version
2 from rhodecode import get_version
3 from rhodecode import __platform__
3 from rhodecode import __platform__
4 from rhodecode import __license__
4 from rhodecode import __license__
5 from rhodecode import PLATFORM_OTHERS
5 from rhodecode import PLATFORM_OTHERS
6
6
7 py_version = sys.version_info
7 py_version = sys.version_info
8
8
9 if py_version < (2, 5):
9 if py_version < (2, 5):
10 raise Exception('RhodeCode requires python 2.5 or later')
10 raise Exception('RhodeCode requires python 2.5 or later')
11
11
12 requirements = [
12 requirements = [
13 "Pylons==1.0.0",
13 "Pylons==1.0.0",
14 "WebHelpers>=1.2",
14 "WebHelpers>=1.2",
15 "formencode==1.2.4",
15 "SQLAlchemy>=0.7.2,<0.8",
16 "SQLAlchemy>=0.7.2,<0.8",
16 "Mako>=0.4.2",
17 "Mako>=0.4.2",
17 "pygments>=1.4",
18 "pygments>=1.4",
18 "mercurial>=1.9,<2.0",
19 "mercurial>=1.9,<2.0",
19 "whoosh<1.8",
20 "whoosh<1.8",
20 "celery>=2.2.5,<2.3",
21 "celery>=2.2.5,<2.3",
21 "babel",
22 "babel",
22 "python-dateutil>=1.5.0,<2.0.0",
23 "python-dateutil>=1.5.0,<2.0.0",
23 "dulwich>=0.8.0",
24 "dulwich>=0.8.0",
24 "vcs>=0.2.1.dev",
25 "vcs>=0.2.1.dev",
25 "webob==1.0.8"
26 "webob==1.0.8"
26 ]
27 ]
27
28
28 dependency_links = [
29 dependency_links = [
29 "https://secure.rhodecode.org/vcs/archive/default.zip#egg=vcs-0.2.1.dev",
30 "https://secure.rhodecode.org/vcs/archive/default.zip#egg=vcs-0.2.1.dev",
30 "https://bitbucket.org/marcinkuzminski/vcs/get/default.zip#egg=vcs-0.2.1.dev",
31 "https://bitbucket.org/marcinkuzminski/vcs/get/default.zip#egg=vcs-0.2.1.dev",
31 ]
32 ]
32
33
33 classifiers = ['Development Status :: 4 - Beta',
34 classifiers = ['Development Status :: 4 - Beta',
34 'Environment :: Web Environment',
35 'Environment :: Web Environment',
35 'Framework :: Pylons',
36 'Framework :: Pylons',
36 'Intended Audience :: Developers',
37 'Intended Audience :: Developers',
37 'Operating System :: OS Independent',
38 'Operating System :: OS Independent',
38 'Programming Language :: Python',
39 'Programming Language :: Python',
39 'Programming Language :: Python :: 2.5',
40 'Programming Language :: Python :: 2.5',
40 'Programming Language :: Python :: 2.6',
41 'Programming Language :: Python :: 2.6',
41 'Programming Language :: Python :: 2.7', ]
42 'Programming Language :: Python :: 2.7', ]
42
43
43 if py_version < (2, 6):
44 if py_version < (2, 6):
44 requirements.append("simplejson")
45 requirements.append("simplejson")
45 requirements.append("pysqlite")
46 requirements.append("pysqlite")
46
47
47 if __platform__ in PLATFORM_OTHERS:
48 if __platform__ in PLATFORM_OTHERS:
48 requirements.append("py-bcrypt")
49 requirements.append("py-bcrypt")
49
50
50
51
51 #additional files from project that goes somewhere in the filesystem
52 #additional files from project that goes somewhere in the filesystem
52 #relative to sys.prefix
53 #relative to sys.prefix
53 data_files = []
54 data_files = []
54
55
55 #additional files that goes into package itself
56 #additional files that goes into package itself
56 package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], }
57 package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], }
57
58
58 description = ('Mercurial repository browser/management with '
59 description = ('Mercurial repository browser/management with '
59 'build in push/pull server and full text search')
60 'build in push/pull server and full text search')
60 keywords = ' '.join(['rhodecode', 'rhodiumcode', 'mercurial', 'git',
61 keywords = ' '.join(['rhodecode', 'rhodiumcode', 'mercurial', 'git',
61 'repository management', 'hgweb replacement'
62 'repository management', 'hgweb replacement'
62 'hgwebdir', 'gitweb replacement', 'serving hgweb', ])
63 'hgwebdir', 'gitweb replacement', 'serving hgweb', ])
63 #long description
64 #long description
64 try:
65 try:
65 readme_file = 'README.rst'
66 readme_file = 'README.rst'
66 changelog_file = 'docs/changelog.rst'
67 changelog_file = 'docs/changelog.rst'
67 long_description = open(readme_file).read() + '\n\n' + \
68 long_description = open(readme_file).read() + '\n\n' + \
68 open(changelog_file).read()
69 open(changelog_file).read()
69
70
70 except IOError, err:
71 except IOError, err:
71 sys.stderr.write("[WARNING] Cannot find file specified as "
72 sys.stderr.write("[WARNING] Cannot find file specified as "
72 "long_description (%s)\n or changelog (%s) skipping that file" \
73 "long_description (%s)\n or changelog (%s) skipping that file" \
73 % (readme_file, changelog_file))
74 % (readme_file, changelog_file))
74 long_description = description
75 long_description = description
75
76
76
77
77 try:
78 try:
78 from setuptools import setup, find_packages
79 from setuptools import setup, find_packages
79 except ImportError:
80 except ImportError:
80 from ez_setup import use_setuptools
81 from ez_setup import use_setuptools
81 use_setuptools()
82 use_setuptools()
82 from setuptools import setup, find_packages
83 from setuptools import setup, find_packages
83 #packages
84 #packages
84 packages = find_packages(exclude=['ez_setup'])
85 packages = find_packages(exclude=['ez_setup'])
85
86
86 setup(
87 setup(
87 name='RhodeCode',
88 name='RhodeCode',
88 version=get_version(),
89 version=get_version(),
89 description=description,
90 description=description,
90 long_description=long_description,
91 long_description=long_description,
91 keywords=keywords,
92 keywords=keywords,
92 license=__license__,
93 license=__license__,
93 author='Marcin Kuzminski',
94 author='Marcin Kuzminski',
94 author_email='marcin@python-works.com',
95 author_email='marcin@python-works.com',
95 dependency_links=dependency_links,
96 dependency_links=dependency_links,
96 url='http://rhodecode.org',
97 url='http://rhodecode.org',
97 install_requires=requirements,
98 install_requires=requirements,
98 classifiers=classifiers,
99 classifiers=classifiers,
99 setup_requires=["PasteScript>=1.6.3"],
100 setup_requires=["PasteScript>=1.6.3"],
100 data_files=data_files,
101 data_files=data_files,
101 packages=packages,
102 packages=packages,
102 include_package_data=True,
103 include_package_data=True,
103 test_suite='nose.collector',
104 test_suite='nose.collector',
104 package_data=package_data,
105 package_data=package_data,
105 message_extractors={'rhodecode': [
106 message_extractors={'rhodecode': [
106 ('**.py', 'python', None),
107 ('**.py', 'python', None),
107 ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
108 ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
108 ('templates/**.html', 'mako', {'input_encoding': 'utf-8'}),
109 ('templates/**.html', 'mako', {'input_encoding': 'utf-8'}),
109 ('public/**', 'ignore', None)]},
110 ('public/**', 'ignore', None)]},
110 zip_safe=False,
111 zip_safe=False,
111 paster_plugins=['PasteScript', 'Pylons'],
112 paster_plugins=['PasteScript', 'Pylons'],
112 entry_points="""
113 entry_points="""
113 [paste.app_factory]
114 [paste.app_factory]
114 main = rhodecode.config.middleware:make_app
115 main = rhodecode.config.middleware:make_app
115
116
116 [paste.app_install]
117 [paste.app_install]
117 main = pylons.util:PylonsInstaller
118 main = pylons.util:PylonsInstaller
118
119
119 [paste.global_paster_command]
120 [paste.global_paster_command]
120 make-index = rhodecode.lib.indexers:MakeIndex
121 make-index = rhodecode.lib.indexers:MakeIndex
121 upgrade-db = rhodecode.lib.dbmigrate:UpgradeDb
122 upgrade-db = rhodecode.lib.dbmigrate:UpgradeDb
122 celeryd=rhodecode.lib.celerypylons.commands:CeleryDaemonCommand
123 celeryd=rhodecode.lib.celerypylons.commands:CeleryDaemonCommand
123 """,
124 """,
124 )
125 )
General Comments 0
You need to be logged in to leave comments. Login now