Commit 3e43c7db70021cf7a78677047aa0d15b1eeb0156

Authored by Sergio Oliveira
1 parent 721677c8

Refactored colab-admin command

Allow to run celery from colab-admin

Signed-off-by: Sergio Oliveira <sergio@tracy.com.br>
@@ -64,7 +64,7 @@ To run Colab with development server you will have to: @@ -64,7 +64,7 @@ To run Colab with development server you will have to:
64 64
65 .. code-block:: 65 .. code-block::
66 66
67 - colab-init-config > /etc/colab/settings.yaml 67 + colab-admin initconfig > /etc/colab/settings.yaml
68 68
69 2- Edit the configuration file. Make sure you set everything you need including **database** credentials. 69 2- Edit the configuration file. Make sure you set everything you need including **database** credentials.
70 70
@@ -92,4 +92,4 @@ How to run the tests @@ -92,4 +92,4 @@ How to run the tests
92 Follow the steps below: 92 Follow the steps below:
93 93
94 * Go to vagrant/colab/ 94 * Go to vagrant/colab/
95 -* run: ./runtests.sh  
96 \ No newline at end of file 95 \ No newline at end of file
  96 +* run: ./runtests.sh
colab/management/__init__.py
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -  
2 -import os  
3 -  
4 -from django.core.management import ManagementUtility  
5 -  
6 -from .initconfig import initconfig  
7 -  
8 -  
9 -def execute_from_command_line(argv=None):  
10 - """  
11 - A simple method that runs a ManagementUtility.  
12 - """  
13 - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "colab.settings")  
14 -  
15 - utility = ManagementUtility(argv)  
16 - utility.execute()  
17 -  
18 -  
19 -def run_colab_config(argv=None):  
20 - initconfig()  
colab/management/commands/__init__.py 0 → 100644
colab/management/commands/celery.py 0 → 100644
@@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
  1 +from __future__ import absolute_import, unicode_literals
  2 +
  3 +from celery.bin import celery
  4 +
  5 +from colab.celery import app
  6 +from colab.queue.command import CeleryCommand
  7 +
  8 +base = celery.CeleryCommand(app=app)
  9 +
  10 +
  11 +# this is a reimplementation of the djcelery 'celery' command
  12 +# taken from Sentry
  13 +class Command(CeleryCommand):
  14 + """The celery command."""
  15 + help = 'celery commands, see celery help'
  16 + options = (CeleryCommand.options
  17 + + base.get_options()
  18 + + base.preload_options)
  19 +
  20 + def run_from_argv(self, argv):
  21 + argv = self.handle_default_options(argv)
  22 + if self.requires_system_checks:
  23 + self.validate()
  24 + base.execute_from_commandline(
  25 + ['{0[0]} {0[1]}'.format(argv)] + argv[2:],
  26 + )
colab/management/commands/initconfig.py 0 → 100644
@@ -0,0 +1,124 @@ @@ -0,0 +1,124 @@
  1 +
  2 +from django.core.management.base import BaseCommand
  3 +from django.utils.crypto import get_random_string
  4 +
  5 +
  6 +CONFIG_TEMPLATE = """
  7 +## Set to false in production
  8 +DEBUG = True
  9 +TEMPLATE_DEBUG = True
  10 +
  11 +## System admins
  12 +ADMINS = [['John Foo', 'john@example.com'], ['Mary Bar', 'mary@example.com']]
  13 +
  14 +MANAGERS = ADMINS
  15 +
  16 +COLAB_FROM_ADDRESS = '"Colab" <noreply@example.com>'
  17 +SERVER_EMAIL = '"Colab" <noreply@example.com>'
  18 +
  19 +EMAIL_HOST = 'localhost'
  20 +EMAIL_PORT = 25
  21 +EMAIL_SUBJECT_PREFIX = '[colab]'
  22 +
  23 +SECRET_KEY = '{secret_key}'
  24 +
  25 +ALLOWED_HOSTS = [
  26 + 'localhost',
  27 +# 'example.com',
  28 +# 'example.org',
  29 +# 'example.net',
  30 +]
  31 +
  32 +### Uncomment to enable social networks fields profile
  33 +# SOCIAL_NETWORK_ENABLED = True
  34 +
  35 +## Database settings
  36 +##
  37 +## When DEBUG is True colab will create the DB on
  38 +## the repository root. In case of production settings
  39 +## (DEBUG False) the DB settings must be set.
  40 +##
  41 +# DATABASES = {{
  42 +# 'default': {{
  43 +# 'ENGINE': 'django.db.backends.sqlite3',
  44 +# 'NAME': '/path/to/colab.sqlite3',
  45 +# }}
  46 +# }}
  47 +
  48 +## Disable indexing
  49 +ROBOTS_NOINDEX = False
  50 +
  51 +LOGGING = {{
  52 + 'version': 1,
  53 +
  54 + 'handlers': {{
  55 + 'null': {{
  56 + 'level': 'DEBUG',
  57 + 'class': 'logging.NullHandler',
  58 + }},
  59 + }},
  60 +
  61 + 'loggers': {{
  62 + 'colab.mailman': {{
  63 + 'handlers': ['null'],
  64 + 'propagate': False,
  65 + }},
  66 + 'haystack': {{
  67 + 'handlers': ['null'],
  68 + 'propagate': False,
  69 + }},
  70 + 'pysolr': {{
  71 + 'handlers': ['null'],
  72 + 'propagate': False,
  73 + }},
  74 + }},
  75 +}}
  76 +
  77 +
  78 +## Gitlab plugin - Put this in plugins.d/gitlab.py to actiate ##
  79 +# from django.utils.translation import ugettext_lazy as _
  80 +# from colab.plugins.utils.menu import colab_url_factory
  81 +#
  82 +# name = 'colab.plugins.gitlab'
  83 +# verbose_name = 'Gitlab Proxy'
  84 +#
  85 +# upstream = 'localhost'
  86 +# #middlewares = []
  87 +#
  88 +# urls = {{
  89 +# 'include': 'colab.plugins.gitlab.urls',
  90 +# 'namespace': 'gitlab',
  91 +# 'prefix': 'gitlab',
  92 +# }}
  93 +#
  94 +# menu_title = _('Code')
  95 +#
  96 +# url = colab_url_factory('gitlab')
  97 +#
  98 +# menu_urls = (
  99 +# url(display=_('Public Projects'), viewname='gitlab',
  100 +# kwargs={{'path': '/public/projects'}}, auth=False),
  101 +# url(display=_('Profile'), viewname='gitlab',
  102 +# kwargs={{'path': '/profile'}}, auth=True),
  103 +# url(display=_('New Project'), viewname='gitlab',
  104 +# kwargs={{'path': '/projects/new'}}, auth=True),
  105 +# url(display=_('Projects'), viewname='gitlab',
  106 +# kwargs={{'path': '/dashboard/projects'}}, auth=True),
  107 +# url(display=_('Groups'), viewname='gitlab',
  108 +# kwargs={{'path': '/profile/groups'}}, auth=True),
  109 +# url(display=_('Issues'), viewname='gitlab',
  110 +# kwargs={{'path': '/dashboard/issues'}}, auth=True),
  111 +# url(display=_('Merge Requests'), viewname='gitlab',
  112 +# kwargs={{'path': '/merge_requests'}}, auth=True),
  113 +#
  114 +# )
  115 +"""
  116 +
  117 +
  118 +class Command(BaseCommand):
  119 + help = 'Returns an example config file for Colab'
  120 +
  121 + def handle(self, *args, **kwargs):
  122 + chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
  123 + secret_key = get_random_string(50, chars)
  124 + print(CONFIG_TEMPLATE.format(secret_key=secret_key))
colab/management/initconfig.py
@@ -1,120 +0,0 @@ @@ -1,120 +0,0 @@
1 -  
2 -from django.utils.crypto import get_random_string  
3 -  
4 -  
5 -CONFIG_TEMPLATE = """  
6 -## Set to false in production  
7 -DEBUG = True  
8 -TEMPLATE_DEBUG = True  
9 -  
10 -## System admins  
11 -ADMINS = [['John Foo', 'john@example.com'], ['Mary Bar', 'mary@example.com']]  
12 -  
13 -MANAGERS = ADMINS  
14 -  
15 -COLAB_FROM_ADDRESS = '"Colab" <noreply@example.com>'  
16 -SERVER_EMAIL = '"Colab" <noreply@example.com>'  
17 -  
18 -EMAIL_HOST = 'localhost'  
19 -EMAIL_PORT = 25  
20 -EMAIL_SUBJECT_PREFIX = '[colab]'  
21 -  
22 -SECRET_KEY = '{secret_key}'  
23 -  
24 -ALLOWED_HOSTS = [  
25 - 'localhost',  
26 -# 'example.com',  
27 -# 'example.org',  
28 -# 'example.net',  
29 -]  
30 -  
31 -### Uncomment to enable social networks fields profile  
32 -# SOCIAL_NETWORK_ENABLED = True  
33 -  
34 -## Database settings  
35 -##  
36 -## When DEBUG is True colab will create the DB on  
37 -## the repository root. In case of production settings  
38 -## (DEBUG False) the DB settings must be set.  
39 -##  
40 -# DATABASES = {{  
41 -# 'default': {{  
42 -# 'ENGINE': 'django.db.backends.sqlite3',  
43 -# 'NAME': '/path/to/colab.sqlite3',  
44 -# }}  
45 -# }}  
46 -  
47 -## Disable indexing  
48 -ROBOTS_NOINDEX = False  
49 -  
50 -LOGGING = {{  
51 - 'version': 1,  
52 -  
53 - 'handlers': {{  
54 - 'null': {{  
55 - 'level': 'DEBUG',  
56 - 'class': 'logging.NullHandler',  
57 - }},  
58 - }},  
59 -  
60 - 'loggers': {{  
61 - 'colab.mailman': {{  
62 - 'handlers': ['null'],  
63 - 'propagate': False,  
64 - }},  
65 - 'haystack': {{  
66 - 'handlers': ['null'],  
67 - 'propagate': False,  
68 - }},  
69 - 'pysolr': {{  
70 - 'handlers': ['null'],  
71 - 'propagate': False,  
72 - }},  
73 - }},  
74 -}}  
75 -  
76 -  
77 -## Gitlab plugin - Put this in plugins.d/gitlab.py to actiate ##  
78 -# from django.utils.translation import ugettext_lazy as _  
79 -# from colab.plugins.utils.menu import colab_url_factory  
80 -#  
81 -# name = 'colab.plugins.gitlab'  
82 -# verbose_name = 'Gitlab Proxy'  
83 -#  
84 -# upstream = 'localhost'  
85 -# #middlewares = []  
86 -#  
87 -# urls = {{  
88 -# 'include': 'colab.plugins.gitlab.urls',  
89 -# 'namespace': 'gitlab',  
90 -# 'prefix': 'gitlab',  
91 -# }}  
92 -#  
93 -# menu_title = _('Code')  
94 -#  
95 -# url = colab_url_factory('gitlab')  
96 -#  
97 -# menu_urls = (  
98 -# url(display=_('Public Projects'), viewname='gitlab',  
99 -# kwargs={{'path': '/public/projects'}}, auth=False),  
100 -# url(display=_('Profile'), viewname='gitlab',  
101 -# kwargs={{'path': '/profile'}}, auth=True),  
102 -# url(display=_('New Project'), viewname='gitlab',  
103 -# kwargs={{'path': '/projects/new'}}, auth=True),  
104 -# url(display=_('Projects'), viewname='gitlab',  
105 -# kwargs={{'path': '/dashboard/projects'}}, auth=True),  
106 -# url(display=_('Groups'), viewname='gitlab',  
107 -# kwargs={{'path': '/profile/groups'}}, auth=True),  
108 -# url(display=_('Issues'), viewname='gitlab',  
109 -# kwargs={{'path': '/dashboard/issues'}}, auth=True),  
110 -# url(display=_('Merge Requests'), viewname='gitlab',  
111 -# kwargs={{'path': '/merge_requests'}}, auth=True),  
112 -#  
113 -# )  
114 -"""  
115 -  
116 -  
117 -def initconfig():  
118 - chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'  
119 - secret_key = get_random_string(50, chars)  
120 - print(CONFIG_TEMPLATE.format(secret_key=secret_key))  
colab/queue/__init__.py 0 → 100644
colab/queue/command.py 0 → 100644
@@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
  1 +from __future__ import absolute_import
  2 +
  3 +import celery
  4 +import os
  5 +import sys
  6 +
  7 +from django.core.management.base import BaseCommand
  8 +
  9 +DB_SHARED_THREAD = """\
  10 +DatabaseWrapper objects created in a thread can only \
  11 +be used in that same thread. The object with alias '%s' \
  12 +was created in thread id %s and this is thread id %s.\
  13 +"""
  14 +
  15 +
  16 +def patch_thread_ident():
  17 + # monkey patch django.
  18 + # This patch make sure that we use real threads to get the ident which
  19 + # is going to happen if we are using gevent or eventlet.
  20 + # -- patch taken from gunicorn
  21 + if getattr(patch_thread_ident, 'called', False):
  22 + return
  23 + try:
  24 + from django.db.backends import BaseDatabaseWrapper, DatabaseError
  25 +
  26 + if 'validate_thread_sharing' in BaseDatabaseWrapper.__dict__:
  27 + import thread
  28 + _get_ident = thread.get_ident
  29 +
  30 + __old__init__ = BaseDatabaseWrapper.__init__
  31 +
  32 + def _init(self, *args, **kwargs):
  33 + __old__init__(self, *args, **kwargs)
  34 + self._thread_ident = _get_ident()
  35 +
  36 + def _validate_thread_sharing(self):
  37 + if (not self.allow_thread_sharing
  38 + and self._thread_ident != _get_ident()):
  39 + raise DatabaseError(
  40 + DB_SHARED_THREAD % (
  41 + self.alias, self._thread_ident, _get_ident()),
  42 + )
  43 +
  44 + BaseDatabaseWrapper.__init__ = _init
  45 + BaseDatabaseWrapper.validate_thread_sharing = \
  46 + _validate_thread_sharing
  47 +
  48 + patch_thread_ident.called = True
  49 + except ImportError:
  50 + pass
  51 +patch_thread_ident()
  52 +
  53 +
  54 +class CeleryCommand(BaseCommand):
  55 + options = BaseCommand.option_list
  56 + skip_opts = ['--app', '--loader', '--config']
  57 + keep_base_opts = False
  58 +
  59 + def get_version(self):
  60 + return 'celery %s' % (celery.__version__)
  61 +
  62 + def execute(self, *args, **options):
  63 + broker = options.get('broker')
  64 + if broker:
  65 + self.set_broker(broker)
  66 + super(CeleryCommand, self).execute(*args, **options)
  67 +
  68 + def set_broker(self, broker):
  69 + os.environ['CELERY_BROKER_URL'] = broker
  70 +
  71 + def run_from_argv(self, argv):
  72 + self.handle_default_options(argv[2:])
  73 + return super(CeleryCommand, self).run_from_argv(argv)
  74 +
  75 + def handle_default_options(self, argv):
  76 + acc = []
  77 + broker = None
  78 + for i, arg in enumerate(argv):
  79 + if '--settings=' in arg:
  80 + _, settings_module = arg.split('=')
  81 + os.environ['DJANGO_SETTINGS_MODULE'] = settings_module
  82 + elif '--pythonpath=' in arg:
  83 + _, pythonpath = arg.split('=')
  84 + sys.path.insert(0, pythonpath)
  85 + elif '--broker=' in arg:
  86 + _, broker = arg.split('=')
  87 + elif arg == '-b':
  88 + broker = argv[i + 1]
  89 + else:
  90 + acc.append(arg)
  91 + if broker:
  92 + self.set_broker(broker)
  93 + return argv if self.keep_base_opts else acc
  94 +
  95 + def die(self, msg):
  96 + sys.stderr.write(msg)
  97 + sys.stderr.write('\n')
  98 + sys.exit()
  99 +
  100 + @property
  101 + def option_list(self):
  102 + return [x for x in self.options
  103 + if x._long_opts[0] not in self.skip_opts]
colab/settings.py
@@ -49,6 +49,7 @@ INSTALLED_APPS = ( @@ -49,6 +49,7 @@ INSTALLED_APPS = (
49 'taggit', 49 'taggit',
50 50
51 # Own apps 51 # Own apps
  52 + 'colab',
52 'colab.home', 53 'colab.home',
53 'colab.plugins', 54 'colab.plugins',
54 'colab.super_archives', 55 'colab.super_archives',
colab/utils/runner.py 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +
  2 +import os
  3 +
  4 +from django.core.management import ManagementUtility
  5 +
  6 +
  7 +def execute_from_command_line(argv=None):
  8 + """
  9 + A simple method that runs a ManagementUtility.
  10 + """
  11 + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "colab.settings")
  12 +
  13 + utility = ManagementUtility(argv)
  14 + utility.execute()
@@ -55,8 +55,7 @@ setup( @@ -55,8 +55,7 @@ setup(
55 packages=find_packages(exclude=EXCLUDE_FROM_PACKAGES), 55 packages=find_packages(exclude=EXCLUDE_FROM_PACKAGES),
56 include_package_data=True, 56 include_package_data=True,
57 entry_points={'console_scripts': [ 57 entry_points={'console_scripts': [
58 - 'colab-admin = colab.management:execute_from_command_line',  
59 - 'colab-init-config = colab.management:initconfig', 58 + 'colab-admin = colab.utils.runner:execute_from_command_line',
60 ]}, 59 ]},
61 zip_safe=False, 60 zip_safe=False,
62 long_description=open('README.rst').read(), 61 long_description=open('README.rst').read(),
vagrant/provision.sh
@@ -36,7 +36,7 @@ sudo mkdir -p /etc/colab @@ -36,7 +36,7 @@ sudo mkdir -p /etc/colab
36 sudo chown vagrant:vagrant /etc/colab 36 sudo chown vagrant:vagrant /etc/colab
37 37
38 if [ ! -s /etc/colab/settings.py ]; then 38 if [ ! -s /etc/colab/settings.py ]; then
39 - colab-init-config > /etc/colab/settings.py 39 + colab-admin initconfig > /etc/colab/settings.py
40 fi 40 fi
41 41
42 colab-admin migrate 42 colab-admin migrate