mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Merge branch 'master' into features/relay_domains
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
||||
include README.rst COPYING requirements.txt
|
||||
recursive-include modoboa *.html *.js *.css *.png *.po *.mo *.json *.gif
|
||||
recursive-include modoboa/core/templates *.tpl
|
||||
recursive-include doc *
|
||||
recursive-include modoboa/core/commands/templates *.tpl
|
||||
recursive-include doc *
|
||||
|
||||
@@ -94,7 +94,7 @@ Deployment
|
||||
`modoboa-admin.py`, a command line tool, let you deploy a
|
||||
*ready-to-use* Modoboa site using only one instruction::
|
||||
|
||||
$ modoboa-admin.py deploy modoboa_example --syncdb --collectstatic [--with-amavis]
|
||||
$ modoboa-admin.py deploy modoboa_example --syncdb --collectstatic [--with-amavis] [--dburl database-url] [--amavis_dburl database-url]
|
||||
|
||||
Just answer the few questions and you're done. You can now go to the
|
||||
:ref:`first_use` section.
|
||||
@@ -104,6 +104,31 @@ Just answer the few questions and you're done. You can now go to the
|
||||
The `--with-amavis` option must be set only if you intend to use
|
||||
the :ref:`amavis_frontend`.
|
||||
|
||||
|
||||
In case you need a **silent installation**, e.g. if you're using Salt-Stack.
|
||||
It's possible to supply the database credentials as commandline arguments.
|
||||
|
||||
.. note::
|
||||
|
||||
`--dburl database-url` for the modoboa database credentials
|
||||
`--amavis_dburl database-url` for the amavis database credentials
|
||||
|
||||
Your database-url should meet the following syntax:
|
||||
``scheme://[user:pass@][host:port]/dbname``
|
||||
|
||||
**or**
|
||||
|
||||
``sqlite:////full/path/to/your/database/file.sqlite``
|
||||
|
||||
Available `schemes` are:
|
||||
* postgres
|
||||
* postgresql
|
||||
* postgis
|
||||
* mysql
|
||||
* mysql2
|
||||
* sqlite
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
If you plan to serve Modoboa using a URL prefix, you must change the
|
||||
|
||||
@@ -25,6 +25,8 @@ variable::
|
||||
|
||||
Then, edit the ``inbox`` namespace and add the following lines::
|
||||
|
||||
inbox = yes
|
||||
|
||||
mailbox Drafts {
|
||||
auto = create
|
||||
special_use = \Drafts
|
||||
@@ -111,7 +113,7 @@ content inside::
|
||||
# Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
}
|
||||
|
||||
|
||||
userdb sql {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
@@ -149,7 +151,7 @@ PostgreSQL users
|
||||
|
||||
::
|
||||
|
||||
driver = postgresql
|
||||
driver = pgsql
|
||||
|
||||
connect = host=<postgres socket> dbname=<database> user=<user> password=<password>
|
||||
|
||||
@@ -213,7 +215,7 @@ proper permissions::
|
||||
unix_listener dict {
|
||||
mode = 0600
|
||||
user = <user owning mailboxes>
|
||||
#group =
|
||||
#group =
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,12 +394,12 @@ Finally, configure the ``sieve`` plugin by editing the
|
||||
:file:`conf.d/90-sieve.conf` file. Put the follwing caontent inside::
|
||||
|
||||
plugin {
|
||||
# Location of the active script. When ManageSieve is used this is actually
|
||||
# Location of the active script. When ManageSieve is used this is actually
|
||||
# a symlink pointing to the active script in the sieve storage directory.
|
||||
sieve = ~/.dovecot.sieve
|
||||
|
||||
#
|
||||
# The path to the directory where the personal Sieve scripts are stored. For
|
||||
# The path to the directory where the personal Sieve scripts are stored. For
|
||||
# ManageSieve this is where the uploaded scripts are stored.
|
||||
sieve_dir = ~/sieve
|
||||
}
|
||||
@@ -440,12 +442,12 @@ Use the following configuration in the :file:`/etc/postfix/main.cf` file
|
||||
virtual_transport = dovecot
|
||||
dovecot_destination_recipient_limit = 1
|
||||
|
||||
virtual_minimum_uid = <vmail user id>
|
||||
virtual_minimum_uid = <vmail user id>
|
||||
virtual_gid_maps = static:<vmail group id>
|
||||
virtual_uid_maps = static:<vmail user id>
|
||||
virtual_mailbox_base = /var/vmail
|
||||
|
||||
relay_domains =
|
||||
relay_domains =
|
||||
virtual_mailbox_domains = <driver>:/etc/postfix/sql-domains.cf
|
||||
virtual_alias_domains = <driver>:/etc/postfix/sql-domain-aliases.cf
|
||||
virtual_mailbox_maps = <driver>:/etc/postfix/sql-mailboxes.cf
|
||||
@@ -455,7 +457,7 @@ Use the following configuration in the :file:`/etc/postfix/main.cf` file
|
||||
|
||||
smtpd_recipient_restrictions =
|
||||
...
|
||||
check_recipient_access <driver>:/etc/postfix/maps/sql-maintain.cf
|
||||
check_recipient_access <driver>:/etc/postfix/sql-maintain.cf
|
||||
permit_mynetworks
|
||||
...
|
||||
|
||||
|
||||
@@ -60,4 +60,4 @@ def unset_default_topredirection(extension):
|
||||
"""
|
||||
topredirection = parameters.get_admin("DEFAULT_TOP_REDIRECTION")
|
||||
if topredirection == extension.name:
|
||||
parameters.save_admin("DEFAULT_TOP_REDIRECTION", "userprefs")
|
||||
parameters.save_admin("DEFAULT_TOP_REDIRECTION", "core")
|
||||
|
||||
@@ -17,12 +17,16 @@ def enabled_applications():
|
||||
:return: a list
|
||||
"""
|
||||
from modoboa.core.models import Extension
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from modoboa.lib.dbutils import db_table_exists
|
||||
|
||||
result = [("core", "core")]
|
||||
result = [("user", "user")]
|
||||
if db_table_exists("core_extension"):
|
||||
exts = Extension.objects.filter(enabled=True)
|
||||
result += [(ext.name, ext.name) for ext in exts]
|
||||
for ext in exts:
|
||||
extclass = exts_pool.get_extension(ext.name)
|
||||
if extclass.available_for_topredirection:
|
||||
result.append((ext.name, ext.name))
|
||||
return sorted(result, key=lambda e: e[0])
|
||||
|
||||
|
||||
@@ -98,7 +102,7 @@ class GeneralParametersForm(parameters.AdminParametersForm):
|
||||
label=ugettext_lazy("Bind password"),
|
||||
initial='',
|
||||
help_text=ugettext_lazy("The password to use when binding to the LDAP server (with 'Bind DN')"),
|
||||
widget=forms.PasswordInput,
|
||||
widget=forms.PasswordInput(render_value=True),
|
||||
required=False
|
||||
)
|
||||
|
||||
@@ -152,7 +156,7 @@ class GeneralParametersForm(parameters.AdminParametersForm):
|
||||
default_top_redirection = forms.ChoiceField(
|
||||
label=ugettext_lazy("Default top redirection"),
|
||||
choices=[],
|
||||
initial="core",
|
||||
initial="user",
|
||||
help_text=ugettext_lazy("The default redirection used when no application is specified")
|
||||
)
|
||||
|
||||
@@ -176,6 +180,13 @@ class GeneralParametersForm(parameters.AdminParametersForm):
|
||||
super(GeneralParametersForm, self).__init__(*args, **kwargs)
|
||||
self.fields["default_top_redirection"].choices = enabled_applications()
|
||||
|
||||
def clean_secret_key(self):
|
||||
if len(self.cleaned_data["secret_key"]) not in [16, 24, 32]:
|
||||
raise forms.ValidationError(
|
||||
_("Key must be either 16, 24, or 32 bytes long")
|
||||
)
|
||||
return self.cleaned_data["secret_key"]
|
||||
|
||||
def clean_ldap_user_dn_template(self):
|
||||
tpl = self.cleaned_data["ldap_user_dn_template"]
|
||||
try:
|
||||
|
||||
@@ -19,7 +19,7 @@ class Command(object):
|
||||
self._verbose = verbose
|
||||
if not settings.configured:
|
||||
settings.configure()
|
||||
self._templates_dir = "%s/commands/templates" % os.path.dirname(__file__)
|
||||
self._templates_dir = "%s/templates" % os.path.dirname(__file__)
|
||||
|
||||
def _render_template(self, tplfile, env):
|
||||
fp = open(tplfile)
|
||||
|
||||
@@ -4,19 +4,21 @@ import os
|
||||
import shutil
|
||||
import getpass
|
||||
import subprocess
|
||||
import dj_database_url
|
||||
|
||||
from django.core import management
|
||||
from django.template import Context, Template
|
||||
from modoboa.lib.sysutils import exec_cmd
|
||||
from . import Command
|
||||
from modoboa.core.commands import Command
|
||||
|
||||
dbconn_tpl = """
|
||||
'{{ conn_name }}': {
|
||||
'ENGINE': 'django.db.backends.{{ dbtype }}', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
|
||||
'NAME': '{{ dbname }}', # Or path to database file if using sqlite3.
|
||||
'USER': '{{ username }}', # Not used with sqlite3.
|
||||
'PASSWORD': '{{ password }}', # Not used with sqlite3.
|
||||
'HOST': '{{ dbhost }}', # Set to empty string for localhost. Not used with sqlite3.
|
||||
'PORT': '', # Set to empty string for default. Not used with sqlite3.{% if dbtype == 'mysql' %}
|
||||
'ENGINE': '{{ ENGINE }}',
|
||||
'NAME': '{{ NAME }}', # Or path to database file if using sqlite3.
|
||||
'USER': '{% if USER %}{{ USER }}{% endif %}', # Not used with sqlite3.
|
||||
'PASSWORD': '{% if PASSWORD %}{{ PASSWORD }}{% endif %}', # Not used with sqlite3.
|
||||
'HOST': '{% if HOST %}{{ HOST }}{% endif %}', # Set to empty string for localhost. Not used with sqlite3.
|
||||
'PORT': '{% if PORT %}{{ PORT }}{% endif %}', # Set to empty string for default. Not used with sqlite3.{% if ENGINE == 'django.db.backends.mysql' %}
|
||||
'OPTIONS' : {
|
||||
"init_command" : 'SET foreign_key_checks = 0;',
|
||||
},{% endif %}
|
||||
@@ -43,6 +45,16 @@ class DeployCommand(Command):
|
||||
'--collectstatic', action='store_true', default=False,
|
||||
help='Run django collectstatic command'
|
||||
)
|
||||
self._parser.add_argument(
|
||||
'--dburl', type=str, nargs=1, default=None,
|
||||
help='The database-url for your modoboa instance')
|
||||
self._parser.add_argument(
|
||||
'--amavis_dburl', type=str, nargs=1, default=None,
|
||||
help='The database-url for your amavis instance')
|
||||
self._parser.add_argument(
|
||||
'--domain', type=str, nargs=1, default=None,
|
||||
help='The domain under which you want to deploy modoboa')
|
||||
|
||||
|
||||
def _exec_django_command(self, name, cwd, *args):
|
||||
"""Run a django command for the freshly created project
|
||||
@@ -76,22 +88,29 @@ class DeployCommand(Command):
|
||||
"""
|
||||
print "Configuring database connection: %s" % name
|
||||
info = {'conn_name': name,
|
||||
'dbtype': raw_input('Database type (mysql, postgres or sqlite3): ')}
|
||||
if info['dbtype'] not in ['mysql', 'postgres', 'sqlite3']:
|
||||
info['dbtype'] = 'mysql'
|
||||
if info['dbtype'] == 'postgres':
|
||||
info['dbtype'] = 'postgresql_psycopg2'
|
||||
if info['dbtype'] == 'sqlite3':
|
||||
info['dbname'] = '%s.db' % name
|
||||
'ENGINE': raw_input('Database type (mysql, postgres or sqlite3): ')}
|
||||
if info['ENGINE'] not in ['mysql', 'postgres', 'sqlite3']:
|
||||
raise RuntimeError('Unsupported database engine')
|
||||
|
||||
if info['ENGINE'] == 'sqlite3':
|
||||
info['ENGINE'] = 'django.db.backends.sqlite3'
|
||||
info['NAME'] = '%s.db' % name
|
||||
return info
|
||||
if info['ENGINE'] == 'postgres':
|
||||
info['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
default_port = 5432
|
||||
else:
|
||||
default_host = 'localhost' if info['dbtype'] == 'mysql' else ''
|
||||
info['dbhost'] = \
|
||||
raw_input("Database host (default: '%s'): " % default_host)
|
||||
if info['dbhost'] == '':
|
||||
info['dbhost'] = default_host
|
||||
info['dbname'] = raw_input('Database name: ')
|
||||
info['username'] = raw_input('Username: ')
|
||||
info['password'] = getpass.getpass('Password: ')
|
||||
info['ENGINE'] = 'django.db.backends.mysql'
|
||||
default_port = 3306
|
||||
info['HOST'] = raw_input("Database host (default: 'localhost'): ")
|
||||
info['PORT'] = raw_input("Database port (default: '%s'): " % default_port)
|
||||
# leave port setting empty, if default value is supplied and
|
||||
# leave it to django
|
||||
if info['PORT'] == default_port:
|
||||
info['PORT'] = ''
|
||||
info['NAME'] = raw_input('Database name: ')
|
||||
info['USER'] = raw_input('Username: ')
|
||||
info['PASSWORD'] = getpass.getpass('Password: ')
|
||||
return info
|
||||
|
||||
def handle(self, parsed_args):
|
||||
@@ -109,13 +128,41 @@ class DeployCommand(Command):
|
||||
django14 = False
|
||||
|
||||
t = Template(dbconn_tpl)
|
||||
default_conn = t.render(Context(self.ask_db_info()))
|
||||
amavis_conn = t.render(Context(self.ask_db_info('amavis'))) \
|
||||
if parsed_args.with_amavis else None
|
||||
|
||||
allowed_host = raw_input(
|
||||
'Under which domain do you want to deploy modoboa? '
|
||||
)
|
||||
if parsed_args.dburl:
|
||||
info = dj_database_url.config(default=parsed_args.dburl[0])
|
||||
# In case the user fails to supply a valid database url, fallback to manual mode
|
||||
if not info:
|
||||
print "There was a problem with your database-url. \n"
|
||||
info = self.ask_db_info()
|
||||
#If we set this earlier, our fallback method will never be triggered
|
||||
info['conn_name'] = 'default'
|
||||
else:
|
||||
info = self.ask_db_info()
|
||||
|
||||
default_conn = t.render(Context(info))
|
||||
|
||||
if parsed_args.with_amavis:
|
||||
if parsed_args.amavis_dburl:
|
||||
amavis_info = dj_database_url.config(default=parsed_args.amavis_dburl[0])
|
||||
# In case the user fails to supply a valid database url, fallback to manual mode
|
||||
if not amavis_info:
|
||||
amavis_info = self.ask_db_info('amavis')
|
||||
#If we set this earlier, our fallback method will never be triggered
|
||||
amavis_info['conn_name'] = 'amavis'
|
||||
else:
|
||||
amavis_info = self.ask_db_info('amavis')
|
||||
|
||||
amavis_conn = t.render(Context(amavis_info))
|
||||
else:
|
||||
amavis_conn = None
|
||||
|
||||
if parsed_args.domain:
|
||||
allowed_host = parsed_args.domain[0]
|
||||
else:
|
||||
allowed_host = raw_input(
|
||||
'Under which domain do you want to deploy modoboa? '
|
||||
)
|
||||
|
||||
mod = __import__(parsed_args.name, globals(), locals(), ['settings'])
|
||||
tpl = self._render_template(
|
||||
@@ -126,15 +173,15 @@ class DeployCommand(Command):
|
||||
'allowed_host': allowed_host
|
||||
}
|
||||
)
|
||||
fp = open("%s/settings.py" % path, "w")
|
||||
fp.write(tpl)
|
||||
fp.close()
|
||||
with open("%s/settings.py" % path, "w") as fp:
|
||||
fp.write(tpl)
|
||||
shutil.copyfile(
|
||||
"%s/urls.py.tpl" % self._templates_dir, "%s/urls.py" % path
|
||||
)
|
||||
os.mkdir("%s/media" % path)
|
||||
|
||||
if parsed_args.syncdb:
|
||||
os.unlink("%s/settings.pyc" % path)
|
||||
self._exec_django_command(
|
||||
"syncdb", parsed_args.name, '--noinput'
|
||||
)
|
||||
|
||||
@@ -159,7 +159,6 @@ MODOBOA_APPS = (
|
||||
'modoboa.extensions.webmail',
|
||||
'modoboa.extensions.stats',
|
||||
'modoboa.extensions.sievefilters',
|
||||
'modoboa.extensions.stats',
|
||||
{% if not amavis_conn %}#{% endif %}'modoboa.extensions.amavis',
|
||||
)
|
||||
|
||||
@@ -167,6 +166,8 @@ INSTALLED_APPS += MODOBOA_APPS
|
||||
|
||||
AUTH_USER_MODEL = 'core.User'
|
||||
|
||||
SOUTH_TESTS_MIGRATE = False
|
||||
|
||||
#MODOBOA_CUSTOM_LOGO = os.path.join(MEDIA_URL, "custom_logo.png")
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
|
||||
@@ -15,6 +15,7 @@ class ModoExtension(object):
|
||||
url = None
|
||||
needs_media = False
|
||||
always_active = False
|
||||
available_for_topredirection = False
|
||||
|
||||
def infos(self):
|
||||
return dict(
|
||||
|
||||
@@ -35,7 +35,7 @@ def dologin(request):
|
||||
|
||||
nextlocation = request.POST.get("next", None)
|
||||
if nextlocation is None or nextlocation == "None":
|
||||
if user.group != "SimpleUsers":
|
||||
if user.group == "SimpleUsers":
|
||||
nextlocation = reverse("modoboa.lib.webutils.topredirection")
|
||||
else:
|
||||
nextlocation = reverse("domains")
|
||||
|
||||
@@ -20,6 +20,7 @@ class Amavis(ModoExtension):
|
||||
version = "1.0"
|
||||
description = ugettext_lazy("Simple amavis management frontend")
|
||||
url = "quarantine"
|
||||
available_for_topredirection = True
|
||||
|
||||
def init(self):
|
||||
"""Init function
|
||||
|
||||
@@ -11,6 +11,7 @@ class SieveFilters(ModoExtension):
|
||||
version = "1.0"
|
||||
description = ugettext_lazy("Plugin to easily create server-side filters")
|
||||
url = "sfilters"
|
||||
available_for_topredirection = True
|
||||
|
||||
def load(self):
|
||||
from .app_settings import ParametersForm, UserSettings
|
||||
|
||||
@@ -12,6 +12,7 @@ class Webmail(ModoExtension):
|
||||
version = "1.0"
|
||||
description = ugettext_lazy("Simple IMAP webmail")
|
||||
needs_media = True
|
||||
available_for_topredirection = True
|
||||
|
||||
def load(self):
|
||||
from .app_settings import ParametersForm, UserSettings
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"model": "lib.parameter",
|
||||
"fields": {
|
||||
"name": "general.DEFAULT_TOP_REDIRECTION",
|
||||
"value": "userprefs"
|
||||
"value": "user"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+5
-11
@@ -138,27 +138,21 @@ def size2integer(value):
|
||||
|
||||
@login_required
|
||||
def topredirection(request):
|
||||
"""Simple view to redirect the request when no application is specified
|
||||
"""Simple view to redirect the request when no application is specified.
|
||||
|
||||
The default "top redirection" can be specified in the *Admin >
|
||||
Settings* panel. It is the application that will be launched by
|
||||
default. Users that are not allowed to access this application
|
||||
will be redirected to the "User preferences" application.
|
||||
|
||||
This feature only applies to simple users.
|
||||
|
||||
:param request: a Request object
|
||||
"""
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.core.extensions import exts_pool
|
||||
|
||||
topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core")
|
||||
if not topredir in ["core"]:
|
||||
infos = exts_pool.get_extension_infos(topredir)
|
||||
path = infos["url"] if infos["url"] else infos["name"]
|
||||
else:
|
||||
path = "admin" # topredir
|
||||
|
||||
if topredir in ["core", "stats"] and \
|
||||
request.user.belongs_to_group('SimpleUsers'):
|
||||
path = "userprefs"
|
||||
|
||||
infos = exts_pool.get_extension_infos(topredir)
|
||||
path = infos["url"] if infos["url"] else infos["name"]
|
||||
return HttpResponseRedirect(path)
|
||||
|
||||
@@ -42,7 +42,8 @@ function modalbox(e, css, defhref, defcb, defclosecb) {
|
||||
$div.modal({show: false});
|
||||
$div.one('shown', function() {
|
||||
$(".help").popover({
|
||||
container: "#modalbox"
|
||||
container: "#modalbox",
|
||||
trigger: "hover"
|
||||
}).click(function(e) {e.preventDefault();});
|
||||
if (modalcb != undefined) {
|
||||
if (typeof modalcb === "function") modalcb(); else eval(modalcb + '()');
|
||||
@@ -308,5 +309,5 @@ $(document).ready(function() {
|
||||
$(document).on('click', 'a[data-toggle="ajaxmodal"]', modalbox);
|
||||
$(document).on('click', 'a[data-toggle="ajaxmodal-autowidth"]', modalbox_autowidth);
|
||||
$(document).on('click', '.activator', activate_widget);
|
||||
$(".help").popover().click(function(e) {e.preventDefault();});
|
||||
$(".help").popover({trigger: 'hover'}).click(function(e) {e.preventDefault();});
|
||||
});
|
||||
@@ -45,7 +45,7 @@ TwocolsNav.prototype = {
|
||||
$('#' + this.options.divid + ' input[type=radio]').click($.proxy(this.radio_clicked, this));
|
||||
$(".help").popover({
|
||||
placement: 'bottom',
|
||||
trigger: 'click'
|
||||
trigger: 'hover'
|
||||
}).click(function(e) {e.preventDefault();});
|
||||
$('#' + this.options.divid + ' select').change();
|
||||
$('#' + this.options.divid + ' input[type=radio]:checked').click();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
django
|
||||
django-reversion
|
||||
dj-database-url
|
||||
south
|
||||
lxml
|
||||
pycrypto
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
# coding: utf-8
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
import pexpect
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
|
||||
def runcmd(cmd, **kwargs):
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
shell=True, **kwargs)
|
||||
output = p.communicate()[0]
|
||||
return p.returncode, output
|
||||
from modoboa.lib.sysutils import exec_cmd
|
||||
|
||||
|
||||
class DeployTest(unittest.TestCase):
|
||||
@@ -25,19 +17,23 @@ class DeployTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
cmd = "mysqladmin -u %s -p%s create %s" % (self.dbuser, self.dbpassword, self.projname)
|
||||
code, out = runcmd(cmd)
|
||||
code, out = exec_cmd(cmd)
|
||||
self.assertEqual(code, 0)
|
||||
self.workdir = tempfile.mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
path = os.path.join(self.workdir, self.projname)
|
||||
code, output = exec_cmd("python manage.py test admin", cwd=path)
|
||||
self.assertEqual(code, 0)
|
||||
|
||||
if hasattr(self, "workdir"):
|
||||
shutil.rmtree(self.workdir)
|
||||
shutil.rmtree(self.workdir)
|
||||
child = pexpect.spawn("mysqladmin -u root -p%s drop %s" % (self.dbpassword, self.projname))
|
||||
child.expect("\[y/N\]")
|
||||
child.sendline("y")
|
||||
child.expect('Database "%s" dropped' % self.projname)
|
||||
|
||||
def test(self):
|
||||
def test_standard(self):
|
||||
timeout = 2
|
||||
cmd = "modoboa-admin.py deploy --syncdb --collectstatic %s" % self.projname
|
||||
child = pexpect.spawn(cmd, cwd=self.workdir)
|
||||
@@ -47,6 +43,8 @@ class DeployTest(unittest.TestCase):
|
||||
child.sendline(self.dbtype)
|
||||
child.expect("Database host \(default: 'localhost'\):", timeout=timeout)
|
||||
child.sendline(self.dbhost)
|
||||
child.expect("Database port \(default: '3306'\):", timeout=timeout)
|
||||
child.sendline('3306')
|
||||
child.expect("Database name:", timeout=timeout)
|
||||
child.sendline(self.projname)
|
||||
child.expect("Username:", timeout=timeout)
|
||||
@@ -59,8 +57,13 @@ class DeployTest(unittest.TestCase):
|
||||
fout.close()
|
||||
self.assertEqual(child.exitstatus, 0)
|
||||
|
||||
path = os.path.join(self.workdir, self.projname)
|
||||
code, output = runcmd("python manage.py test admin", cwd=path)
|
||||
def test_silent(self):
|
||||
dburl = "%s://%s:%s@%s/%s" \
|
||||
% (self.dbtype, self.dbuser, self.dbpassword,
|
||||
self.dbhost, self.projname)
|
||||
cmd = "modoboa-admin.py deploy --syncdb --collectstatic --dburl %s --domain %s %s" \
|
||||
% (dburl, 'localhost', self.projname)
|
||||
code, output = exec_cmd(cmd, cwd=self.workdir)
|
||||
self.assertEqual(code, 0)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user