Merge branch 'release/0.0.2' into production

* release/0.0.2:
  set version number and release date
  implement delete SFTP and setup/delete for mail base directories
  remove invalid command option from setfacl call
  use full paths for invoked commands
  implement and document GVAFileException
  fix exception handling in setup_file_sftp_userdir
  fix logging string formatting
  introduce new settings GVAFILE_SFTP_DIRECTORY and GVAFILE_MAIL_DIRECTORY
  define stub tasks and implement setup_file_sftp_userdir task
This commit is contained in:
Jan Dittberner 2014-12-26 00:50:39 +01:00
commit 0e8ab16e42
6 changed files with 179 additions and 2 deletions

View file

@ -1,5 +1,8 @@
Changelog Changelog
========= =========
* :release:`0.0.2 <2014-12-26>`
* :feature:`-` implement tasks for creating and deleting SFTP and mail base directories
* :release:`0.0.1 <2014-12-25>` * :release:`0.0.1 <2014-12-25>`
* :feature:`-` initial setup of django application and celery worker * :feature:`-` initial setup of django application and celery worker

View file

@ -29,6 +29,12 @@ The project module :py:mod:`gvafile`
.. automodule:: gvafile.urls .. automodule:: gvafile.urls
:py:mod:`gvafile.exceptions`
----------------------------
.. automodule:: gvafile.exceptions
:py:mod:`gvafile.wsgi` :py:mod:`gvafile.wsgi`
---------------------- ----------------------

View file

@ -14,6 +14,7 @@
import sys import sys
import os import os
import django
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the
@ -22,6 +23,10 @@ sys.path.insert(0, os.path.abspath(os.path.join('..', 'gvafile')))
os.environ['GVAFILE_ALLOWED_HOSTS'] = 'localhost' os.environ['GVAFILE_ALLOWED_HOSTS'] = 'localhost'
os.environ['GVAFILE_SERVER_EMAIL'] = 'root@localhost' os.environ['GVAFILE_SERVER_EMAIL'] = 'root@localhost'
os.environ['GVAFILE_SFTP_DIRECTORY'] = '/home/www'
os.environ['GVAFILE_MAIL_DIRECTORY'] = '/home/mail'
django.setup()
# -- General configuration ----------------------------------------------------- # -- General configuration -----------------------------------------------------
@ -57,9 +62,9 @@ copyright = u'2014, Jan Dittberner'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '0.0.1' version = '0.0.2'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.0.1' release = '0.0.2'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View file

@ -0,0 +1,12 @@
"""
This module defines exceptions for gvafile.
"""
from __future__ import unicode_literals
class GVAFileException(Exception):
"""
Generic Exception class for gvafile.
"""

View file

@ -271,6 +271,12 @@ WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
########## END WSGI CONFIGURATION ########## END WSGI CONFIGURATION
########## GVAFILE CONFIGURATION
GVAFILE_SFTP_DIRECTORY = get_env_setting('GVAFILE_SFTP_DIRECTORY')
GVAFILE_MAIL_DIRECTORY = get_env_setting('GVAFILE_MAIL_DIRECTORY')
########## END GVAFILE CONFIGURATION
########## CELERY CONFIGURATION ########## CELERY CONFIGURATION
BROKER_URL = get_env_setting('GVAFILE_BROKER_URL') BROKER_URL = get_env_setting('GVAFILE_BROKER_URL')
CELERY_RESULT_BACKEND = 'amqp' CELERY_RESULT_BACKEND = 'amqp'

145
gvafile/osusers/tasks.py Normal file
View file

@ -0,0 +1,145 @@
"""
This module defines `Celery`_ tasks to manage file system entities.
.. _Celery: http://www.celeryproject.org/
"""
from __future__ import absolute_import, unicode_literals
import os
import subprocess
from django.conf import settings
from celery import shared_task
from celery.utils.log import get_task_logger
from gvafile.exceptions import GVAFileException
_logger = get_task_logger(__name__)
SUDO_CMD = '/usr/bin/sudo'
INSTALL_CMD = '/usr/bin/install'
SETFACL_CMD = '/usr/bin/setfacl'
RM_CMD = '/bin/rm'
def _build_sftp_directory_name(username):
"""
Constructs the SFTP directory name for a given username.
"""
return os.path.join(settings.GVAFILE_SFTP_DIRECTORY, username)
def _build_mail_directory_name(username):
"""
Constructs the mailbox directory name for a given username.
"""
return os.path.join(settings.GVAFILE_MAIL_DIRECTORY, username)
@shared_task
def setup_file_sftp_userdir(username):
"""
This task creates the home directory for an SFTP user if it does not exist
yet.
:param str username: the user name
:raises Exception: if the SFTP directory of the user cannot be created
:return: the created directory name
:rtype: str
"""
sftp_directory = _build_sftp_directory_name(username)
try:
subprocess.check_output([
SUDO_CMD, INSTALL_CMD, '-o', username, '-g', username,
'-m', '0750', '-d', sftp_directory], stderr=subprocess.STDOUT)
subprocess.check_output([
SUDO_CMD, SETFACL_CMD, '-m', 'www-data:--x',
sftp_directory], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
_logger.exception(
'could not create SFTP directory for user %s', username)
raise GVAFileException(
"could not create SFTP directory for user %s" % username)
return sftp_directory
@shared_task
def delete_file_sftp_userdir(username):
"""
This task recursively deletes the home directory of an SFTP user if it
does not exist yet.
:param str username: the user name
:raises Exception: if the SFTP directory of the user cannot be removed
:return: the removed directory name
:rtype: str
"""
sftp_directory = _build_sftp_directory_name(username)
try:
subprocess.check_output([
SUDO_CMD, RM_CMD, '-r', '-f', sftp_directory],
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
_logger.exception(
'could not remove SFTP directory for user %s', username)
raise GVAFileException(
"could not remove SFTP directory for user %s" % username)
return sftp_directory
@shared_task
def setup_file_mail_userdir(username):
"""
This task creates the mail base directory for a user if it does not exist
yet.
:param str username: the user name
:raises Exception: if the mail base directory for the user cannot be
created
:return: the created directory name
:rtype: str
"""
mail_directory = _build_mail_directory_name(username)
try:
subprocess.check_output([
SUDO_CMD, INSTALL_CMD, '-o', username, '-g', username,
'-m', '0750', '-d', mail_directory], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
_logger.exception(
'could not create mail base directory for user %s', username)
raise GVAFileException(
"could not create mail base directory for user %s" % username)
return mail_directory
@shared_task
def delete_file_mail_userdir(username):
"""
This task recursively deletes the mail base directory for a user if it
does not exist yet.
:param str username: the user name
:raises Exception: if the mail base directory of the user cannot be removed
:return: the removed directory name
:rtype: str
"""
mail_directory = _build_mail_directory_name(username)
try:
subprocess.check_output([
SUDO_CMD, RM_CMD, '-r', '-f', mail_directory],
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
_logger.exception(
'could not remove mail base directory of user %s', username)
raise GVAFileException(
"could not remove mail base directory of user %s" % username)
return mail_directory