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( |
|
|
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( |
|
|
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( |
|
|
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( |
|
|
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 = |
|
|
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 = |
|
|
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