Apache2 backend, replace FcgidWrapper directive by Alias /fcgi-bin/
This commit is contained in:
parent
525d38750e
commit
711951d1bd
5
TODO.md
5
TODO.md
|
@ -285,15 +285,12 @@ https://code.djangoproject.com/ticket/24576
|
||||||
# Apache restart fails: detect if appache running, and execute start
|
# Apache restart fails: detect if appache running, and execute start
|
||||||
# Change crons, create cron for deleted webapps and users
|
# Change crons, create cron for deleted webapps and users
|
||||||
* UNIFY PHP FPM settings name
|
* UNIFY PHP FPM settings name
|
||||||
# virtualhost name name-account?
|
# virtualhost name: name-account?
|
||||||
* add a delay to changes on the webserver apache to no overwelm it with backend executions?
|
* add a delay to changes on the webserver apache to no overwelm it with backend executions?
|
||||||
* replace unique_name by natural_key?
|
* replace unique_name by natural_key?
|
||||||
* do not require contact or create default
|
* do not require contact or create default
|
||||||
* send signals for backend triggers
|
* send signals for backend triggers
|
||||||
* monitor resources with multiple backends not possible to identify the correct last execution, allow to specify backends only once or change backend.model = 'resources.MonitorData'
|
|
||||||
* force ignore slack billing period overridig when billing
|
* force ignore slack billing period overridig when billing
|
||||||
* fpm reload starts new pools?
|
* fpm reload starts new pools?
|
||||||
* more processes for webmail, or use fpm pool
|
|
||||||
* rename resource.monitors to resource.backends ?
|
* rename resource.monitors to resource.backends ?
|
||||||
|
|
||||||
* abstract model classes enabling overriding?
|
* abstract model classes enabling overriding?
|
||||||
|
|
|
@ -57,7 +57,7 @@ class WebApp(models.Model):
|
||||||
|
|
||||||
@cached
|
@cached
|
||||||
def get_options(self):
|
def get_options(self):
|
||||||
return OrderedDict((opt.name, opt.value) for opt in self.options.all())
|
return OrderedDict((opt.name, opt.value) for opt in self.options.all().order_by('name'))
|
||||||
|
|
||||||
def get_directive(self):
|
def get_directive(self):
|
||||||
return self.type_instance.get_directive()
|
return self.type_instance.get_directive()
|
||||||
|
|
|
@ -92,9 +92,9 @@ class Processes(AppOption):
|
||||||
group = AppOption.PROCESS
|
group = AppOption.PROCESS
|
||||||
|
|
||||||
|
|
||||||
class PHPEnabledFunctions(PHPAppOption):
|
class PHPEnableFunctions(PHPAppOption):
|
||||||
name = 'enabled_functions'
|
name = 'enable_functions'
|
||||||
verbose_name = _("Enabled functions")
|
verbose_name = _("Enable functions")
|
||||||
help_text = ','.join(settings.WEBAPPS_PHP_DISABLED_FUNCTIONS)
|
help_text = ','.join(settings.WEBAPPS_PHP_DISABLED_FUNCTIONS)
|
||||||
regex = r'^[\w\.,-]+$'
|
regex = r'^[\w\.,-]+$'
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ WEBAPPS_ENABLED_OPTIONS = getattr(settings, 'WEBAPPS_ENABLED_OPTIONS', (
|
||||||
'orchestra.contrib.webapps.options.PublicRoot',
|
'orchestra.contrib.webapps.options.PublicRoot',
|
||||||
'orchestra.contrib.webapps.options.Timeout',
|
'orchestra.contrib.webapps.options.Timeout',
|
||||||
'orchestra.contrib.webapps.options.Processes',
|
'orchestra.contrib.webapps.options.Processes',
|
||||||
'orchestra.contrib.webapps.options.PHPEnabledFunctions',
|
'orchestra.contrib.webapps.options.PHPEnableFunctions',
|
||||||
'orchestra.contrib.webapps.options.PHPAllowURLInclude',
|
'orchestra.contrib.webapps.options.PHPAllowURLInclude',
|
||||||
'orchestra.contrib.webapps.options.PHPAllowURLFopen',
|
'orchestra.contrib.webapps.options.PHPAllowURLFopen',
|
||||||
'orchestra.contrib.webapps.options.PHPAutoAppendFile',
|
'orchestra.contrib.webapps.options.PHPAutoAppendFile',
|
||||||
|
|
|
@ -71,7 +71,7 @@ class PHPApp(AppType):
|
||||||
per_account=True merges all (account, webapp.type) options
|
per_account=True merges all (account, webapp.type) options
|
||||||
"""
|
"""
|
||||||
init_vars = OrderedDict()
|
init_vars = OrderedDict()
|
||||||
options = self.instance.options.all()
|
options = self.instance.options.all().order_by('name')
|
||||||
if merge:
|
if merge:
|
||||||
# Get options from the same account and php_version webapps
|
# Get options from the same account and php_version webapps
|
||||||
options = []
|
options = []
|
||||||
|
@ -84,7 +84,7 @@ class PHPApp(AppType):
|
||||||
enabled_functions = set()
|
enabled_functions = set()
|
||||||
for opt in options:
|
for opt in options:
|
||||||
if opt.name in php_options:
|
if opt.name in php_options:
|
||||||
if opt.name == 'enabled_functions':
|
if opt.name == 'enable_functions':
|
||||||
enabled_functions = enabled_functions.union(set(opt.value.split(',')))
|
enabled_functions = enabled_functions.union(set(opt.value.split(',')))
|
||||||
else:
|
else:
|
||||||
init_vars[opt.name] = opt.value
|
init_vars[opt.name] = opt.value
|
||||||
|
@ -93,7 +93,7 @@ class PHPApp(AppType):
|
||||||
for function in self.PHP_DISABLED_FUNCTIONS:
|
for function in self.PHP_DISABLED_FUNCTIONS:
|
||||||
if function not in enabled_functions:
|
if function not in enabled_functions:
|
||||||
disabled_functions.append(function)
|
disabled_functions.append(function)
|
||||||
init_vars['dissabled_functions'] = ','.join(disabled_functions)
|
init_vars['disable_functions'] = ','.join(disabled_functions)
|
||||||
timeout = self.instance.options.filter(name='timeout').first()
|
timeout = self.instance.options.filter(name='timeout').first()
|
||||||
if timeout:
|
if timeout:
|
||||||
# Give a little slack here
|
# Give a little slack here
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Apache2Backend(ServiceController):
|
||||||
|
|
||||||
def render_virtual_host(self, site, context, ssl=False):
|
def render_virtual_host(self, site, context, ssl=False):
|
||||||
context['port'] = self.HTTPS_PORT if ssl else self.HTTP_PORT
|
context['port'] = self.HTTPS_PORT if ssl else self.HTTP_PORT
|
||||||
extra_conf = self.get_content_directives(site)
|
extra_conf = self.get_content_directives(site, context)
|
||||||
directives = site.get_directives()
|
directives = site.get_directives()
|
||||||
if ssl:
|
if ssl:
|
||||||
extra_conf += self.get_ssl(directives)
|
extra_conf += self.get_ssl(directives)
|
||||||
|
@ -147,11 +147,11 @@ class Apache2Backend(ServiceController):
|
||||||
(self.__class__.__name__, method))
|
(self.__class__.__name__, method))
|
||||||
return method(context, *args)
|
return method(context, *args)
|
||||||
|
|
||||||
def get_content_directives(self, site):
|
def get_content_directives(self, site, context):
|
||||||
directives = []
|
directives = []
|
||||||
for content in site.content_set.all():
|
for content in site.content_set.all():
|
||||||
directive = content.webapp.get_directive()
|
directive = content.webapp.get_directive()
|
||||||
context = self.get_content_context(content)
|
self.set_content_context(content, context)
|
||||||
directives += self.get_directives(directive, context)
|
directives += self.get_directives(directive, context)
|
||||||
return directives
|
return directives
|
||||||
|
|
||||||
|
@ -189,15 +189,27 @@ class Apache2Backend(ServiceController):
|
||||||
def get_fcgid_directives(self, context, app_path, wrapper_path):
|
def get_fcgid_directives(self, context, app_path, wrapper_path):
|
||||||
context.update({
|
context.update({
|
||||||
'app_path': os.path.normpath(app_path),
|
'app_path': os.path.normpath(app_path),
|
||||||
'wrapper_path': wrapper_path,
|
'wrapper_name': os.path.basename(wrapper_path),
|
||||||
})
|
})
|
||||||
directives = self.get_location_filesystem_map(context)
|
directives = ''
|
||||||
|
# This Alias trick is used instead of FcgidWrapper because we don't want to define
|
||||||
|
# a new fcgid process class each time an app is mounted (num proc limits enforcement).
|
||||||
|
if 'wrapper_dir' not in context:
|
||||||
|
# fcgi-bin only needs to be defined once per vhots
|
||||||
|
context['wrapper_dir'] = os.path.dirname(wrapper_path)
|
||||||
|
directives = textwrap.dedent("""\
|
||||||
|
Alias /fcgi-bin/ %(wrapper_dir)s/
|
||||||
|
<Location /fcgi-bin/>
|
||||||
|
SetHandler fcgid-script
|
||||||
|
Options +ExecCGI
|
||||||
|
</Location>
|
||||||
|
""") % context
|
||||||
|
directives += self.get_location_filesystem_map(context)
|
||||||
directives += textwrap.dedent("""
|
directives += textwrap.dedent("""
|
||||||
ProxyPass %(location)s/ !
|
ProxyPass %(location)s/ !
|
||||||
<Directory %(app_path)s/>
|
<Directory %(app_path)s/>
|
||||||
Options +ExecCGI
|
AddHandler php-fcgi .php
|
||||||
AddHandler fcgid-script .php
|
Action php-fcgi /fcgi-bin/%(wrapper_name)s
|
||||||
FcgidWrapper %(wrapper_path)s
|
|
||||||
</Directory>""") % context
|
</Directory>""") % context
|
||||||
return [
|
return [
|
||||||
(context['location'], directives),
|
(context['location'], directives),
|
||||||
|
@ -295,7 +307,7 @@ class Apache2Backend(ServiceController):
|
||||||
def get_server_names(self, site):
|
def get_server_names(self, site):
|
||||||
server_name = None
|
server_name = None
|
||||||
server_alias = []
|
server_alias = []
|
||||||
for domain in site.domains.all():
|
for domain in site.domains.all().order_by('name'):
|
||||||
if not server_name and not domain.name.startswith('*'):
|
if not server_name and not domain.name.startswith('*'):
|
||||||
server_name = domain.name
|
server_name = domain.name
|
||||||
else:
|
else:
|
||||||
|
@ -311,29 +323,28 @@ class Apache2Backend(ServiceController):
|
||||||
'site': site,
|
'site': site,
|
||||||
'site_name': site.name,
|
'site_name': site.name,
|
||||||
'ip': settings.WEBSITES_DEFAULT_IP,
|
'ip': settings.WEBSITES_DEFAULT_IP,
|
||||||
'site_unique_name': '0-'+site.unique_name,
|
'site_unique_name': site.unique_name,
|
||||||
'user': self.get_username(site),
|
'user': self.get_username(site),
|
||||||
'group': self.get_groupname(site),
|
'group': self.get_groupname(site),
|
||||||
'server_name': server_name,
|
'server_name': server_name,
|
||||||
'server_alias': server_alias,
|
'server_alias': server_alias,
|
||||||
# TODO remove '0-'
|
'sites_enabled': "%s.conf" % os.path.join(sites_enabled, site.unique_name),
|
||||||
'sites_enabled': "%s.conf" % os.path.join(sites_enabled, '0-'+site.unique_name),
|
'sites_available': "%s.conf" % os.path.join(sites_available, site.unique_name),
|
||||||
'sites_available': "%s.conf" % os.path.join(sites_available, '0-'+site.unique_name),
|
|
||||||
'access_log': site.get_www_access_log_path(),
|
'access_log': site.get_www_access_log_path(),
|
||||||
'error_log': site.get_www_error_log_path(),
|
'error_log': site.get_www_error_log_path(),
|
||||||
'banner': self.get_banner(),
|
'banner': self.get_banner(),
|
||||||
}
|
}
|
||||||
return replace(context, "'", '"')
|
return replace(context, "'", '"')
|
||||||
|
|
||||||
def get_content_context(self, content):
|
def set_content_context(self, content, context):
|
||||||
context = self.get_context(content.website)
|
content_context = {
|
||||||
context.update({
|
|
||||||
'type': content.webapp.type,
|
'type': content.webapp.type,
|
||||||
'location': normurlpath(content.path),
|
'location': normurlpath(content.path),
|
||||||
'app_name': content.webapp.name,
|
'app_name': content.webapp.name,
|
||||||
'app_path': content.webapp.get_path(),
|
'app_path': content.webapp.get_path(),
|
||||||
})
|
}
|
||||||
return replace(context, "'", '"')
|
content_context = replace(content_context, "'", '"')
|
||||||
|
context.update(content_context)
|
||||||
|
|
||||||
|
|
||||||
class Apache2Traffic(ServiceMonitor):
|
class Apache2Traffic(ServiceMonitor):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
@ -69,8 +70,8 @@ class Website(models.Model):
|
||||||
|
|
||||||
@cached
|
@cached
|
||||||
def get_directives(self):
|
def get_directives(self):
|
||||||
directives = {}
|
directives = OrderedDict()
|
||||||
for opt in self.directives.all():
|
for opt in self.directives.all().order_by('name', 'value'):
|
||||||
try:
|
try:
|
||||||
directives[opt.name].append(opt.value)
|
directives[opt.name].append(opt.value)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -104,7 +105,7 @@ class Website(models.Model):
|
||||||
|
|
||||||
class WebsiteDirective(models.Model):
|
class WebsiteDirective(models.Model):
|
||||||
website = models.ForeignKey(Website, verbose_name=_("web site"),
|
website = models.ForeignKey(Website, verbose_name=_("web site"),
|
||||||
related_name='directives')
|
related_name='directives')
|
||||||
name = models.CharField(_("name"), max_length=128,
|
name = models.CharField(_("name"), max_length=128,
|
||||||
choices=SiteDirective.get_choices())
|
choices=SiteDirective.get_choices())
|
||||||
value = models.CharField(_("value"), max_length=256)
|
value = models.CharField(_("value"), max_length=256)
|
||||||
|
|
|
@ -64,7 +64,8 @@ class SelectPluginAdminMixin(object):
|
||||||
plugin_value = request.GET.get(self.plugin_field) or request.POST.get(self.plugin_field)
|
plugin_value = request.GET.get(self.plugin_field) or request.POST.get(self.plugin_field)
|
||||||
if not plugin_value and request.method == 'POST':
|
if not plugin_value and request.method == 'POST':
|
||||||
# HACK baceuse django add_preserved_filters removes extising queryargs
|
# HACK baceuse django add_preserved_filters removes extising queryargs
|
||||||
value = re.search(r"type=([^&^']+)[&']", request.META.get('HTTP_REFERER', ''))
|
value = re.search(r"%s=([^&^']+)[&']" % self.plugin_field,
|
||||||
|
request.META.get('HTTP_REFERER', ''))
|
||||||
if value:
|
if value:
|
||||||
plugin_value = value.groups()[0]
|
plugin_value = value.groups()[0]
|
||||||
return plugin_value
|
return plugin_value
|
||||||
|
|
Loading…
Reference in New Issue