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