Move code from gvaweb to webtasks
This change allows celery to find its tasks under the expected webtasks namespace.
This commit is contained in:
parent
9e48e068e2
commit
3b05272254
7 changed files with 38 additions and 35 deletions
10
gvaweb/webtasks/__init__.py
Normal file
10
gvaweb/webtasks/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
"""
|
||||
This module contains :py:mod:`webtasks.tasks`.
|
||||
|
||||
"""
|
||||
|
||||
__version__ = "0.2.0"
|
||||
|
||||
from webtasks.celery import app as celery_app
|
||||
|
||||
__all__ = ("celery_app",)
|
||||
13
gvaweb/webtasks/celery.py
Normal file
13
gvaweb/webtasks/celery.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
"""
|
||||
This module defines the Celery_ app for gvaweb.
|
||||
|
||||
.. _Celery: http://www.celeryproject.org/
|
||||
|
||||
"""
|
||||
from celery import Celery
|
||||
|
||||
#: The Celery application
|
||||
app = Celery("webtasks")
|
||||
|
||||
app.config_from_object("webtasks.settings", namespace="CELERY")
|
||||
app.autodiscover_tasks(["webtasks.tasks"], force=True)
|
||||
44
gvaweb/webtasks/settings.py
Normal file
44
gvaweb/webtasks/settings.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# pymode:lint_ignore=E501
|
||||
"""
|
||||
Common settings and globals.
|
||||
|
||||
"""
|
||||
|
||||
from os import environ
|
||||
|
||||
|
||||
def get_env_setting(setting):
|
||||
"""
|
||||
Get the environment setting or return exception.
|
||||
|
||||
:param str setting: name of an environment setting
|
||||
:raises ImproperlyConfigured: if the environment setting is not defined
|
||||
:return: environment setting value
|
||||
:rtype: str
|
||||
"""
|
||||
try:
|
||||
return environ[setting]
|
||||
except KeyError:
|
||||
error_msg = "Set the %s env variable" % setting
|
||||
raise AssertionError(error_msg)
|
||||
|
||||
|
||||
########## CELERY CONFIGURATION
|
||||
CELERY_TIMEZONE = "Europe/Berlin"
|
||||
CELERY_ENABLE_UTC = True
|
||||
CELERY_RESULT_PERSISTENT = True
|
||||
CELERY_TASK_RESULT_EXPIRES = None
|
||||
CELERY_ROUTES = ("gvacommon.celeryrouters.GvaRouter",)
|
||||
CELERY_ACCEPT_CONTENT = ["json"]
|
||||
CELERY_TASK_SERIALIZER = "json"
|
||||
CELERY_RESULT_SERIALIZER = "json"
|
||||
CELERY_RESULT_BACKEND = get_env_setting("GVAWEB_RESULTS_REDIS_URL")
|
||||
CELERY_BROKER_URL = get_env_setting("GVAWEB_BROKER_URL")
|
||||
########## END CELERY CONFIGURATION
|
||||
|
||||
########## GVAWEB CONFIGURATION
|
||||
GVAWEB_NGINX_SITES_AVAILABLE = get_env_setting("GVAWEB_NGINX_SITES_AVAILABLE")
|
||||
GVAWEB_NGINX_SITES_ENABLED = get_env_setting("GVAWEB_NGINX_SITES_ENABLED")
|
||||
GVAWEB_WWWUSER_MOUNT = get_env_setting("GVAWEB_WWWUSER_MOUNT")
|
||||
########## END GVAWEB CONFIGURATION
|
||||
192
gvaweb/webtasks/tasks.py
Normal file
192
gvaweb/webtasks/tasks.py
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
"""
|
||||
This module defines Celery_ tasks to manage website configurations.
|
||||
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
from tempfile import mkstemp
|
||||
|
||||
from jinja2 import Environment, PackageLoader
|
||||
|
||||
from celery import shared_task
|
||||
from celery.utils.log import get_task_logger
|
||||
from webtasks import settings
|
||||
|
||||
_LOGGER = get_task_logger(__name__)
|
||||
|
||||
SUDO_CMD = '/usr/bin/sudo'
|
||||
RM_CMD = '/bin/rm'
|
||||
LN_CMD = '/bin/ln'
|
||||
SERVICE_CMD = '/bin/systemctl'
|
||||
INSTALL_CMD = '/usr/bin/install'
|
||||
|
||||
JINJA_ENV = Environment(loader=PackageLoader('webtasks', 'templates'))
|
||||
|
||||
|
||||
def _jinja_parentdomain(domain):
|
||||
return '.'.join(domain.split('.')[1:])
|
||||
|
||||
|
||||
JINJA_ENV.filters['parentdomain'] = _jinja_parentdomain
|
||||
|
||||
|
||||
def log_and_raise(exception, message, *args):
|
||||
logargs = list(args) + [exception.returncode, exception.output]
|
||||
_LOGGER.error(message + "\nreturncode: %d\noutput:\n%s", *logargs)
|
||||
raise Exception(message % args)
|
||||
|
||||
|
||||
def log_without_raise(exception, message, *args):
|
||||
logargs = list(args) + [exception.returncode, exception.output]
|
||||
_LOGGER.error(message + "\nreturncode: %d\noutput:\n%s", *logargs)
|
||||
|
||||
|
||||
def _build_vhost_config_path(sitename):
|
||||
return os.path.join(settings.GVAWEB_NGINX_SITES_AVAILABLE, sitename)
|
||||
|
||||
|
||||
def _build_enabled_vhost_path(sitename):
|
||||
return os.path.join(settings.GVAWEB_NGINX_SITES_ENABLED, sitename)
|
||||
|
||||
|
||||
def _build_document_root_path(sitename, username):
|
||||
return os.path.join(
|
||||
settings.GVAWEB_WWWUSER_MOUNT, username, sitename, 'html')
|
||||
|
||||
|
||||
def _get_template(templatename):
|
||||
return JINJA_ENV.get_template(templatename)
|
||||
|
||||
|
||||
@shared_task
|
||||
def create_web_vhost_config(username, sitename, wildcard):
|
||||
"""
|
||||
This task creates a virtual host configuration on an nginx web
|
||||
server.
|
||||
|
||||
:param str username: user who owns the site
|
||||
:param str sitename: site name
|
||||
:param boolean wildcard: designates whether this is website has a wildcard
|
||||
subdomain
|
||||
:return: :py:const:`True` if the creation finished successfully
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
config_template = _get_template('vhost.nginx')
|
||||
config_data = config_template.render(domain=sitename, wildcard=wildcard)
|
||||
config_file = None
|
||||
try:
|
||||
nginx_temp_file, filename = mkstemp()
|
||||
config_file = os.fdopen(nginx_temp_file, 'w')
|
||||
config_file.write(config_data.encode('utf8'))
|
||||
finally:
|
||||
if config_file:
|
||||
config_file.close()
|
||||
try:
|
||||
subprocess.check_output([
|
||||
SUDO_CMD, INSTALL_CMD, '-o', 'root', '-g', 'root', '-m', '0640',
|
||||
filename, _build_vhost_config_path(sitename)],
|
||||
stderr=subprocess.STDOUT)
|
||||
subprocess.check_output([
|
||||
SUDO_CMD, RM_CMD, filename], stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as cpe:
|
||||
log_and_raise(
|
||||
cpe, 'could not setup site configuration for %s', sitename)
|
||||
return True
|
||||
|
||||
|
||||
@shared_task
|
||||
def disable_web_vhost(sitename):
|
||||
"""
|
||||
This task disables a virtual host configuration on an nginx web server.
|
||||
|
||||
:param str sitename: site name
|
||||
:return: :py:const:`True` if the virtual host has been disabled
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
try:
|
||||
subprocess.check_output([
|
||||
SUDO_CMD, RM_CMD, "-f", _build_enabled_vhost_path(sitename)],
|
||||
stderr=subprocess.STDOUT)
|
||||
subprocess.check_output([
|
||||
SUDO_CMD, SERVICE_CMD, 'reload', 'nginx'],
|
||||
stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as cpe:
|
||||
log_and_raise(
|
||||
cpe, 'could not disable site configuration for %s', sitename)
|
||||
return True
|
||||
|
||||
|
||||
@shared_task
|
||||
def enable_web_vhost(sitename):
|
||||
"""
|
||||
This task enables an existing virtual host configuration on an nginx web
|
||||
server.
|
||||
|
||||
:param str sitename: site name
|
||||
:return: :py:const:`True` if the virtual host has been enabled
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
try:
|
||||
subprocess.check_output([
|
||||
SUDO_CMD, LN_CMD, '-s', '-f',
|
||||
_build_vhost_config_path(sitename),
|
||||
_build_enabled_vhost_path(sitename)],
|
||||
stderr=subprocess.STDOUT)
|
||||
subprocess.check_output([
|
||||
SUDO_CMD, SERVICE_CMD, 'restart', 'nginx'],
|
||||
stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as cpe:
|
||||
log_and_raise(
|
||||
cpe, 'could not enable site configuration for %s', sitename)
|
||||
return True
|
||||
|
||||
|
||||
@shared_task
|
||||
def delete_web_vhost_config(sitename):
|
||||
"""
|
||||
This task removes a virtual host configuration on an nginx web server.
|
||||
|
||||
:param str sitename: site name
|
||||
:return: :py:const:`True` if the configuration has been deleted
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
try:
|
||||
subprocess.check_output([
|
||||
SUDO_CMD, RM_CMD, "-f", _build_vhost_config_path(sitename)],
|
||||
stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as cpe:
|
||||
log_and_raise(
|
||||
cpe, 'could not delete site configuration for %s', sitename)
|
||||
return True
|
||||
|
||||
|
||||
@shared_task
|
||||
def create_web_php_fpm_pool_config(username):
|
||||
"""
|
||||
This task creates a PHP FPM pool configuration.
|
||||
|
||||
:param str username: user name
|
||||
:return: :py:const:`True` if the creation finished successfully
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
# TODO: implement PHP FPM docker management setup
|
||||
return True
|
||||
|
||||
|
||||
@shared_task
|
||||
def delete_web_php_fpm_pool_config(username):
|
||||
"""
|
||||
This task deletes a PHP FPM pool configuration.
|
||||
|
||||
:param str username: user name
|
||||
:return: :py:const:`True` if the pool has been deleted
|
||||
:rtype: boolean
|
||||
|
||||
"""
|
||||
# TODO: implement PHP FPM docker management removal
|
||||
return True
|
||||
23
gvaweb/webtasks/templates/vhost.nginx
Normal file
23
gvaweb/webtasks/templates/vhost.nginx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
server {
|
||||
{% if wildcard -%}
|
||||
server_name .{{ domain|parentdomain }};
|
||||
{% else -%}
|
||||
server_name {{ domain }};
|
||||
{% -endif %}
|
||||
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
access_log /var/log/nginx/{{ domain }}.access.log;
|
||||
error_log /var/log/nginx/{{ domain }}.error.log;
|
||||
|
||||
location /.well-known/acme-challenge {
|
||||
root /srv/www/acme-challenge/{{ domain }};
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# vim: ft=nginx et sw=4 ts=4 si ai
|
||||
Loading…
Add table
Add a link
Reference in a new issue