changeset 0:b4d371b24a5e default tip

Initial Import
author Louis Opter <kalessin@kalessin.fr>
date Thu, 01 Apr 2010 19:18:49 +0000
parents
children
files backup-lapp-app
diffstat 1 files changed, 118 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/backup-lapp-app	Thu Apr 01 19:18:49 2010 +0000
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+# The MIT License
+#
+# Copyright (c) 2010 Louis Opter <kalessin@kalessin.fr>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import errno
+import os
+import shutil
+import subprocess
+import sys
+import tarfile
+import tempfile
+
+class TempDir(object):
+    """Wrap tempfile.mkdtemp to use the with statement"""
+
+    def __init__(self):
+        pass
+
+    def __enter__(self):
+        self.__path = tempfile.mkdtemp()
+        return self.__path
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        shutil.rmtree(self.__path)
+
+def status(message):
+    print '%s: %s.' % (os.path.basename(sys.argv[0]), message)
+
+def die(message):
+    status(message)
+    status('a log has been recorded in %s' % log_path)
+    sys.exit(1)
+
+def dump_db():
+    """Use pg_dump to backup the databse into `root'"""
+
+    dump_path = os.path.join(root, db_name + '.sql')
+    with open(dump_path, 'w') as dump:
+        status('Dumping database to %s' % dump_path)
+        if subprocess.call(['sudo', '-u', 'postgres', 'pg_dump', db_name],
+                           stdout=dump, stderr=log) != 0:
+            die('error while dumping database %s to a temporary directory' % db_name)
+
+    status('Database %s dumped' % db_name)
+
+def archive():
+    """Create a tar bzipped archive of the db dump and the www-dir"""
+
+    try:
+        archive = tarfile.open(os.path.join(root, archive_name), 'w:bz2')
+        archive.add(os.path.join(root, db_name + '.sql'), db_name + '.sql')
+        archive.add(www_dir, os.path.basename(www_dir))
+        archive.close()
+    except tarfile.TarError, ex:
+        die('Can\'t create the tar archive %s: %s' % (archive_name, str(ex)))
+
+    status('Archive %s created' % archive_name)
+
+def send_archive():
+    """Send the tarball using scp or s3cmd"""
+
+    archive = os.path.join(root, archive_name)
+    if dest[0:5] == 's3://':
+        ret = subprocess.call(['s3cmd', '--acl-private', 'put', archive, dest], stdout=log, stderr=log)
+    else:
+        ret = subprocess.call(['scp', archive, dest], stdout=log, stderr=log)
+
+    if ret != 0:
+        die('error while cpying %s to %s' % (archive_name, dest))
+
+    status('Archive %s copied to "%s"' % (archive_name, dest))
+
+if __name__ == '__main__':
+    if len(sys.argv) != 4 or sys.argv[1] == '--help':
+        print 'Usage: %s db-name www-dir [[user@]host:]path|s3://bucket/[path]' % os.path.basename(sys.argv[0])
+        sys.exit(0)
+
+    # globals
+    db_name = sys.argv[1]
+    # python basename return '' for a path with an ending slash...
+    www_dir = sys.argv[2] != '/' and os.path.join('/var/www', sys.argv[2]) or '/var/www'
+    dest = sys.argv[3]
+    archive_name = 'backup-lapp-app-%s.tar.bz2' % db_name
+    log_path = os.path.join(os.getenv('TMP') or '/tmp/', db_name + '.log')
+
+    if not os.path.exists(www_dir):
+        status('%s: %s' % (www_dir, os.strerror(errno.ENOENT)))
+        sys.exit(1)
+
+    with open(log_path, 'w') as log:
+        with TempDir() as root:
+            status('root=%s' % root)
+            dump_db()
+            archive()
+            send_archive()
+    os.remove(log_path)
+
+    sys.exit(0)