##// END OF EJS Templates
complete rewrite of paster commands,...
marcink -
r785:277427ac beta
parent child Browse files
Show More
@@ -2,7 +2,6 b' from celery.decorators import task'
2 2
3 3 import os
4 4 import traceback
5 import beaker
6 5 from time import mktime
7 6 from operator import itemgetter
8 7
@@ -12,7 +11,7 b' from pylons.i18n.translation import _'
12 11 from rhodecode.lib.celerylib import run_task, locked_task, str2bool
13 12 from rhodecode.lib.helpers import person
14 13 from rhodecode.lib.smtp_mailer import SmtpMailer
15 from rhodecode.lib.utils import OrderedDict
14 from rhodecode.lib.utils import OrderedDict, add_cache
16 15 from rhodecode.model import init_model
17 16 from rhodecode.model import meta
18 17 from rhodecode.model.db import RhodeCodeUi
@@ -21,29 +20,6 b' from vcs.backends import get_repo'
21 20
22 21 from sqlalchemy import engine_from_config
23 22
24 #set cache regions for beaker so celery can utilise it
25 def add_cache(settings):
26 cache_settings = {'regions':None}
27 for key in settings.keys():
28 for prefix in ['beaker.cache.', 'cache.']:
29 if key.startswith(prefix):
30 name = key.split(prefix)[1].strip()
31 cache_settings[name] = settings[key].strip()
32 if cache_settings['regions']:
33 for region in cache_settings['regions'].split(','):
34 region = region.strip()
35 region_settings = {}
36 for key, value in cache_settings.items():
37 if key.startswith(region):
38 region_settings[key.split('.')[1]] = value
39 region_settings['expire'] = int(region_settings.get('expire',
40 60))
41 region_settings.setdefault('lock_dir',
42 cache_settings.get('lock_dir'))
43 if 'type' not in region_settings:
44 region_settings['type'] = cache_settings.get('type',
45 'memory')
46 beaker.cache.cache_regions[region] = region_settings
47 23 add_cache(config)
48 24
49 25 try:
@@ -1,64 +1,11 b''
1 import os
2 from paste.script.command import Command, BadCommand
3 import paste.deploy
4 from pylons import config
1 from rhodecode.lib.utils import BasePasterCommand, Command
5 2
6 3
7 4 __all__ = ['CeleryDaemonCommand', 'CeleryBeatCommand',
8 5 'CAMQPAdminCommand', 'CeleryEventCommand']
9 6
10 7
11 class CeleryCommand(Command):
12 """
13 Abstract Base Class for celery commands.
14
15 The celery commands are somewhat aggressive about loading
16 celery.conf, and since our module sets the `CELERY_LOADER`
17 environment variable to our loader, we have to bootstrap a bit and
18 make sure we've had a chance to load the pylons config off of the
19 command line, otherwise everything fails.
20 """
21 min_args = 1
22 min_args_error = "Please provide a paster config file as an argument."
23 takes_config_file = 1
24 requires_config_file = True
25
26 def run(self, args):
27 """
28 Overrides Command.run
29
30 Checks for a config file argument and loads it.
31 """
32 if len(args) < self.min_args:
33 raise BadCommand(
34 self.min_args_error % {'min_args': self.min_args,
35 'actual_args': len(args)})
36 # Decrement because we're going to lob off the first argument.
37 # @@ This is hacky
38 self.min_args -= 1
39 self.bootstrap_config(args[0])
40 self.update_parser()
41 return super(CeleryCommand, self).run(args[1:])
42
43 def update_parser(self):
44 """
45 Abstract method. Allows for the class's parser to be updated
46 before the superclass's `run` method is called. Necessary to
47 allow options/arguments to be passed through to the underlying
48 celery command.
49 """
50 raise NotImplementedError("Abstract Method.")
51
52 def bootstrap_config(self, conf):
53 """
54 Loads the pylons configuration.
55 """
56 path_to_ini_file = os.path.realpath(conf)
57 conf = paste.deploy.appconfig('config:' + path_to_ini_file)
58 config.init_app(conf.global_conf, conf.local_conf)
59
60
61 class CeleryDaemonCommand(CeleryCommand):
8 class CeleryDaemonCommand(BasePasterCommand):
62 9 """Start the celery worker
63 10
64 11 Starts the celery worker that uses a paste.deploy configuration
@@ -80,7 +27,7 b' class CeleryDaemonCommand(CeleryCommand)'
80 27 return celeryd.WorkerCommand().run(**vars(self.options))
81 28
82 29
83 class CeleryBeatCommand(CeleryCommand):
30 class CeleryBeatCommand(BasePasterCommand):
84 31 """Start the celery beat server
85 32
86 33 Starts the celery beat server using a paste.deploy configuration
@@ -101,7 +48,7 b' class CeleryBeatCommand(CeleryCommand):'
101 48 from celery.bin import celerybeat
102 49 return celerybeat.BeatCommand(**vars(self.options))
103 50
104 class CAMQPAdminCommand(CeleryCommand):
51 class CAMQPAdminCommand(BasePasterCommand):
105 52 """CAMQP Admin
106 53
107 54 CAMQP celery admin tool.
@@ -122,7 +69,7 b' class CAMQPAdminCommand(CeleryCommand):'
122 69 return camqadm.camqadm(*self.args, **vars(self.options))
123 70
124 71
125 class CeleryEventCommand(CeleryCommand):
72 class CeleryEventCommand(BasePasterCommand):
126 73 """Celery event commandd.
127 74
128 75 Capture celery events.
@@ -1,23 +1,28 b''
1 1 import os
2 2 import sys
3 import traceback
3 4 from os.path import dirname as dn, join as jn
4 5
5 6 #to get the rhodecode import
6 7 sys.path.append(dn(dn(dn(os.path.realpath(__file__)))))
7 8
9 from rhodecode.model import init_model
10 from rhodecode.model.scm import ScmModel
8 11 from rhodecode.config.environment import load_environment
9 from rhodecode.model.scm import ScmModel
12 from rhodecode.lib.utils import BasePasterCommand, Command, add_cache
13
10 14 from shutil import rmtree
11 15 from webhelpers.html.builder import escape
12 16 from vcs.utils.lazy import LazyProperty
13 17
18 from sqlalchemy import engine_from_config
19
14 20 from whoosh.analysis import RegexTokenizer, LowercaseFilter, StopFilter
15 21 from whoosh.fields import TEXT, ID, STORED, Schema, FieldType
16 22 from whoosh.index import create_in, open_dir
17 23 from whoosh.formats import Characters
18 24 from whoosh.highlight import highlight, SimpleFragmenter, HtmlFormatter
19 25
20 import traceback
21 26
22 27 #EXTENSIONS WE WANT TO INDEX CONTENT OFF
23 28 INDEX_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
@@ -45,10 +50,8 b" IDX_NAME = 'HG_INDEX'"
45 50 FORMATTER = HtmlFormatter('span', between='\n<span class="break">...</span>\n')
46 51 FRAGMENTER = SimpleFragmenter(200)
47 52
48 from paste.script import command
49 import ConfigParser
50 53
51 class MakeIndex(command.Command):
54 class MakeIndex(BasePasterCommand):
52 55
53 56 max_args = 1
54 57 min_args = 1
@@ -57,26 +60,16 b' class MakeIndex(command.Command):'
57 60 summary = "Creates index for full text search given configuration file"
58 61 group_name = "RhodeCode"
59 62 takes_config_file = -1
60 parser = command.Command.standard_parser(verbose=True)
61 parser.add_option('--repo-location',
62 action='store',
63 dest='repo_location',
64 help="Specifies repositories location to index REQUIRED",
65 )
66 parser.add_option('-f',
67 action='store_true',
68 dest='full_index',
69 help="Specifies that index should be made full i.e"
70 " destroy old and build from scratch",
71 default=False)
63 parser = Command.standard_parser(verbose=True)
64
72 65 def command(self):
73 config_name = self.args[0]
74 p = config_name.split('/')
75 root = '.' if len(p) == 1 else '/'.join(p[:-1])
76 config = ConfigParser.ConfigParser({'here':root})
77 config.read(config_name)
78 66
79 index_location = dict(config.items('app:main'))['index_dir']
67 from pylons import config
68 add_cache(config)
69 engine = engine_from_config(config, 'sqlalchemy.db1.')
70 init_model(engine)
71
72 index_location = config['index_dir']
80 73 repo_location = self.options.repo_location
81 74
82 75 #======================================================================
@@ -93,6 +86,18 b' class MakeIndex(command.Command):'
93 86 except LockHeld:
94 87 sys.exit(1)
95 88
89 def update_parser(self):
90 self.parser.add_option('--repo-location',
91 action='store',
92 dest='repo_location',
93 help="Specifies repositories location to index REQUIRED",
94 )
95 self.parser.add_option('-f',
96 action='store_true',
97 dest='full_index',
98 help="Specifies that index should be made full i.e"
99 " destroy old and build from scratch",
100 default=False)
96 101
97 102 class ResultWrapper(object):
98 103 def __init__(self, search_type, searcher, matcher, highlight_items):
@@ -36,7 +36,10 b' from UserDict import DictMixin'
36 36 from mercurial import ui, config, hg
37 37 from mercurial.error import RepoError
38 38
39 from paste.script import command
39 import paste
40 import beaker
41 from paste.script.command import Command, BadCommand
42
40 43 from vcs.backends.base import BaseChangeset
41 44 from vcs.utils.lazy import LazyProperty
42 45
@@ -416,6 +419,31 b' class OrderedDict(dict, DictMixin):'
416 419 return not self == other
417 420
418 421
422 #set cache regions for beaker so celery can utilise it
423 def add_cache(settings):
424 cache_settings = {'regions':None}
425 for key in settings.keys():
426 for prefix in ['beaker.cache.', 'cache.']:
427 if key.startswith(prefix):
428 name = key.split(prefix)[1].strip()
429 cache_settings[name] = settings[key].strip()
430 if cache_settings['regions']:
431 for region in cache_settings['regions'].split(','):
432 region = region.strip()
433 region_settings = {}
434 for key, value in cache_settings.items():
435 if key.startswith(region):
436 region_settings[key.split('.')[1]] = value
437 region_settings['expire'] = int(region_settings.get('expire',
438 60))
439 region_settings.setdefault('lock_dir',
440 cache_settings.get('lock_dir'))
441 if 'type' not in region_settings:
442 region_settings['type'] = cache_settings.get('type',
443 'memory')
444 beaker.cache.cache_regions[region] = region_settings
445
446
419 447 #===============================================================================
420 448 # TEST FUNCTIONS AND CREATORS
421 449 #===============================================================================
@@ -498,7 +526,66 b' def create_test_env(repos_test_path, con'
498 526 tar.extractall(jn(TESTS_TMP_PATH, HG_REPO))
499 527 tar.close()
500 528
501 class UpgradeDb(command.Command):
529
530 #==============================================================================
531 # PASTER COMMANDS
532 #==============================================================================
533
534 class BasePasterCommand(Command):
535 """
536 Abstract Base Class for paster commands.
537
538 The celery commands are somewhat aggressive about loading
539 celery.conf, and since our module sets the `CELERY_LOADER`
540 environment variable to our loader, we have to bootstrap a bit and
541 make sure we've had a chance to load the pylons config off of the
542 command line, otherwise everything fails.
543 """
544 min_args = 1
545 min_args_error = "Please provide a paster config file as an argument."
546 takes_config_file = 1
547 requires_config_file = True
548
549 def run(self, args):
550 """
551 Overrides Command.run
552
553 Checks for a config file argument and loads it.
554 """
555 if len(args) < self.min_args:
556 raise BadCommand(
557 self.min_args_error % {'min_args': self.min_args,
558 'actual_args': len(args)})
559
560 # Decrement because we're going to lob off the first argument.
561 # @@ This is hacky
562 self.min_args -= 1
563 self.bootstrap_config(args[0])
564 self.update_parser()
565 return super(BasePasterCommand, self).run(args[1:])
566
567 def update_parser(self):
568 """
569 Abstract method. Allows for the class's parser to be updated
570 before the superclass's `run` method is called. Necessary to
571 allow options/arguments to be passed through to the underlying
572 celery command.
573 """
574 raise NotImplementedError("Abstract Method.")
575
576 def bootstrap_config(self, conf):
577 """
578 Loads the pylons configuration.
579 """
580 from pylons import config as pylonsconfig
581
582 path_to_ini_file = os.path.realpath(conf)
583 conf = paste.deploy.appconfig('config:' + path_to_ini_file)
584 pylonsconfig.init_app(conf.global_conf, conf.local_conf)
585
586
587
588 class UpgradeDb(BasePasterCommand):
502 589 """Command used for paster to upgrade our database to newer version
503 590 """
504 591
@@ -509,16 +596,16 b' class UpgradeDb(command.Command):'
509 596 summary = "Upgrades current db to newer version given configuration file"
510 597 group_name = "RhodeCode"
511 598
512 parser = command.Command.standard_parser(verbose=True)
599 parser = Command.standard_parser(verbose=True)
513 600
514 parser.add_option('--sql',
601 def command(self):
602 from pylons import config
603 raise NotImplementedError('Not implemented yet')
604
605
606 def update_parser(self):
607 self.parser.add_option('--sql',
515 608 action='store_true',
516 609 dest='just_sql',
517 610 help="Prints upgrade sql for further investigation",
518 611 default=False)
519 def command(self):
520 config_name = self.args[0]
521 p = config_name.split('/')
522 root = '.' if len(p) == 1 else '/'.join(p[:-1])
523 config = ConfigParser.ConfigParser({'here':root})
524 config.read(config_name)
General Comments 0
You need to be logged in to leave comments. Login now