Show More
@@ -2,7 +2,6 b' from celery.decorators import task' | |||||
2 |
|
2 | |||
3 | import os |
|
3 | import os | |
4 | import traceback |
|
4 | import traceback | |
5 | import beaker |
|
|||
6 | from time import mktime |
|
5 | from time import mktime | |
7 | from operator import itemgetter |
|
6 | from operator import itemgetter | |
8 |
|
7 | |||
@@ -12,7 +11,7 b' from pylons.i18n.translation import _' | |||||
12 | from rhodecode.lib.celerylib import run_task, locked_task, str2bool |
|
11 | from rhodecode.lib.celerylib import run_task, locked_task, str2bool | |
13 | from rhodecode.lib.helpers import person |
|
12 | from rhodecode.lib.helpers import person | |
14 | from rhodecode.lib.smtp_mailer import SmtpMailer |
|
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 | from rhodecode.model import init_model |
|
15 | from rhodecode.model import init_model | |
17 | from rhodecode.model import meta |
|
16 | from rhodecode.model import meta | |
18 | from rhodecode.model.db import RhodeCodeUi |
|
17 | from rhodecode.model.db import RhodeCodeUi | |
@@ -21,29 +20,6 b' from vcs.backends import get_repo' | |||||
21 |
|
20 | |||
22 | from sqlalchemy import engine_from_config |
|
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 | add_cache(config) |
|
23 | add_cache(config) | |
48 |
|
24 | |||
49 | try: |
|
25 | try: |
@@ -1,64 +1,11 b'' | |||||
1 | import os |
|
1 | from rhodecode.lib.utils import BasePasterCommand, Command | |
2 | from paste.script.command import Command, BadCommand |
|
|||
3 | import paste.deploy |
|
|||
4 | from pylons import config |
|
|||
5 |
|
2 | |||
6 |
|
3 | |||
7 | __all__ = ['CeleryDaemonCommand', 'CeleryBeatCommand', |
|
4 | __all__ = ['CeleryDaemonCommand', 'CeleryBeatCommand', | |
8 | 'CAMQPAdminCommand', 'CeleryEventCommand'] |
|
5 | 'CAMQPAdminCommand', 'CeleryEventCommand'] | |
9 |
|
6 | |||
10 |
|
7 | |||
11 | class CeleryCommand(Command): |
|
8 | class CeleryDaemonCommand(BasePasterCommand): | |
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): |
|
|||
62 | """Start the celery worker |
|
9 | """Start the celery worker | |
63 |
|
10 | |||
64 | Starts the celery worker that uses a paste.deploy configuration |
|
11 | Starts the celery worker that uses a paste.deploy configuration | |
@@ -80,7 +27,7 b' class CeleryDaemonCommand(CeleryCommand)' | |||||
80 | return celeryd.WorkerCommand().run(**vars(self.options)) |
|
27 | return celeryd.WorkerCommand().run(**vars(self.options)) | |
81 |
|
28 | |||
82 |
|
29 | |||
83 |
class CeleryBeatCommand( |
|
30 | class CeleryBeatCommand(BasePasterCommand): | |
84 | """Start the celery beat server |
|
31 | """Start the celery beat server | |
85 |
|
32 | |||
86 | Starts the celery beat server using a paste.deploy configuration |
|
33 | Starts the celery beat server using a paste.deploy configuration | |
@@ -101,7 +48,7 b' class CeleryBeatCommand(CeleryCommand):' | |||||
101 | from celery.bin import celerybeat |
|
48 | from celery.bin import celerybeat | |
102 | return celerybeat.BeatCommand(**vars(self.options)) |
|
49 | return celerybeat.BeatCommand(**vars(self.options)) | |
103 |
|
50 | |||
104 |
class CAMQPAdminCommand( |
|
51 | class CAMQPAdminCommand(BasePasterCommand): | |
105 | """CAMQP Admin |
|
52 | """CAMQP Admin | |
106 |
|
53 | |||
107 | CAMQP celery admin tool. |
|
54 | CAMQP celery admin tool. | |
@@ -122,7 +69,7 b' class CAMQPAdminCommand(CeleryCommand):' | |||||
122 | return camqadm.camqadm(*self.args, **vars(self.options)) |
|
69 | return camqadm.camqadm(*self.args, **vars(self.options)) | |
123 |
|
70 | |||
124 |
|
71 | |||
125 |
class CeleryEventCommand( |
|
72 | class CeleryEventCommand(BasePasterCommand): | |
126 | """Celery event commandd. |
|
73 | """Celery event commandd. | |
127 |
|
74 | |||
128 | Capture celery events. |
|
75 | Capture celery events. |
@@ -1,23 +1,28 b'' | |||||
1 | import os |
|
1 | import os | |
2 | import sys |
|
2 | import sys | |
|
3 | import traceback | |||
3 | from os.path import dirname as dn, join as jn |
|
4 | from os.path import dirname as dn, join as jn | |
4 |
|
5 | |||
5 | #to get the rhodecode import |
|
6 | #to get the rhodecode import | |
6 | sys.path.append(dn(dn(dn(os.path.realpath(__file__))))) |
|
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 | from rhodecode.config.environment import load_environment |
|
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 | from shutil import rmtree |
|
14 | from shutil import rmtree | |
11 | from webhelpers.html.builder import escape |
|
15 | from webhelpers.html.builder import escape | |
12 | from vcs.utils.lazy import LazyProperty |
|
16 | from vcs.utils.lazy import LazyProperty | |
13 |
|
17 | |||
|
18 | from sqlalchemy import engine_from_config | |||
|
19 | ||||
14 | from whoosh.analysis import RegexTokenizer, LowercaseFilter, StopFilter |
|
20 | from whoosh.analysis import RegexTokenizer, LowercaseFilter, StopFilter | |
15 | from whoosh.fields import TEXT, ID, STORED, Schema, FieldType |
|
21 | from whoosh.fields import TEXT, ID, STORED, Schema, FieldType | |
16 | from whoosh.index import create_in, open_dir |
|
22 | from whoosh.index import create_in, open_dir | |
17 | from whoosh.formats import Characters |
|
23 | from whoosh.formats import Characters | |
18 | from whoosh.highlight import highlight, SimpleFragmenter, HtmlFormatter |
|
24 | from whoosh.highlight import highlight, SimpleFragmenter, HtmlFormatter | |
19 |
|
25 | |||
20 | import traceback |
|
|||
21 |
|
26 | |||
22 | #EXTENSIONS WE WANT TO INDEX CONTENT OFF |
|
27 | #EXTENSIONS WE WANT TO INDEX CONTENT OFF | |
23 | INDEX_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c', |
|
28 | INDEX_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c', | |
@@ -45,10 +50,8 b" IDX_NAME = 'HG_INDEX'" | |||||
45 | FORMATTER = HtmlFormatter('span', between='\n<span class="break">...</span>\n') |
|
50 | FORMATTER = HtmlFormatter('span', between='\n<span class="break">...</span>\n') | |
46 | FRAGMENTER = SimpleFragmenter(200) |
|
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 | max_args = 1 |
|
56 | max_args = 1 | |
54 | min_args = 1 |
|
57 | min_args = 1 | |
@@ -57,26 +60,16 b' class MakeIndex(command.Command):' | |||||
57 | summary = "Creates index for full text search given configuration file" |
|
60 | summary = "Creates index for full text search given configuration file" | |
58 | group_name = "RhodeCode" |
|
61 | group_name = "RhodeCode" | |
59 | takes_config_file = -1 |
|
62 | takes_config_file = -1 | |
60 |
parser = |
|
63 | parser = Command.standard_parser(verbose=True) | |
61 | parser.add_option('--repo-location', |
|
64 | ||
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) |
|
|||
72 | def command(self): |
|
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 | repo_location = self.options.repo_location |
|
73 | repo_location = self.options.repo_location | |
81 |
|
74 | |||
82 | #====================================================================== |
|
75 | #====================================================================== | |
@@ -93,6 +86,18 b' class MakeIndex(command.Command):' | |||||
93 | except LockHeld: |
|
86 | except LockHeld: | |
94 | sys.exit(1) |
|
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 | class ResultWrapper(object): |
|
102 | class ResultWrapper(object): | |
98 | def __init__(self, search_type, searcher, matcher, highlight_items): |
|
103 | def __init__(self, search_type, searcher, matcher, highlight_items): |
@@ -36,7 +36,10 b' from UserDict import DictMixin' | |||||
36 | from mercurial import ui, config, hg |
|
36 | from mercurial import ui, config, hg | |
37 | from mercurial.error import RepoError |
|
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 | from vcs.backends.base import BaseChangeset |
|
43 | from vcs.backends.base import BaseChangeset | |
41 | from vcs.utils.lazy import LazyProperty |
|
44 | from vcs.utils.lazy import LazyProperty | |
42 |
|
45 | |||
@@ -416,6 +419,31 b' class OrderedDict(dict, DictMixin):' | |||||
416 | return not self == other |
|
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 | # TEST FUNCTIONS AND CREATORS |
|
448 | # TEST FUNCTIONS AND CREATORS | |
421 | #=============================================================================== |
|
449 | #=============================================================================== | |
@@ -498,7 +526,66 b' def create_test_env(repos_test_path, con' | |||||
498 | tar.extractall(jn(TESTS_TMP_PATH, HG_REPO)) |
|
526 | tar.extractall(jn(TESTS_TMP_PATH, HG_REPO)) | |
499 | tar.close() |
|
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 | """Command used for paster to upgrade our database to newer version |
|
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 | summary = "Upgrades current db to newer version given configuration file" |
|
596 | summary = "Upgrades current db to newer version given configuration file" | |
510 | group_name = "RhodeCode" |
|
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 | action='store_true', |
|
608 | action='store_true', | |
516 | dest='just_sql', |
|
609 | dest='just_sql', | |
517 | help="Prints upgrade sql for further investigation", |
|
610 | help="Prints upgrade sql for further investigation", | |
518 | default=False) |
|
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