Only reload apache only when strictly necessary
This commit is contained in:
parent
79ae1a79b0
commit
525d38750e
12
TODO.md
12
TODO.md
|
@ -286,6 +286,14 @@ https://code.djangoproject.com/ticket/24576
|
||||||
# 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?
|
||||||
# php version update should trigger webiste upgrade (wrapper name/fpm config for apache), public root and other config also needs apache to execute
|
|
||||||
* 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?
|
||||||
# Delete webapps deletes wrapper that may be used for other sites, maybe merging webapps is a bad idea after all?
|
* replace unique_name by natural_key?
|
||||||
|
* do not require contact or create default
|
||||||
|
* 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
|
||||||
|
* fpm reload starts new pools?
|
||||||
|
* more processes for webmail, or use fpm pool
|
||||||
|
* rename resource.monitors to resource.backends ?
|
||||||
|
|
||||||
|
* abstract model classes enabling overriding?
|
||||||
|
|
|
@ -142,27 +142,28 @@ def collect(instance, action, **kwargs):
|
||||||
operations = kwargs.get('operations', set())
|
operations = kwargs.get('operations', set())
|
||||||
route_cache = kwargs.get('route_cache', {})
|
route_cache = kwargs.get('route_cache', {})
|
||||||
for backend_cls in ServiceBackend.get_backends():
|
for backend_cls in ServiceBackend.get_backends():
|
||||||
# Check if there exists a related instance to be executed for this backend
|
# Check if there exists a related instance to be executed for this backend and action
|
||||||
instances = []
|
instances = []
|
||||||
if backend_cls.is_main(instance):
|
if action in backend_cls.actions:
|
||||||
instances = [(instance, action)]
|
if backend_cls.is_main(instance):
|
||||||
else:
|
instances = [(instance, action)]
|
||||||
candidate = backend_cls.get_related(instance)
|
else:
|
||||||
if candidate:
|
candidate = backend_cls.get_related(instance)
|
||||||
if candidate.__class__.__name__ == 'ManyRelatedManager':
|
if candidate:
|
||||||
if 'pk_set' in kwargs:
|
if candidate.__class__.__name__ == 'ManyRelatedManager':
|
||||||
# m2m_changed signal
|
if 'pk_set' in kwargs:
|
||||||
candidates = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
# m2m_changed signal
|
||||||
|
candidates = kwargs['model'].objects.filter(pk__in=kwargs['pk_set'])
|
||||||
|
else:
|
||||||
|
candidates = candidate.all()
|
||||||
else:
|
else:
|
||||||
candidates = candidate.all()
|
candidates = [candidate]
|
||||||
else:
|
for candidate in candidates:
|
||||||
candidates = [candidate]
|
# Check if a delete for candidate is in operations
|
||||||
for candidate in candidates:
|
delete_mock = Operation(backend_cls, candidate, Operation.DELETE)
|
||||||
# Check if a delete for candidate is in operations
|
if delete_mock not in operations:
|
||||||
delete_mock = Operation(backend_cls, candidate, Operation.DELETE)
|
# related objects with backend.model trigger save()
|
||||||
if delete_mock not in operations:
|
instances.append((candidate, Operation.SAVE))
|
||||||
# related objects with backend.model trigger save()
|
|
||||||
instances.append((candidate, Operation.SAVE))
|
|
||||||
for selected, iaction in instances:
|
for selected, iaction in instances:
|
||||||
# Maintain consistent state of operations based on save/delete behaviour
|
# Maintain consistent state of operations based on save/delete behaviour
|
||||||
# Prevent creating a deleted selected by deleting existing saves
|
# Prevent creating a deleted selected by deleting existing saves
|
||||||
|
|
|
@ -10,11 +10,9 @@ def run_monitor(modeladmin, request, queryset):
|
||||||
async = modeladmin.model.monitor.__defaults__[0]
|
async = modeladmin.model.monitor.__defaults__[0]
|
||||||
logs = set()
|
logs = set()
|
||||||
for resource in queryset:
|
for resource in queryset:
|
||||||
results = resource.monitor()
|
rlogs = resource.monitor()
|
||||||
if not async:
|
if not async:
|
||||||
for result in results:
|
logs = logs.union(set([str(rlog.pk) for rlog in rlogs]))
|
||||||
if hasattr(result, 'log'):
|
|
||||||
logs.add(str(result.log.pk))
|
|
||||||
modeladmin.log_change(request, resource, _("Run monitors"))
|
modeladmin.log_change(request, resource, _("Run monitors"))
|
||||||
if async:
|
if async:
|
||||||
num = len(queryset)
|
num = len(queryset)
|
||||||
|
|
|
@ -42,7 +42,7 @@ class ServiceMonitor(ServiceBackend):
|
||||||
from .models import MonitorData
|
from .models import MonitorData
|
||||||
try:
|
try:
|
||||||
return MonitorData.objects.filter(content_type=self.content_type,
|
return MonitorData.objects.filter(content_type=self.content_type,
|
||||||
object_id=object_id).latest()
|
monitor=type(self).get_name(), object_id=object_id).latest()
|
||||||
except MonitorData.DoesNotExist:
|
except MonitorData.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ def monitor(resource_id, ids=None, async=True):
|
||||||
|
|
||||||
resource = Resource.objects.get(pk=resource_id)
|
resource = Resource.objects.get(pk=resource_id)
|
||||||
resource_model = resource.content_type.model_class()
|
resource_model = resource.content_type.model_class()
|
||||||
operations = []
|
logs = []
|
||||||
# Execute monitors
|
# Execute monitors
|
||||||
for monitor_name in resource.monitors:
|
for monitor_name in resource.monitors:
|
||||||
backend = ServiceMonitor.get_backend(monitor_name)
|
backend = ServiceMonitor.get_backend(monitor_name)
|
||||||
|
@ -28,10 +28,9 @@ def monitor(resource_id, ids=None, async=True):
|
||||||
monitorings = []
|
monitorings = []
|
||||||
for obj in model.objects.filter(**kwargs):
|
for obj in model.objects.filter(**kwargs):
|
||||||
op = Operation(backend, obj, Operation.MONITOR)
|
op = Operation(backend, obj, Operation.MONITOR)
|
||||||
operations.append(op)
|
|
||||||
monitorings.append(op)
|
monitorings.append(op)
|
||||||
# TODO async=True only when running with celery
|
# TODO async=True only when running with celery
|
||||||
Operation.execute(monitorings, async=async)
|
logs += Operation.execute(monitorings, async=async)
|
||||||
|
|
||||||
kwargs = {'id__in': ids} if ids else {}
|
kwargs = {'id__in': ids} if ids else {}
|
||||||
# Update used resources and trigger resource exceeded and revovery
|
# Update used resources and trigger resource exceeded and revovery
|
||||||
|
@ -50,4 +49,4 @@ def monitor(resource_id, ids=None, async=True):
|
||||||
op = Operation(backend, obj, Operation.RECOVERY)
|
op = Operation(backend, obj, Operation.RECOVERY)
|
||||||
triggers.append(op)
|
triggers.append(op)
|
||||||
Operation.execute(triggers)
|
Operation.execute(triggers)
|
||||||
return operations
|
return logs
|
||||||
|
|
|
@ -33,7 +33,7 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
echo -e "${fpm_config}" | diff -N -I'^\s*;;' %(fpm_path)s -
|
echo -e "${fpm_config}" | diff -N -I'^\s*;;' %(fpm_path)s -
|
||||||
} || {
|
} || {
|
||||||
echo -e "${fpm_config}" > %(fpm_path)s
|
echo -e "${fpm_config}" > %(fpm_path)s
|
||||||
UPDATEDFPM=1
|
UPDATED_FPM=1
|
||||||
}
|
}
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
|
@ -46,7 +46,10 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
echo -e "${wrapper}" | diff -N -I'^\s*#' %(wrapper_path)s -
|
echo -e "${wrapper}" | diff -N -I'^\s*#' %(wrapper_path)s -
|
||||||
} || {
|
} || {
|
||||||
echo -e "${wrapper}" > %(wrapper_path)s
|
echo -e "${wrapper}" > %(wrapper_path)s
|
||||||
[[ ${UPDATED_APACHE} -eq 0 ]] && UPDATED_APACHE=%(is_mounted)i
|
if [[ %(is_mounted)i -eq 1 ]]; then
|
||||||
|
# Reload fcgid wrapper
|
||||||
|
pkill -SIGHUP -U %(user)s "^%(php_binary)s$" || true
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
|
@ -93,15 +96,14 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
if [[ $UPDATEDFPM == 1 ]]; then
|
if [[ $UPDATED_FPM -eq 1 ]]; then
|
||||||
service php5-fpm reload
|
service php5-fpm reload
|
||||||
service php5-fpm start
|
|
||||||
fi
|
fi
|
||||||
# Coordinate apache restart with apache backend
|
# Coordinate apache restart with apache backend
|
||||||
locked=1
|
locked=1
|
||||||
state="$(grep -v 'PHPBackend' /dev/shm/restart.apache2)" || locked=0
|
state="$(grep -v 'PHPBackend' /dev/shm/restart.apache2)" || locked=0
|
||||||
echo -n "$state" > /dev/shm/restart.apache2
|
echo -n "$state" > /dev/shm/restart.apache2
|
||||||
if [[ $UPDATED_APACHE == 1 ]]; then
|
if [[ $UPDATED_APACHE -eq 1 ]]; then
|
||||||
if [[ $locked == 0 ]]; then
|
if [[ $locked == 0 ]]; then
|
||||||
service apache2 reload
|
service apache2 reload
|
||||||
else
|
else
|
||||||
|
@ -151,18 +153,19 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
init_vars = [ "-d %s='%s'" % (k, v.replace("'", '"')) for k,v in init_vars.items() ]
|
init_vars = [ "-d %s='%s'" % (k, v.replace("'", '"')) for k,v in init_vars.items() ]
|
||||||
init_vars = ' \\\n '.join(init_vars)
|
init_vars = ' \\\n '.join(init_vars)
|
||||||
context.update({
|
context.update({
|
||||||
'php_binary': os.path.normpath(settings.WEBAPPS_PHP_CGI_BINARY_PATH % context),
|
'php_binary_path': os.path.normpath(settings.WEBAPPS_PHP_CGI_BINARY_PATH % context),
|
||||||
'php_rc': os.path.normpath(settings.WEBAPPS_PHP_CGI_RC_DIR % context),
|
'php_rc': os.path.normpath(settings.WEBAPPS_PHP_CGI_RC_DIR % context),
|
||||||
'php_ini_scan': os.path.normpath(settings.WEBAPPS_PHP_CGI_INI_SCAN_DIR % context),
|
'php_ini_scan': os.path.normpath(settings.WEBAPPS_PHP_CGI_INI_SCAN_DIR % context),
|
||||||
'php_init_vars': init_vars,
|
'php_init_vars': init_vars,
|
||||||
})
|
})
|
||||||
|
context['php_binary'] = os.path.basename(context['php_binary_path'])
|
||||||
return textwrap.dedent("""\
|
return textwrap.dedent("""\
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# %(banner)s
|
# %(banner)s
|
||||||
export PHPRC=%(php_rc)s
|
export PHPRC=%(php_rc)s
|
||||||
export PHP_INI_SCAN_DIR=%(php_ini_scan)s
|
export PHP_INI_SCAN_DIR=%(php_ini_scan)s
|
||||||
export PHP_FCGI_MAX_REQUESTS=%(max_requests)s
|
export PHP_FCGI_MAX_REQUESTS=%(max_requests)s
|
||||||
exec %(php_binary)s %(php_init_vars)s""") % context
|
exec %(php_binary_path)s %(php_init_vars)s""") % context
|
||||||
|
|
||||||
def get_fcgid_cmd_options(self, webapp, context):
|
def get_fcgid_cmd_options(self, webapp, context):
|
||||||
maps = {
|
maps = {
|
||||||
|
|
|
@ -88,7 +88,7 @@ class Processes(AppOption):
|
||||||
# FPM pm.max_children
|
# FPM pm.max_children
|
||||||
verbose_name = _("Number of processes")
|
verbose_name = _("Number of processes")
|
||||||
help_text = _("Maximum number of children that can be alive at the same time (a number between 0 and 9).")
|
help_text = _("Maximum number of children that can be alive at the same time (a number between 0 and 9).")
|
||||||
regex = r'^[0-9]$'
|
regex = r'^[0-9]{1,2}$'
|
||||||
group = AppOption.PROCESS
|
group = AppOption.PROCESS
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
<div id="branding"><a href="/admin/"></a><h1 id="site-name"><a href="/admin/">Pangea Hosting Management <span class="version">0.0.1a1</span></a></h1></div>
|
<div id="branding"><a href="/admin/"></a><h1 id="site-name"><a href="/admin/">Pangea Hosting Management <span class="version">0.0.1a1</span></a></h1></div>
|
||||||
{% for item in menu.children %}{% admin_tools_render_menu_item item forloop.counter %}{% endfor %}
|
{% for item in menu.children %}{% admin_tools_render_menu_item item forloop.counter %}{% endfor %}
|
||||||
<span style="float:right;color:grey;padding:10px;font-size:11px;">{% trans 'Welcome' %},
|
<span style="float:right;color:grey;padding:10px;font-size:11px;">{% trans 'Welcome' %},
|
||||||
{% url 'admin:users_user_change' user.pk as user_change_url %}
|
{% url 'admin:accounts_account_change' user.pk as user_change_url %}
|
||||||
<a href="{{ user_change_url }}" style="color:#555;"><strong>{% filter force_escape %}{% firstof user.get_short_name user.username %}{% endfilter %}</strong></a>.
|
<a href="{{ user_change_url }}" style="color:#555;"><strong>{% filter force_escape %}{% firstof user.get_short_name user.username %}{% endfilter %}</strong></a>.
|
||||||
<a href="{% url 'admin:password_change' %}" style="color:#555;">Change password</a> / <a href="{% url 'admin:logout' %}" style="color:#555;">Log out</a></span>
|
<a href="{% url 'admin:password_change' %}" style="color:#555;">Change password</a> / <a href="{% url 'admin:logout' %}" style="color:#555;">Log out</a></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue