diff --git a/README.rst b/README.rst index e34f4e9..ed504d3 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,9 @@ An installer which deploy a complete mail server based on Modoboa. This tool is still in beta stage, it has been tested on Debian Jessie (8) only. - /tmp partitions must be mounted without ``noexec``. +.. warning:: + + ``/tmp`` partition must be mounted without the ``noexec`` option. Usage:: @@ -26,9 +28,11 @@ By default, the following components are installed: * Dovecot * Amavis (with SpamAssassin and ClamAV) -If you want to follow details of installation process, use --debug +If you want more information about the installation process, add the +``--debug`` option to your command line. -At the end of the process, you should consider updating virus database with this command:: +At the end of the process, you should consider updating virus databases +with this command:: - freshclam - /etc/init.d/clamav-daemon restart + $ freshclam + $ service clamav-daemon restart diff --git a/modoboa_installer/scripts/dovecot.py b/modoboa_installer/scripts/dovecot.py index 9bbf8b9..3cfab68 100644 --- a/modoboa_installer/scripts/dovecot.py +++ b/modoboa_installer/scripts/dovecot.py @@ -2,7 +2,6 @@ import glob import pwd -import shutil from .. import database from .. import utils @@ -64,7 +63,7 @@ class Dovecot(base.Installer): self.get_file_path("fix_modoboa_postgres_schema.sql") ) for f in glob.glob("{}/*".format(self.get_file_path("conf.d"))): - shutil.copy(f, "{}/conf.d".format(self.config_dir)) + utils.copy_file(f, "{}/conf.d".format(self.config_dir)) def restart_daemon(self): """Restart daemon process. diff --git a/modoboa_installer/scripts/razor.py b/modoboa_installer/scripts/razor.py index 91b3fcd..035b64e 100644 --- a/modoboa_installer/scripts/razor.py +++ b/modoboa_installer/scripts/razor.py @@ -2,7 +2,6 @@ import os import pwd -import shutil import stat from .. import utils @@ -31,7 +30,8 @@ class Razor(base.Installer): path = os.path.join(self.config.get("amavis", "home_dir"), ".razor") utils.mkdir(path, stat.S_IRWXU, pw[2], pw[3]) utils.exec_cmd("razor-admin -home {} -create".format(path)) - shutil.copy(os.path.join(path, "razor-agent.conf"), self.config_dir) + utils.copy_file( + os.path.join(path, "razor-agent.conf"), self.config_dir) utils.exec_cmd("razor-admin -home {} -discover".format(path), sudo_user=user) utils.exec_cmd("razor-admin -home {} -register".format(path), diff --git a/modoboa_installer/utils.py b/modoboa_installer/utils.py index 3ce1931..6050041 100644 --- a/modoboa_installer/utils.py +++ b/modoboa_installer/utils.py @@ -2,6 +2,7 @@ import contextlib import datetime +import glob import os import shutil import string @@ -103,14 +104,31 @@ class ConfigFileTemplate(string.Template): delimiter = "%" +def backup_file(fname): + """Create a backup of a given file.""" + for f in glob.glob("{}.old.*".format(fname)): + os.unlink(f) + bak_name = "{}.old.{}".format( + fname, datetime.datetime.now().isoformat()) + shutil.copy(fname, bak_name) + + +def copy_file(src, dest): + """Copy a file to a destination and make a backup before.""" + if os.path.isdir(dest): + dest = os.path.join(dest, os.path.basename(src)) + if os.path.isfile(dest): + backup_file(dest) + shutil.copy(src, dest) + + def copy_from_template(template, dest, context): """Create and copy a configuration file from a template.""" now = datetime.datetime.now().isoformat() with open(template) as fp: buf = fp.read() - if os.path.exists(dest): - bak_name = "{}.{}.{}".format(dest, "old", now) - shutil.copy(dest, bak_name) + if os.path.isfile(dest): + backup_file(dest) with open(dest, "w") as fp: fp.write( "# This file was automatically installed on {}\n"