gvaweb/gvaweb/webtasks/tasks.py

193 lines
5.4 KiB
Python

"""
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