##// END OF EJS Templates
tg: use FullStackApplicationConfigurator instead of deprecated setup_tg_wsgi_app and AppConfig
Mads Kiilerich -
r8290:27d9ca0c default
parent child Browse files
Show More
@@ -1,192 +1,194 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # This program is free software: you can redistribute it and/or modify
2 # This program is free software: you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation, either version 3 of the License, or
4 # the Free Software Foundation, either version 3 of the License, or
5 # (at your option) any later version.
5 # (at your option) any later version.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU General Public License
12 # You should have received a copy of the GNU General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 """
14 """
15 Global configuration file for TurboGears2 specific settings in Kallithea.
15 Global configuration file for TurboGears2 specific settings in Kallithea.
16
16
17 This file complements the .ini file.
17 This file complements the .ini file.
18 """
18 """
19
19
20 import logging
20 import logging
21 import os
21 import os
22 import platform
22 import platform
23 import sys
23 import sys
24
24
25 import alembic.config
25 import alembic.config
26 import mercurial
26 import mercurial
27 import tg
27 import tg
28 from alembic.migration import MigrationContext
28 from alembic.migration import MigrationContext
29 from alembic.script.base import ScriptDirectory
29 from alembic.script.base import ScriptDirectory
30 from sqlalchemy import create_engine
30 from sqlalchemy import create_engine
31 from tg.configuration import AppConfig
31 from tg import FullStackApplicationConfigurator
32
32
33 import kallithea.lib.locale
33 import kallithea.lib.locale
34 import kallithea.model.base
34 import kallithea.model.base
35 import kallithea.model.meta
35 import kallithea.model.meta
36 from kallithea.lib import celerypylons
36 from kallithea.lib import celerypylons
37 from kallithea.lib.middleware.https_fixup import HttpsFixup
37 from kallithea.lib.middleware.https_fixup import HttpsFixup
38 from kallithea.lib.middleware.permanent_repo_url import PermanentRepoUrl
38 from kallithea.lib.middleware.permanent_repo_url import PermanentRepoUrl
39 from kallithea.lib.middleware.simplegit import SimpleGit
39 from kallithea.lib.middleware.simplegit import SimpleGit
40 from kallithea.lib.middleware.simplehg import SimpleHg
40 from kallithea.lib.middleware.simplehg import SimpleHg
41 from kallithea.lib.middleware.wrapper import RequestWrapper
41 from kallithea.lib.middleware.wrapper import RequestWrapper
42 from kallithea.lib.utils import check_git_version, load_rcextensions, set_app_settings, set_indexer_config, set_vcs_config
42 from kallithea.lib.utils import check_git_version, load_rcextensions, set_app_settings, set_indexer_config, set_vcs_config
43 from kallithea.lib.utils2 import asbool
43 from kallithea.lib.utils2 import asbool
44 from kallithea.model import db
44 from kallithea.model import db
45
45
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 base_config = AppConfig(**{
50 base_config = FullStackApplicationConfigurator()
51
52 base_config.update_blueprint({
51 'package': kallithea,
53 'package': kallithea,
52
54
53 # Rendering Engines Configuration
55 # Rendering Engines Configuration
54 'renderers': [
56 'renderers': [
55 'json',
57 'json',
56 'mako',
58 'mako',
57 ],
59 ],
58 'default_renderer': 'mako',
60 'default_renderer': 'mako',
59 'use_dotted_templatenames': False,
61 'use_dotted_templatenames': False,
60
62
61 # Configure Sessions, store data as JSON to avoid pickle security issues
63 # Configure Sessions, store data as JSON to avoid pickle security issues
62 'session.enabled': True,
64 'session.enabled': True,
63 'session.data_serializer': 'json',
65 'session.data_serializer': 'json',
64
66
65 # Configure the base SQLALchemy Setup
67 # Configure the base SQLALchemy Setup
66 'use_sqlalchemy': True,
68 'use_sqlalchemy': True,
67 'model': kallithea.model.base,
69 'model': kallithea.model.base,
68 'DBSession': kallithea.model.meta.Session,
70 'DBSession': kallithea.model.meta.Session,
69
71
70 # Configure App without an authentication backend.
72 # Configure App without an authentication backend.
71 'auth_backend': None,
73 'auth_backend': None,
72
74
73 # Use custom error page for these errors. By default, Turbogears2 does not add
75 # Use custom error page for these errors. By default, Turbogears2 does not add
74 # 400 in this list.
76 # 400 in this list.
75 # Explicitly listing all is considered more robust than appending to defaults,
77 # Explicitly listing all is considered more robust than appending to defaults,
76 # in light of possible future framework changes.
78 # in light of possible future framework changes.
77 'errorpage.status_codes': [400, 401, 403, 404],
79 'errorpage.status_codes': [400, 401, 403, 404],
78
80
79 # Disable transaction manager -- currently Kallithea takes care of transactions itself
81 # Disable transaction manager -- currently Kallithea takes care of transactions itself
80 'tm.enabled': False,
82 'tm.enabled': False,
81
83
82 # Set the default i18n source language so TG doesn't search beyond 'en' in Accept-Language.
84 # Set the default i18n source language so TG doesn't search beyond 'en' in Accept-Language.
83 'i18n.lang': 'en',
85 'i18n.lang': 'en',
84 })
86 })
85
87
86 # DebugBar, a debug toolbar for TurboGears2.
88 # DebugBar, a debug toolbar for TurboGears2.
87 # (https://github.com/TurboGears/tgext.debugbar)
89 # (https://github.com/TurboGears/tgext.debugbar)
88 # To enable it, install 'tgext.debugbar' and 'kajiki', and run Kallithea with
90 # To enable it, install 'tgext.debugbar' and 'kajiki', and run Kallithea with
89 # 'debug = true' (not in production!)
91 # 'debug = true' (not in production!)
90 # See the Kallithea documentation for more information.
92 # See the Kallithea documentation for more information.
91 try:
93 try:
92 from tgext.debugbar import enable_debugbar
94 from tgext.debugbar import enable_debugbar
93 import kajiki # only to check its existence
95 import kajiki # only to check its existence
94 assert kajiki
96 assert kajiki
95 except ImportError:
97 except ImportError:
96 pass
98 pass
97 else:
99 else:
98 base_config['renderers'].append('kajiki')
100 base_config['renderers'].append('kajiki')
99 enable_debugbar(base_config)
101 enable_debugbar(base_config)
100
102
101
103
102 def setup_configuration(app):
104 def setup_configuration(app):
103 config = app.config
105 config = app.config
104
106
105 if not kallithea.lib.locale.current_locale_is_valid():
107 if not kallithea.lib.locale.current_locale_is_valid():
106 log.error("Terminating ...")
108 log.error("Terminating ...")
107 sys.exit(1)
109 sys.exit(1)
108
110
109 # Mercurial sets encoding at module import time, so we have to monkey patch it
111 # Mercurial sets encoding at module import time, so we have to monkey patch it
110 hgencoding = config.get('hgencoding')
112 hgencoding = config.get('hgencoding')
111 if hgencoding:
113 if hgencoding:
112 mercurial.encoding.encoding = hgencoding
114 mercurial.encoding.encoding = hgencoding
113
115
114 if config.get('ignore_alembic_revision', False):
116 if config.get('ignore_alembic_revision', False):
115 log.warn('database alembic revision checking is disabled')
117 log.warn('database alembic revision checking is disabled')
116 else:
118 else:
117 dbconf = config['sqlalchemy.url']
119 dbconf = config['sqlalchemy.url']
118 alembic_cfg = alembic.config.Config()
120 alembic_cfg = alembic.config.Config()
119 alembic_cfg.set_main_option('script_location', 'kallithea:alembic')
121 alembic_cfg.set_main_option('script_location', 'kallithea:alembic')
120 alembic_cfg.set_main_option('sqlalchemy.url', dbconf)
122 alembic_cfg.set_main_option('sqlalchemy.url', dbconf)
121 script_dir = ScriptDirectory.from_config(alembic_cfg)
123 script_dir = ScriptDirectory.from_config(alembic_cfg)
122 available_heads = sorted(script_dir.get_heads())
124 available_heads = sorted(script_dir.get_heads())
123
125
124 engine = create_engine(dbconf)
126 engine = create_engine(dbconf)
125 with engine.connect() as conn:
127 with engine.connect() as conn:
126 context = MigrationContext.configure(conn)
128 context = MigrationContext.configure(conn)
127 current_heads = sorted(str(s) for s in context.get_current_heads())
129 current_heads = sorted(str(s) for s in context.get_current_heads())
128 if current_heads != available_heads:
130 if current_heads != available_heads:
129 log.error('Failed to run Kallithea:\n\n'
131 log.error('Failed to run Kallithea:\n\n'
130 'The database version does not match the Kallithea version.\n'
132 'The database version does not match the Kallithea version.\n'
131 'Please read the documentation on how to upgrade or downgrade the database.\n'
133 'Please read the documentation on how to upgrade or downgrade the database.\n'
132 'Current database version id(s): %s\n'
134 'Current database version id(s): %s\n'
133 'Expected database version id(s): %s\n'
135 'Expected database version id(s): %s\n'
134 'If you are a developer and you know what you are doing, you can add `ignore_alembic_revision = True` '
136 'If you are a developer and you know what you are doing, you can add `ignore_alembic_revision = True` '
135 'to your .ini file to skip the check.\n' % (' '.join(current_heads), ' '.join(available_heads)))
137 'to your .ini file to skip the check.\n' % (' '.join(current_heads), ' '.join(available_heads)))
136 sys.exit(1)
138 sys.exit(1)
137
139
138 # store some globals into kallithea
140 # store some globals into kallithea
139 kallithea.DEFAULT_USER_ID = db.User.get_default_user().user_id
141 kallithea.DEFAULT_USER_ID = db.User.get_default_user().user_id
140
142
141 if asbool(config.get('use_celery')):
143 if asbool(config.get('use_celery')):
142 kallithea.CELERY_APP = celerypylons.make_app()
144 kallithea.CELERY_APP = celerypylons.make_app()
143 kallithea.CONFIG = config
145 kallithea.CONFIG = config
144
146
145 load_rcextensions(root_path=config['here'])
147 load_rcextensions(root_path=config['here'])
146
148
147 set_app_settings(config)
149 set_app_settings(config)
148
150
149 instance_id = kallithea.CONFIG.get('instance_id', '*')
151 instance_id = kallithea.CONFIG.get('instance_id', '*')
150 if instance_id == '*':
152 if instance_id == '*':
151 instance_id = '%s-%s' % (platform.uname()[1], os.getpid())
153 instance_id = '%s-%s' % (platform.uname()[1], os.getpid())
152 kallithea.CONFIG['instance_id'] = instance_id
154 kallithea.CONFIG['instance_id'] = instance_id
153
155
154 # update kallithea.CONFIG with the meanwhile changed 'config'
156 # update kallithea.CONFIG with the meanwhile changed 'config'
155 kallithea.CONFIG.update(config)
157 kallithea.CONFIG.update(config)
156
158
157 # configure vcs and indexer libraries (they are supposed to be independent
159 # configure vcs and indexer libraries (they are supposed to be independent
158 # as much as possible and thus avoid importing tg.config or
160 # as much as possible and thus avoid importing tg.config or
159 # kallithea.CONFIG).
161 # kallithea.CONFIG).
160 set_vcs_config(kallithea.CONFIG)
162 set_vcs_config(kallithea.CONFIG)
161 set_indexer_config(kallithea.CONFIG)
163 set_indexer_config(kallithea.CONFIG)
162
164
163 check_git_version()
165 check_git_version()
164
166
165 kallithea.model.meta.Session.remove()
167 kallithea.model.meta.Session.remove()
166
168
167
169
168 tg.hooks.register('configure_new_app', setup_configuration)
170 tg.hooks.register('configure_new_app', setup_configuration)
169
171
170
172
171 def setup_application(app):
173 def setup_application(app):
172 config = app.config
174 config = app.config
173
175
174 # we want our low level middleware to get to the request ASAP. We don't
176 # we want our low level middleware to get to the request ASAP. We don't
175 # need any stack middleware in them - especially no StatusCodeRedirect buffering
177 # need any stack middleware in them - especially no StatusCodeRedirect buffering
176 app = SimpleHg(app, config)
178 app = SimpleHg(app, config)
177 app = SimpleGit(app, config)
179 app = SimpleGit(app, config)
178
180
179 # Enable https redirects based on HTTP_X_URL_SCHEME set by proxy
181 # Enable https redirects based on HTTP_X_URL_SCHEME set by proxy
180 if any(asbool(config.get(x)) for x in ['https_fixup', 'force_https', 'use_htsts']):
182 if any(asbool(config.get(x)) for x in ['https_fixup', 'force_https', 'use_htsts']):
181 app = HttpsFixup(app, config)
183 app = HttpsFixup(app, config)
182
184
183 app = PermanentRepoUrl(app, config)
185 app = PermanentRepoUrl(app, config)
184
186
185 # Optional and undocumented wrapper - gives more verbose request/response logging, but has a slight overhead
187 # Optional and undocumented wrapper - gives more verbose request/response logging, but has a slight overhead
186 if asbool(config.get('use_wsgi_wrapper')):
188 if asbool(config.get('use_wsgi_wrapper')):
187 app = RequestWrapper(app, config)
189 app = RequestWrapper(app, config)
188
190
189 return app
191 return app
190
192
191
193
192 tg.hooks.register('before_config', setup_application)
194 tg.hooks.register('before_wsgi_middlewares', setup_application)
@@ -1,47 +1,40 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # This program is free software: you can redistribute it and/or modify
2 # This program is free software: you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation, either version 3 of the License, or
4 # the Free Software Foundation, either version 3 of the License, or
5 # (at your option) any later version.
5 # (at your option) any later version.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU General Public License
12 # You should have received a copy of the GNU General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 """WSGI middleware initialization for the Kallithea application."""
14 """WSGI middleware initialization for the Kallithea application."""
15
15
16 from kallithea.config.app_cfg import base_config
16 from kallithea.config.app_cfg import base_config
17
17
18
18
19 __all__ = ['make_app']
19 __all__ = ['make_app']
20
20
21 load_environment = base_config.make_load_environment()
22 # Use base_config to setup the necessary PasteDeploy application factory.
23 # make_base_app will wrap the TurboGears2 app with all the middleware it needs.
24 make_base_app = base_config.setup_tg_wsgi_app(load_environment)
25
21
26
22 def make_app(global_conf, **app_conf):
27 def make_app(global_conf, full_stack=True, **app_conf):
28 """
23 """
29 Set up Kallithea with the settings found in the PasteDeploy configuration
24 Set up Kallithea with the settings found in the PasteDeploy configuration
30 file used.
25 file used.
31
26
32 :param global_conf: The global settings for Kallithea (those
27 :param global_conf: The global settings for Kallithea (those
33 defined under the ``[DEFAULT]`` section).
28 defined under the ``[DEFAULT]`` section).
34 :type global_conf: dict
35 :param full_stack: Should the whole TurboGears2 stack be set up?
36 :type full_stack: str or bool
37 :return: The Kallithea application with all the relevant middleware
29 :return: The Kallithea application with all the relevant middleware
38 loaded.
30 loaded.
39
31
40 This is the PasteDeploy factory for the Kallithea application.
32 This is the PasteDeploy factory for the Kallithea application.
41
33
42 ``app_conf`` contains all the application-specific settings (those defined
34 ``app_conf`` contains all the application-specific settings (those defined
43 under ``[app:main]``.
35 under ``[app:main]``.
44 """
36 """
45 assert app_conf.get('sqlalchemy.url') # must be called with a Kallithea .ini file, which for example must have this config option
37 assert app_conf.get('sqlalchemy.url') # must be called with a Kallithea .ini file, which for example must have this config option
46 assert global_conf.get('here') and global_conf.get('__file__') # app config should be initialized the paste way ...
38 assert global_conf.get('here') and global_conf.get('__file__') # app config should be initialized the paste way ...
47 return make_base_app(global_conf, full_stack=full_stack, **app_conf)
39
40 return base_config.make_wsgi_app(global_conf, app_conf, wrap_app=None)
General Comments 0
You need to be logged in to leave comments. Login now