##// END OF EJS Templates
paster: fix redundant question on writable dir. The question needs to...
marcink -
r270:2b3a0761 default
parent child Browse files
Show More
@@ -1,597 +1,597 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Database creation, and setup module for RhodeCode Enterprise. Used for creation
22 Database creation, and setup module for RhodeCode Enterprise. Used for creation
23 of database as well as for migration operations
23 of database as well as for migration operations
24 """
24 """
25
25
26 import os
26 import os
27 import sys
27 import sys
28 import time
28 import time
29 import uuid
29 import uuid
30 import logging
30 import logging
31 import getpass
31 import getpass
32 from os.path import dirname as dn, join as jn
32 from os.path import dirname as dn, join as jn
33
33
34 from sqlalchemy.engine import create_engine
34 from sqlalchemy.engine import create_engine
35
35
36 from rhodecode import __dbversion__
36 from rhodecode import __dbversion__
37 from rhodecode.model import init_model
37 from rhodecode.model import init_model
38 from rhodecode.model.user import UserModel
38 from rhodecode.model.user import UserModel
39 from rhodecode.model.db import (
39 from rhodecode.model.db import (
40 User, Permission, RhodeCodeUi, RhodeCodeSetting, UserToPerm,
40 User, Permission, RhodeCodeUi, RhodeCodeSetting, UserToPerm,
41 DbMigrateVersion, RepoGroup, UserRepoGroupToPerm, CacheKey, Repository)
41 DbMigrateVersion, RepoGroup, UserRepoGroupToPerm, CacheKey, Repository)
42 from rhodecode.model.meta import Session, Base
42 from rhodecode.model.meta import Session, Base
43 from rhodecode.model.permission import PermissionModel
43 from rhodecode.model.permission import PermissionModel
44 from rhodecode.model.repo import RepoModel
44 from rhodecode.model.repo import RepoModel
45 from rhodecode.model.repo_group import RepoGroupModel
45 from rhodecode.model.repo_group import RepoGroupModel
46 from rhodecode.model.settings import SettingsModel
46 from rhodecode.model.settings import SettingsModel
47
47
48
48
49 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
50
50
51
51
52 def notify(msg):
52 def notify(msg):
53 """
53 """
54 Notification for migrations messages
54 Notification for migrations messages
55 """
55 """
56 ml = len(msg) + (4 * 2)
56 ml = len(msg) + (4 * 2)
57 print('\n%s\n*** %s ***\n%s' % ('*' * ml, msg, '*' * ml)).upper()
57 print('\n%s\n*** %s ***\n%s' % ('*' * ml, msg, '*' * ml)).upper()
58
58
59
59
60 class DbManage(object):
60 class DbManage(object):
61
61
62 def __init__(self, log_sql, dbconf, root, tests=False,
62 def __init__(self, log_sql, dbconf, root, tests=False,
63 SESSION=None, cli_args={}):
63 SESSION=None, cli_args={}):
64 self.dbname = dbconf.split('/')[-1]
64 self.dbname = dbconf.split('/')[-1]
65 self.tests = tests
65 self.tests = tests
66 self.root = root
66 self.root = root
67 self.dburi = dbconf
67 self.dburi = dbconf
68 self.log_sql = log_sql
68 self.log_sql = log_sql
69 self.db_exists = False
69 self.db_exists = False
70 self.cli_args = cli_args
70 self.cli_args = cli_args
71 self.init_db(SESSION=SESSION)
71 self.init_db(SESSION=SESSION)
72 self.ask_ok = self.get_ask_ok_func(self.cli_args.get('force_ask'))
72 self.ask_ok = self.get_ask_ok_func(self.cli_args.get('force_ask'))
73
73
74 def get_ask_ok_func(self, param):
74 def get_ask_ok_func(self, param):
75 if param not in [None]:
75 if param not in [None]:
76 # return a function lambda that has a default set to param
76 # return a function lambda that has a default set to param
77 return lambda *args, **kwargs: param
77 return lambda *args, **kwargs: param
78 else:
78 else:
79 from rhodecode.lib.utils import ask_ok
79 from rhodecode.lib.utils import ask_ok
80 return ask_ok
80 return ask_ok
81
81
82 def init_db(self, SESSION=None):
82 def init_db(self, SESSION=None):
83 if SESSION:
83 if SESSION:
84 self.sa = SESSION
84 self.sa = SESSION
85 else:
85 else:
86 # init new sessions
86 # init new sessions
87 engine = create_engine(self.dburi, echo=self.log_sql)
87 engine = create_engine(self.dburi, echo=self.log_sql)
88 init_model(engine)
88 init_model(engine)
89 self.sa = Session()
89 self.sa = Session()
90
90
91 def create_tables(self, override=False):
91 def create_tables(self, override=False):
92 """
92 """
93 Create a auth database
93 Create a auth database
94 """
94 """
95
95
96 log.info("Existing database with the same name is going to be destroyed.")
96 log.info("Existing database with the same name is going to be destroyed.")
97 log.info("Setup command will run DROP ALL command on that database.")
97 log.info("Setup command will run DROP ALL command on that database.")
98 if self.tests:
98 if self.tests:
99 destroy = True
99 destroy = True
100 else:
100 else:
101 destroy = self.ask_ok('Are you sure that you want to destroy the old database? [y/n]')
101 destroy = self.ask_ok('Are you sure that you want to destroy the old database? [y/n]')
102 if not destroy:
102 if not destroy:
103 log.info('Nothing done.')
103 log.info('Nothing done.')
104 sys.exit(0)
104 sys.exit(0)
105 if destroy:
105 if destroy:
106 Base.metadata.drop_all()
106 Base.metadata.drop_all()
107
107
108 checkfirst = not override
108 checkfirst = not override
109 Base.metadata.create_all(checkfirst=checkfirst)
109 Base.metadata.create_all(checkfirst=checkfirst)
110 log.info('Created tables for %s' % self.dbname)
110 log.info('Created tables for %s' % self.dbname)
111
111
112 def set_db_version(self):
112 def set_db_version(self):
113 ver = DbMigrateVersion()
113 ver = DbMigrateVersion()
114 ver.version = __dbversion__
114 ver.version = __dbversion__
115 ver.repository_id = 'rhodecode_db_migrations'
115 ver.repository_id = 'rhodecode_db_migrations'
116 ver.repository_path = 'versions'
116 ver.repository_path = 'versions'
117 self.sa.add(ver)
117 self.sa.add(ver)
118 log.info('db version set to: %s' % __dbversion__)
118 log.info('db version set to: %s' % __dbversion__)
119
119
120 def run_pre_migration_tasks(self):
120 def run_pre_migration_tasks(self):
121 """
121 """
122 Run various tasks before actually doing migrations
122 Run various tasks before actually doing migrations
123 """
123 """
124 # delete cache keys on each upgrade
124 # delete cache keys on each upgrade
125 total = CacheKey.query().count()
125 total = CacheKey.query().count()
126 log.info("Deleting (%s) cache keys now...", total)
126 log.info("Deleting (%s) cache keys now...", total)
127 CacheKey.delete_all_cache()
127 CacheKey.delete_all_cache()
128
128
129 def upgrade(self):
129 def upgrade(self):
130 """
130 """
131 Upgrades given database schema to given revision following
131 Upgrades given database schema to given revision following
132 all needed steps, to perform the upgrade
132 all needed steps, to perform the upgrade
133
133
134 """
134 """
135
135
136 from rhodecode.lib.dbmigrate.migrate.versioning import api
136 from rhodecode.lib.dbmigrate.migrate.versioning import api
137 from rhodecode.lib.dbmigrate.migrate.exceptions import \
137 from rhodecode.lib.dbmigrate.migrate.exceptions import \
138 DatabaseNotControlledError
138 DatabaseNotControlledError
139
139
140 if 'sqlite' in self.dburi:
140 if 'sqlite' in self.dburi:
141 print (
141 print (
142 '********************** WARNING **********************\n'
142 '********************** WARNING **********************\n'
143 'Make sure your version of sqlite is at least 3.7.X. \n'
143 'Make sure your version of sqlite is at least 3.7.X. \n'
144 'Earlier versions are known to fail on some migrations\n'
144 'Earlier versions are known to fail on some migrations\n'
145 '*****************************************************\n')
145 '*****************************************************\n')
146
146
147 upgrade = self.ask_ok(
147 upgrade = self.ask_ok(
148 'You are about to perform a database upgrade. Make '
148 'You are about to perform a database upgrade. Make '
149 'sure you have backed up your database. '
149 'sure you have backed up your database. '
150 'Continue ? [y/n]')
150 'Continue ? [y/n]')
151 if not upgrade:
151 if not upgrade:
152 log.info('No upgrade performed')
152 log.info('No upgrade performed')
153 sys.exit(0)
153 sys.exit(0)
154
154
155 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
155 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
156 'rhodecode/lib/dbmigrate')
156 'rhodecode/lib/dbmigrate')
157 db_uri = self.dburi
157 db_uri = self.dburi
158
158
159 try:
159 try:
160 curr_version = api.db_version(db_uri, repository_path)
160 curr_version = api.db_version(db_uri, repository_path)
161 msg = ('Found current database under version '
161 msg = ('Found current database under version '
162 'control with version %s' % curr_version)
162 'control with version %s' % curr_version)
163
163
164 except (RuntimeError, DatabaseNotControlledError):
164 except (RuntimeError, DatabaseNotControlledError):
165 curr_version = 1
165 curr_version = 1
166 msg = ('Current database is not under version control. Setting '
166 msg = ('Current database is not under version control. Setting '
167 'as version %s' % curr_version)
167 'as version %s' % curr_version)
168 api.version_control(db_uri, repository_path, curr_version)
168 api.version_control(db_uri, repository_path, curr_version)
169
169
170 notify(msg)
170 notify(msg)
171
171
172 self.run_pre_migration_tasks()
172 self.run_pre_migration_tasks()
173
173
174 if curr_version == __dbversion__:
174 if curr_version == __dbversion__:
175 log.info('This database is already at the newest version')
175 log.info('This database is already at the newest version')
176 sys.exit(0)
176 sys.exit(0)
177
177
178 upgrade_steps = range(curr_version + 1, __dbversion__ + 1)
178 upgrade_steps = range(curr_version + 1, __dbversion__ + 1)
179 notify('attempting to upgrade database from '
179 notify('attempting to upgrade database from '
180 'version %s to version %s' % (curr_version, __dbversion__))
180 'version %s to version %s' % (curr_version, __dbversion__))
181
181
182 # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
182 # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
183 _step = None
183 _step = None
184 for step in upgrade_steps:
184 for step in upgrade_steps:
185 notify('performing upgrade step %s' % step)
185 notify('performing upgrade step %s' % step)
186 time.sleep(0.5)
186 time.sleep(0.5)
187
187
188 api.upgrade(db_uri, repository_path, step)
188 api.upgrade(db_uri, repository_path, step)
189 self.sa.rollback()
189 self.sa.rollback()
190 notify('schema upgrade for step %s completed' % (step,))
190 notify('schema upgrade for step %s completed' % (step,))
191
191
192 _step = step
192 _step = step
193
193
194 notify('upgrade to version %s successful' % _step)
194 notify('upgrade to version %s successful' % _step)
195
195
196 def fix_repo_paths(self):
196 def fix_repo_paths(self):
197 """
197 """
198 Fixes an old RhodeCode version path into new one without a '*'
198 Fixes an old RhodeCode version path into new one without a '*'
199 """
199 """
200
200
201 paths = self.sa.query(RhodeCodeUi)\
201 paths = self.sa.query(RhodeCodeUi)\
202 .filter(RhodeCodeUi.ui_key == '/')\
202 .filter(RhodeCodeUi.ui_key == '/')\
203 .scalar()
203 .scalar()
204
204
205 paths.ui_value = paths.ui_value.replace('*', '')
205 paths.ui_value = paths.ui_value.replace('*', '')
206
206
207 try:
207 try:
208 self.sa.add(paths)
208 self.sa.add(paths)
209 self.sa.commit()
209 self.sa.commit()
210 except Exception:
210 except Exception:
211 self.sa.rollback()
211 self.sa.rollback()
212 raise
212 raise
213
213
214 def fix_default_user(self):
214 def fix_default_user(self):
215 """
215 """
216 Fixes an old default user with some 'nicer' default values,
216 Fixes an old default user with some 'nicer' default values,
217 used mostly for anonymous access
217 used mostly for anonymous access
218 """
218 """
219 def_user = self.sa.query(User)\
219 def_user = self.sa.query(User)\
220 .filter(User.username == User.DEFAULT_USER)\
220 .filter(User.username == User.DEFAULT_USER)\
221 .one()
221 .one()
222
222
223 def_user.name = 'Anonymous'
223 def_user.name = 'Anonymous'
224 def_user.lastname = 'User'
224 def_user.lastname = 'User'
225 def_user.email = User.DEFAULT_USER_EMAIL
225 def_user.email = User.DEFAULT_USER_EMAIL
226
226
227 try:
227 try:
228 self.sa.add(def_user)
228 self.sa.add(def_user)
229 self.sa.commit()
229 self.sa.commit()
230 except Exception:
230 except Exception:
231 self.sa.rollback()
231 self.sa.rollback()
232 raise
232 raise
233
233
234 def fix_settings(self):
234 def fix_settings(self):
235 """
235 """
236 Fixes rhodecode settings and adds ga_code key for google analytics
236 Fixes rhodecode settings and adds ga_code key for google analytics
237 """
237 """
238
238
239 hgsettings3 = RhodeCodeSetting('ga_code', '')
239 hgsettings3 = RhodeCodeSetting('ga_code', '')
240
240
241 try:
241 try:
242 self.sa.add(hgsettings3)
242 self.sa.add(hgsettings3)
243 self.sa.commit()
243 self.sa.commit()
244 except Exception:
244 except Exception:
245 self.sa.rollback()
245 self.sa.rollback()
246 raise
246 raise
247
247
248 def create_admin_and_prompt(self):
248 def create_admin_and_prompt(self):
249
249
250 # defaults
250 # defaults
251 defaults = self.cli_args
251 defaults = self.cli_args
252 username = defaults.get('username')
252 username = defaults.get('username')
253 password = defaults.get('password')
253 password = defaults.get('password')
254 email = defaults.get('email')
254 email = defaults.get('email')
255
255
256 if username is None:
256 if username is None:
257 username = raw_input('Specify admin username:')
257 username = raw_input('Specify admin username:')
258 if password is None:
258 if password is None:
259 password = self._get_admin_password()
259 password = self._get_admin_password()
260 if not password:
260 if not password:
261 # second try
261 # second try
262 password = self._get_admin_password()
262 password = self._get_admin_password()
263 if not password:
263 if not password:
264 sys.exit()
264 sys.exit()
265 if email is None:
265 if email is None:
266 email = raw_input('Specify admin email:')
266 email = raw_input('Specify admin email:')
267 api_key = self.cli_args.get('api_key')
267 api_key = self.cli_args.get('api_key')
268 self.create_user(username, password, email, True,
268 self.create_user(username, password, email, True,
269 strict_creation_check=False,
269 strict_creation_check=False,
270 api_key=api_key)
270 api_key=api_key)
271
271
272 def _get_admin_password(self):
272 def _get_admin_password(self):
273 password = getpass.getpass('Specify admin password '
273 password = getpass.getpass('Specify admin password '
274 '(min 6 chars):')
274 '(min 6 chars):')
275 confirm = getpass.getpass('Confirm password:')
275 confirm = getpass.getpass('Confirm password:')
276
276
277 if password != confirm:
277 if password != confirm:
278 log.error('passwords mismatch')
278 log.error('passwords mismatch')
279 return False
279 return False
280 if len(password) < 6:
280 if len(password) < 6:
281 log.error('password is too short - use at least 6 characters')
281 log.error('password is too short - use at least 6 characters')
282 return False
282 return False
283
283
284 return password
284 return password
285
285
286 def create_test_admin_and_users(self):
286 def create_test_admin_and_users(self):
287 log.info('creating admin and regular test users')
287 log.info('creating admin and regular test users')
288 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \
288 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, \
289 TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \
289 TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \
290 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \
290 TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, \
291 TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \
291 TEST_USER_REGULAR_EMAIL, TEST_USER_REGULAR2_LOGIN, \
292 TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL
292 TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL
293
293
294 self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,
294 self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS,
295 TEST_USER_ADMIN_EMAIL, True)
295 TEST_USER_ADMIN_EMAIL, True)
296
296
297 self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
297 self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS,
298 TEST_USER_REGULAR_EMAIL, False)
298 TEST_USER_REGULAR_EMAIL, False)
299
299
300 self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS,
300 self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS,
301 TEST_USER_REGULAR2_EMAIL, False)
301 TEST_USER_REGULAR2_EMAIL, False)
302
302
303 def create_ui_settings(self, repo_store_path):
303 def create_ui_settings(self, repo_store_path):
304 """
304 """
305 Creates ui settings, fills out hooks
305 Creates ui settings, fills out hooks
306 and disables dotencode
306 and disables dotencode
307 """
307 """
308 settings_model = SettingsModel(sa=self.sa)
308 settings_model = SettingsModel(sa=self.sa)
309
309
310 # Build HOOKS
310 # Build HOOKS
311 hooks = [
311 hooks = [
312 (RhodeCodeUi.HOOK_REPO_SIZE, 'python:vcsserver.hooks.repo_size'),
312 (RhodeCodeUi.HOOK_REPO_SIZE, 'python:vcsserver.hooks.repo_size'),
313
313
314 # HG
314 # HG
315 (RhodeCodeUi.HOOK_PRE_PULL, 'python:vcsserver.hooks.pre_pull'),
315 (RhodeCodeUi.HOOK_PRE_PULL, 'python:vcsserver.hooks.pre_pull'),
316 (RhodeCodeUi.HOOK_PULL, 'python:vcsserver.hooks.log_pull_action'),
316 (RhodeCodeUi.HOOK_PULL, 'python:vcsserver.hooks.log_pull_action'),
317 (RhodeCodeUi.HOOK_PRE_PUSH, 'python:vcsserver.hooks.pre_push'),
317 (RhodeCodeUi.HOOK_PRE_PUSH, 'python:vcsserver.hooks.pre_push'),
318 (RhodeCodeUi.HOOK_PUSH, 'python:vcsserver.hooks.log_push_action'),
318 (RhodeCodeUi.HOOK_PUSH, 'python:vcsserver.hooks.log_push_action'),
319
319
320 ]
320 ]
321
321
322 for key, value in hooks:
322 for key, value in hooks:
323 hook_obj = settings_model.get_ui_by_key(key)
323 hook_obj = settings_model.get_ui_by_key(key)
324 hooks2 = hook_obj if hook_obj else RhodeCodeUi()
324 hooks2 = hook_obj if hook_obj else RhodeCodeUi()
325 hooks2.ui_section = 'hooks'
325 hooks2.ui_section = 'hooks'
326 hooks2.ui_key = key
326 hooks2.ui_key = key
327 hooks2.ui_value = value
327 hooks2.ui_value = value
328 self.sa.add(hooks2)
328 self.sa.add(hooks2)
329
329
330 # enable largefiles
330 # enable largefiles
331 largefiles = RhodeCodeUi()
331 largefiles = RhodeCodeUi()
332 largefiles.ui_section = 'extensions'
332 largefiles.ui_section = 'extensions'
333 largefiles.ui_key = 'largefiles'
333 largefiles.ui_key = 'largefiles'
334 largefiles.ui_value = ''
334 largefiles.ui_value = ''
335 self.sa.add(largefiles)
335 self.sa.add(largefiles)
336
336
337 # set default largefiles cache dir, defaults to
337 # set default largefiles cache dir, defaults to
338 # /repo location/.cache/largefiles
338 # /repo location/.cache/largefiles
339 largefiles = RhodeCodeUi()
339 largefiles = RhodeCodeUi()
340 largefiles.ui_section = 'largefiles'
340 largefiles.ui_section = 'largefiles'
341 largefiles.ui_key = 'usercache'
341 largefiles.ui_key = 'usercache'
342 largefiles.ui_value = os.path.join(repo_store_path, '.cache',
342 largefiles.ui_value = os.path.join(repo_store_path, '.cache',
343 'largefiles')
343 'largefiles')
344 self.sa.add(largefiles)
344 self.sa.add(largefiles)
345
345
346 # enable hgsubversion disabled by default
346 # enable hgsubversion disabled by default
347 hgsubversion = RhodeCodeUi()
347 hgsubversion = RhodeCodeUi()
348 hgsubversion.ui_section = 'extensions'
348 hgsubversion.ui_section = 'extensions'
349 hgsubversion.ui_key = 'hgsubversion'
349 hgsubversion.ui_key = 'hgsubversion'
350 hgsubversion.ui_value = ''
350 hgsubversion.ui_value = ''
351 hgsubversion.ui_active = False
351 hgsubversion.ui_active = False
352 self.sa.add(hgsubversion)
352 self.sa.add(hgsubversion)
353
353
354 # enable hggit disabled by default
354 # enable hggit disabled by default
355 hggit = RhodeCodeUi()
355 hggit = RhodeCodeUi()
356 hggit.ui_section = 'extensions'
356 hggit.ui_section = 'extensions'
357 hggit.ui_key = 'hggit'
357 hggit.ui_key = 'hggit'
358 hggit.ui_value = ''
358 hggit.ui_value = ''
359 hggit.ui_active = False
359 hggit.ui_active = False
360 self.sa.add(hggit)
360 self.sa.add(hggit)
361
361
362 # set svn branch defaults
362 # set svn branch defaults
363 branches = ["/branches/*", "/trunk"]
363 branches = ["/branches/*", "/trunk"]
364 tags = ["/tags/*"]
364 tags = ["/tags/*"]
365
365
366 for branch in branches:
366 for branch in branches:
367 settings_model.create_ui_section_value(
367 settings_model.create_ui_section_value(
368 RhodeCodeUi.SVN_BRANCH_ID, branch)
368 RhodeCodeUi.SVN_BRANCH_ID, branch)
369
369
370 for tag in tags:
370 for tag in tags:
371 settings_model.create_ui_section_value(RhodeCodeUi.SVN_TAG_ID, tag)
371 settings_model.create_ui_section_value(RhodeCodeUi.SVN_TAG_ID, tag)
372
372
373 def create_auth_plugin_options(self, skip_existing=False):
373 def create_auth_plugin_options(self, skip_existing=False):
374 """
374 """
375 Create default auth plugin settings, and make it active
375 Create default auth plugin settings, and make it active
376
376
377 :param skip_existing:
377 :param skip_existing:
378 """
378 """
379
379
380 for k, v, t in [('auth_plugins', 'egg:rhodecode-enterprise-ce#rhodecode', 'list'),
380 for k, v, t in [('auth_plugins', 'egg:rhodecode-enterprise-ce#rhodecode', 'list'),
381 ('auth_rhodecode_enabled', 'True', 'bool')]:
381 ('auth_rhodecode_enabled', 'True', 'bool')]:
382 if (skip_existing and
382 if (skip_existing and
383 SettingsModel().get_setting_by_name(k) is not None):
383 SettingsModel().get_setting_by_name(k) is not None):
384 log.debug('Skipping option %s' % k)
384 log.debug('Skipping option %s' % k)
385 continue
385 continue
386 setting = RhodeCodeSetting(k, v, t)
386 setting = RhodeCodeSetting(k, v, t)
387 self.sa.add(setting)
387 self.sa.add(setting)
388
388
389 def create_default_options(self, skip_existing=False):
389 def create_default_options(self, skip_existing=False):
390 """Creates default settings"""
390 """Creates default settings"""
391
391
392 for k, v, t in [
392 for k, v, t in [
393 ('default_repo_enable_locking', False, 'bool'),
393 ('default_repo_enable_locking', False, 'bool'),
394 ('default_repo_enable_downloads', False, 'bool'),
394 ('default_repo_enable_downloads', False, 'bool'),
395 ('default_repo_enable_statistics', False, 'bool'),
395 ('default_repo_enable_statistics', False, 'bool'),
396 ('default_repo_private', False, 'bool'),
396 ('default_repo_private', False, 'bool'),
397 ('default_repo_type', 'hg', 'unicode')]:
397 ('default_repo_type', 'hg', 'unicode')]:
398
398
399 if (skip_existing and
399 if (skip_existing and
400 SettingsModel().get_setting_by_name(k) is not None):
400 SettingsModel().get_setting_by_name(k) is not None):
401 log.debug('Skipping option %s' % k)
401 log.debug('Skipping option %s' % k)
402 continue
402 continue
403 setting = RhodeCodeSetting(k, v, t)
403 setting = RhodeCodeSetting(k, v, t)
404 self.sa.add(setting)
404 self.sa.add(setting)
405
405
406 def fixup_groups(self):
406 def fixup_groups(self):
407 def_usr = User.get_default_user()
407 def_usr = User.get_default_user()
408 for g in RepoGroup.query().all():
408 for g in RepoGroup.query().all():
409 g.group_name = g.get_new_name(g.name)
409 g.group_name = g.get_new_name(g.name)
410 self.sa.add(g)
410 self.sa.add(g)
411 # get default perm
411 # get default perm
412 default = UserRepoGroupToPerm.query()\
412 default = UserRepoGroupToPerm.query()\
413 .filter(UserRepoGroupToPerm.group == g)\
413 .filter(UserRepoGroupToPerm.group == g)\
414 .filter(UserRepoGroupToPerm.user == def_usr)\
414 .filter(UserRepoGroupToPerm.user == def_usr)\
415 .scalar()
415 .scalar()
416
416
417 if default is None:
417 if default is None:
418 log.debug('missing default permission for group %s adding' % g)
418 log.debug('missing default permission for group %s adding' % g)
419 perm_obj = RepoGroupModel()._create_default_perms(g)
419 perm_obj = RepoGroupModel()._create_default_perms(g)
420 self.sa.add(perm_obj)
420 self.sa.add(perm_obj)
421
421
422 def reset_permissions(self, username):
422 def reset_permissions(self, username):
423 """
423 """
424 Resets permissions to default state, useful when old systems had
424 Resets permissions to default state, useful when old systems had
425 bad permissions, we must clean them up
425 bad permissions, we must clean them up
426
426
427 :param username:
427 :param username:
428 """
428 """
429 default_user = User.get_by_username(username)
429 default_user = User.get_by_username(username)
430 if not default_user:
430 if not default_user:
431 return
431 return
432
432
433 u2p = UserToPerm.query()\
433 u2p = UserToPerm.query()\
434 .filter(UserToPerm.user == default_user).all()
434 .filter(UserToPerm.user == default_user).all()
435 fixed = False
435 fixed = False
436 if len(u2p) != len(Permission.DEFAULT_USER_PERMISSIONS):
436 if len(u2p) != len(Permission.DEFAULT_USER_PERMISSIONS):
437 for p in u2p:
437 for p in u2p:
438 Session().delete(p)
438 Session().delete(p)
439 fixed = True
439 fixed = True
440 self.populate_default_permissions()
440 self.populate_default_permissions()
441 return fixed
441 return fixed
442
442
443 def update_repo_info(self):
443 def update_repo_info(self):
444 RepoModel.update_repoinfo()
444 RepoModel.update_repoinfo()
445
445
446 def config_prompt(self, test_repo_path='', retries=3):
446 def config_prompt(self, test_repo_path='', retries=3):
447 defaults = self.cli_args
447 defaults = self.cli_args
448 _path = defaults.get('repos_location')
448 _path = defaults.get('repos_location')
449 if retries == 3:
449 if retries == 3:
450 log.info('Setting up repositories config')
450 log.info('Setting up repositories config')
451
451
452 if _path is not None:
452 if _path is not None:
453 path = _path
453 path = _path
454 elif not self.tests and not test_repo_path:
454 elif not self.tests and not test_repo_path:
455 path = raw_input(
455 path = raw_input(
456 'Enter a valid absolute path to store repositories. '
456 'Enter a valid absolute path to store repositories. '
457 'All repositories in that path will be added automatically:'
457 'All repositories in that path will be added automatically:'
458 )
458 )
459 else:
459 else:
460 path = test_repo_path
460 path = test_repo_path
461 path_ok = True
461 path_ok = True
462
462
463 # check proper dir
463 # check proper dir
464 if not os.path.isdir(path):
464 if not os.path.isdir(path):
465 path_ok = False
465 path_ok = False
466 log.error('Given path %s is not a valid directory' % (path,))
466 log.error('Given path %s is not a valid directory' % (path,))
467
467
468 elif not os.path.isabs(path):
468 elif not os.path.isabs(path):
469 path_ok = False
469 path_ok = False
470 log.error('Given path %s is not an absolute path' % (path,))
470 log.error('Given path %s is not an absolute path' % (path,))
471
471
472 # check if path is at least readable.
472 # check if path is at least readable.
473 if not os.access(path, os.R_OK):
473 if not os.access(path, os.R_OK):
474 path_ok = False
474 path_ok = False
475 log.error('Given path %s is not readable' % (path,))
475 log.error('Given path %s is not readable' % (path,))
476
476
477 # check write access, warn user about non writeable paths
477 # check write access, warn user about non writeable paths
478 elif not os.access(path, os.W_OK) and path_ok:
478 elif not os.access(path, os.W_OK) and path_ok:
479 log.warning('No write permission to given path %s' % (path,))
479 log.warning('No write permission to given path %s' % (path,))
480
480
481 q = ('Given path %s is not writeable, do you want to '
481 q = ('Given path %s is not writeable, do you want to '
482 'continue with read only mode ? [y/n]' % (path,))
482 'continue with read only mode ? [y/n]' % (path,))
483 if not self.ask_ok(q):
483 if not self.ask_ok(q):
484 log.error('Canceled by user')
484 log.error('Canceled by user')
485 sys.exit(-1)
485 sys.exit(-1)
486
486
487 if retries == 0:
487 if retries == 0:
488 sys.exit('max retries reached')
488 sys.exit('max retries reached')
489 if not path_ok:
489 if not path_ok:
490 retries -= 1
490 retries -= 1
491 return self.config_prompt(test_repo_path, retries)
491 return self.config_prompt(test_repo_path, retries)
492
492
493 real_path = os.path.normpath(os.path.realpath(path))
493 real_path = os.path.normpath(os.path.realpath(path))
494
494
495 if real_path != os.path.normpath(path):
495 if real_path != os.path.normpath(path):
496 q = ('Path looks like a symlink, RhodeCode Enterprise will store '
496 q = ('Path looks like a symlink, RhodeCode Enterprise will store '
497 'given path as %s ? [y/n]') % (real_path,)
497 'given path as %s ? [y/n]') % (real_path,)
498 if not self.ask_ok(q):
498 if not self.ask_ok(q):
499 log.error('Canceled by user')
499 log.error('Canceled by user')
500 sys.exit(-1)
500 sys.exit(-1)
501
501
502 return real_path
502 return real_path
503
503
504 def create_settings(self, path):
504 def create_settings(self, path):
505
505
506 self.create_ui_settings(path)
506 self.create_ui_settings(path)
507
507
508 ui_config = [
508 ui_config = [
509 ('web', 'push_ssl', 'false'),
509 ('web', 'push_ssl', 'false'),
510 ('web', 'allow_archive', 'gz zip bz2'),
510 ('web', 'allow_archive', 'gz zip bz2'),
511 ('web', 'allow_push', '*'),
511 ('web', 'allow_push', '*'),
512 ('web', 'baseurl', '/'),
512 ('web', 'baseurl', '/'),
513 ('paths', '/', path),
513 ('paths', '/', path),
514 ('phases', 'publish', 'true')
514 ('phases', 'publish', 'true')
515 ]
515 ]
516 for section, key, value in ui_config:
516 for section, key, value in ui_config:
517 ui_conf = RhodeCodeUi()
517 ui_conf = RhodeCodeUi()
518 setattr(ui_conf, 'ui_section', section)
518 setattr(ui_conf, 'ui_section', section)
519 setattr(ui_conf, 'ui_key', key)
519 setattr(ui_conf, 'ui_key', key)
520 setattr(ui_conf, 'ui_value', value)
520 setattr(ui_conf, 'ui_value', value)
521 self.sa.add(ui_conf)
521 self.sa.add(ui_conf)
522
522
523 # rhodecode app settings
523 # rhodecode app settings
524 settings = [
524 settings = [
525 ('realm', 'RhodeCode', 'unicode'),
525 ('realm', 'RhodeCode', 'unicode'),
526 ('title', '', 'unicode'),
526 ('title', '', 'unicode'),
527 ('pre_code', '', 'unicode'),
527 ('pre_code', '', 'unicode'),
528 ('post_code', '', 'unicode'),
528 ('post_code', '', 'unicode'),
529 ('show_public_icon', True, 'bool'),
529 ('show_public_icon', True, 'bool'),
530 ('show_private_icon', True, 'bool'),
530 ('show_private_icon', True, 'bool'),
531 ('stylify_metatags', False, 'bool'),
531 ('stylify_metatags', False, 'bool'),
532 ('dashboard_items', 100, 'int'),
532 ('dashboard_items', 100, 'int'),
533 ('admin_grid_items', 25, 'int'),
533 ('admin_grid_items', 25, 'int'),
534 ('show_version', True, 'bool'),
534 ('show_version', True, 'bool'),
535 ('use_gravatar', False, 'bool'),
535 ('use_gravatar', False, 'bool'),
536 ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'),
536 ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'),
537 ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'),
537 ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'),
538 ('support_url', '', 'unicode'),
538 ('support_url', '', 'unicode'),
539 ('update_url', RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode'),
539 ('update_url', RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode'),
540 ('show_revision_number', True, 'bool'),
540 ('show_revision_number', True, 'bool'),
541 ('show_sha_length', 12, 'int'),
541 ('show_sha_length', 12, 'int'),
542 ]
542 ]
543
543
544 for key, val, type_ in settings:
544 for key, val, type_ in settings:
545 sett = RhodeCodeSetting(key, val, type_)
545 sett = RhodeCodeSetting(key, val, type_)
546 self.sa.add(sett)
546 self.sa.add(sett)
547
547
548 self.create_auth_plugin_options()
548 self.create_auth_plugin_options()
549 self.create_default_options()
549 self.create_default_options()
550
550
551 log.info('created ui config')
551 log.info('created ui config')
552
552
553 def create_user(self, username, password, email='', admin=False,
553 def create_user(self, username, password, email='', admin=False,
554 strict_creation_check=True, api_key=None):
554 strict_creation_check=True, api_key=None):
555 log.info('creating user %s' % username)
555 log.info('creating user %s' % username)
556 user = UserModel().create_or_update(
556 user = UserModel().create_or_update(
557 username, password, email, firstname='RhodeCode', lastname='Admin',
557 username, password, email, firstname='RhodeCode', lastname='Admin',
558 active=True, admin=admin, extern_type="rhodecode",
558 active=True, admin=admin, extern_type="rhodecode",
559 strict_creation_check=strict_creation_check)
559 strict_creation_check=strict_creation_check)
560
560
561 if api_key:
561 if api_key:
562 log.info('setting a provided api key for the user %s', username)
562 log.info('setting a provided api key for the user %s', username)
563 user.api_key = api_key
563 user.api_key = api_key
564
564
565 def create_default_user(self):
565 def create_default_user(self):
566 log.info('creating default user')
566 log.info('creating default user')
567 # create default user for handling default permissions.
567 # create default user for handling default permissions.
568 user = UserModel().create_or_update(username=User.DEFAULT_USER,
568 user = UserModel().create_or_update(username=User.DEFAULT_USER,
569 password=str(uuid.uuid1())[:20],
569 password=str(uuid.uuid1())[:20],
570 email=User.DEFAULT_USER_EMAIL,
570 email=User.DEFAULT_USER_EMAIL,
571 firstname='Anonymous',
571 firstname='Anonymous',
572 lastname='User',
572 lastname='User',
573 strict_creation_check=False)
573 strict_creation_check=False)
574 # based on configuration options activate/deactive this user which
574 # based on configuration options activate/deactive this user which
575 # controlls anonymous access
575 # controlls anonymous access
576 if self.cli_args.get('public_access') is False:
576 if self.cli_args.get('public_access') is False:
577 log.info('Public access disabled')
577 log.info('Public access disabled')
578 user.active = False
578 user.active = False
579 Session().add(user)
579 Session().add(user)
580 Session().commit()
580 Session().commit()
581
581
582 def create_permissions(self):
582 def create_permissions(self):
583 """
583 """
584 Creates all permissions defined in the system
584 Creates all permissions defined in the system
585 """
585 """
586 # module.(access|create|change|delete)_[name]
586 # module.(access|create|change|delete)_[name]
587 # module.(none|read|write|admin)
587 # module.(none|read|write|admin)
588 log.info('creating permissions')
588 log.info('creating permissions')
589 PermissionModel(self.sa).create_permissions()
589 PermissionModel(self.sa).create_permissions()
590
590
591 def populate_default_permissions(self):
591 def populate_default_permissions(self):
592 """
592 """
593 Populate default permissions. It will create only the default
593 Populate default permissions. It will create only the default
594 permissions that are missing, and not alter already defined ones
594 permissions that are missing, and not alter already defined ones
595 """
595 """
596 log.info('creating default user permissions')
596 log.info('creating default user permissions')
597 PermissionModel(self.sa).create_default_user_permissions(user=User.DEFAULT_USER)
597 PermissionModel(self.sa).create_default_user_permissions(user=User.DEFAULT_USER)
General Comments 0
You need to be logged in to leave comments. Login now