Files
@ f2900ebaac0d
Branch filter:
Location: kallithea/kallithea/config/app_cfg.py
f2900ebaac0d
8.5 KiB
text/x-python
locale: fix environment checks: LC_ALL has precedence over LC_CTYPE
'man 7 locale' describes following precedence:
If the second argument to setlocale(3) is an empty string, "", for
the default locale, it is determined using the following steps:
1. If there is a non-null environment variable LC_ALL, the value of
LC_ALL is used.
2. If an environment variable with the same name as one of the
categories above exists and is non-null, its value is used for that
category.
3. If there is a non-null environment variable LANG, the value of
LANG is used.
So, if LC_ALL is set, it is used regardless of LC_CTYPE or LANG.
Hence, when suggesting users what to change when their locale is invalid, we
should also first check LC_ALL instead of LC_CTYPE.
'man 7 locale' describes following precedence:
If the second argument to setlocale(3) is an empty string, "", for
the default locale, it is determined using the following steps:
1. If there is a non-null environment variable LC_ALL, the value of
LC_ALL is used.
2. If an environment variable with the same name as one of the
categories above exists and is non-null, its value is used for that
category.
3. If there is a non-null environment variable LANG, the value of
LANG is used.
So, if LC_ALL is set, it is used regardless of LC_CTYPE or LANG.
Hence, when suggesting users what to change when their locale is invalid, we
should also first check LC_ALL instead of LC_CTYPE.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | # -*- coding: utf-8 -*-
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Global configuration file for TurboGears2 specific settings in Kallithea.
This file complements the .ini file.
"""
import platform
import os, sys, logging
import tg
from tg import hooks
from tg.configuration import AppConfig
from tg.support.converters import asbool
import alembic.config
from alembic.script.base import ScriptDirectory
from alembic.migration import MigrationContext
from sqlalchemy import create_engine
import mercurial
from kallithea.lib.middleware.permanent_repo_url import PermanentRepoUrl
from kallithea.lib.middleware.https_fixup import HttpsFixup
from kallithea.lib.middleware.simplegit import SimpleGit
from kallithea.lib.middleware.simplehg import SimpleHg
from kallithea.lib.auth import set_available_permissions
from kallithea.lib.utils import load_rcextensions, make_ui, set_app_settings, set_vcs_config, \
set_indexer_config, check_git_version, repo2db_mapper
from kallithea.lib.utils2 import str2bool
import kallithea.model.base
from kallithea.model.scm import ScmModel
import formencode
log = logging.getLogger(__name__)
class KallitheaAppConfig(AppConfig):
# Note: AppConfig has a misleading name, as it's not the application
# configuration, but the application configurator. The AppConfig values are
# used as a template to create the actual configuration, which might
# overwrite or extend the one provided by the configurator template.
# To make it clear, AppConfig creates the config and sets into it the same
# values that AppConfig itself has. Then the values from the config file and
# gearbox options are loaded and merged into the configuration. Then an
# after_init_config(conf) method of AppConfig is called for any change that
# might depend on options provided by configuration files.
def __init__(self):
super(KallitheaAppConfig, self).__init__()
self['package'] = kallithea
self['prefer_toscawidgets2'] = False
self['use_toscawidgets'] = False
self['renderers'] = []
# Enable json in expose
self['renderers'].append('json')
# Configure template rendering
self['renderers'].append('mako')
self['default_renderer'] = 'mako'
self['use_dotted_templatenames'] = False
# Configure Sessions, store data as JSON to avoid pickle security issues
self['session.enabled'] = True
self['session.data_serializer'] = 'json'
# Configure the base SQLALchemy Setup
self['use_sqlalchemy'] = True
self['model'] = kallithea.model.base
self['DBSession'] = kallithea.model.meta.Session
# Configure App without an authentication backend.
self['auth_backend'] = None
# Use custom error page for these errors. By default, Turbogears2 does not add
# 400 in this list.
# Explicitly listing all is considered more robust than appending to defaults,
# in light of possible future framework changes.
self['errorpage.status_codes'] = [400, 401, 403, 404]
# Disable transaction manager -- currently Kallithea takes care of transactions itself
self['tm.enabled'] = False
base_config = KallitheaAppConfig()
# TODO still needed as long as we use pylonslib
sys.modules['pylons'] = tg
# DebugBar, a debug toolbar for TurboGears2.
# (https://github.com/TurboGears/tgext.debugbar)
# To enable it, install 'tgext.debugbar' and 'kajiki', and run Kallithea with
# 'debug = true' (not in production!)
# See the Kallithea documentation for more information.
try:
from tgext.debugbar import enable_debugbar
import kajiki # only to check its existence
except ImportError:
pass
else:
base_config['renderers'].append('kajiki')
enable_debugbar(base_config)
def setup_configuration(app):
config = app.config
# Verify that things work when Dulwich passes unicode paths to the file system layer.
# Note: UTF-8 is preferred, but for example ISO-8859-1 or mbcs should also work under the right cirumstances.
try:
u'\xe9'.encode(sys.getfilesystemencoding()) # Test using é (é)
except UnicodeEncodeError:
log.error("Cannot encode Unicode paths to file system encoding %r", sys.getfilesystemencoding())
for var in ['LC_ALL', 'LC_CTYPE', 'LANG']:
if var in os.environ:
val = os.environ[var]
log.error("Note: Environment variable %s is %r - perhaps change it to some other value from 'locale -a', like 'C.UTF-8' or 'en_US.UTF-8'", var, val)
break
else:
log.error("Note: No locale setting found in environment variables - perhaps set LC_CTYPE to some value from 'locale -a', like 'C.UTF-8' or 'en_US.UTF-8'")
log.error("Terminating ...")
sys.exit(1)
# Mercurial sets encoding at module import time, so we have to monkey patch it
hgencoding = config.get('hgencoding')
if hgencoding:
mercurial.encoding.encoding = hgencoding
if config.get('ignore_alembic_revision', False):
log.warn('database alembic revision checking is disabled')
else:
dbconf = config['sqlalchemy.url']
alembic_cfg = alembic.config.Config()
alembic_cfg.set_main_option('script_location', 'kallithea:alembic')
alembic_cfg.set_main_option('sqlalchemy.url', dbconf)
script_dir = ScriptDirectory.from_config(alembic_cfg)
available_heads = sorted(script_dir.get_heads())
engine = create_engine(dbconf)
with engine.connect() as conn:
context = MigrationContext.configure(conn)
current_heads = sorted(str(s) for s in context.get_current_heads())
if current_heads != available_heads:
log.error('Failed to run Kallithea:\n\n'
'The database version does not match the Kallithea version.\n'
'Please read the documentation on how to upgrade or downgrade the database.\n'
'Current database version id(s): %s\n'
'Expected database version id(s): %s\n'
'If you are a developer and you know what you are doing, you can add `ignore_alembic_revision = True` '
'to your .ini file to skip the check.\n' % (' '.join(current_heads), ' '.join(available_heads)))
sys.exit(1)
# store some globals into kallithea
kallithea.CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
kallithea.CELERY_EAGER = str2bool(config['app_conf'].get('celery.always.eager'))
kallithea.CONFIG = config
load_rcextensions(root_path=config['here'])
set_available_permissions(config)
repos_path = make_ui().configitems('paths')[0][1]
config['base_path'] = repos_path
set_app_settings(config)
instance_id = kallithea.CONFIG.get('instance_id', '*')
if instance_id == '*':
instance_id = '%s-%s' % (platform.uname()[1], os.getpid())
kallithea.CONFIG['instance_id'] = instance_id
# update kallithea.CONFIG with the meanwhile changed 'config'
kallithea.CONFIG.update(config)
# configure vcs and indexer libraries (they are supposed to be independent
# as much as possible and thus avoid importing tg.config or
# kallithea.CONFIG).
set_vcs_config(kallithea.CONFIG)
set_indexer_config(kallithea.CONFIG)
check_git_version()
hooks.register('configure_new_app', setup_configuration)
def setup_application(app):
config = app.config
# we want our low level middleware to get to the request ASAP. We don't
# need any stack middleware in them - especially no StatusCodeRedirect buffering
app = SimpleHg(app, config)
app = SimpleGit(app, config)
# Enable https redirects based on HTTP_X_URL_SCHEME set by proxy
if any(asbool(config.get(x)) for x in ['https_fixup', 'force_https', 'use_htsts']):
app = HttpsFixup(app, config)
app = PermanentRepoUrl(app, config)
return app
hooks.register('before_config', setup_application)
|