Commits

Colin Copeland committed 13d4a9b

add multiple host support

Comments (0)

Files changed (2)

postgresql_backup-tunnel.py

                     level=logging.DEBUG)
 
 
-def comm(*args, **kwargs):
-    kwargs['shell'] = True
-    p = subprocess.Popen(*args, **kwargs)
+def build_cmd(*args, **kwargs):
+    if sudo:
+        cmd = as_user() + cmd
+    if tunnel:
+        cmd = cmd + 
+
+
+def comm(cmd, build=True, **kwargs):
+    cmd = build_cmd(cmd)
+    p = subprocess.Popen(cmd, shell=True, **kwargs)
     out, err = p.communicate()
     if err:
         pass#logging.error(err)
     f.close()
 
 
-def create_tunnel():
+def create_tunnel(port):
     return subprocess.Popen(["ssh -C -L 7777:localhost:5432 postgres@dev"],
                             shell=True,
                             stdout=subprocess.PIPE,

postgresql_backup.py

 import time
 import logging
 import subprocess
+from optparse import OptionParser
 
 
-HOST = 'root@192.168.56.3'
 ROOT = '/Users/copelco/Desktop/backup/'
-DATABASES_TO_IGNORE = ('template0',)
+DATABASES_TO_IGNORE = ('template0', )
 logging.basicConfig(stream=sys.stdout,
                     level=logging.DEBUG)
 
 
-def remote(cmd, **kwargs):
-    ssh = ['ssh', '-C', HOST] + [cmd]
-    args = [ssh]
-    logging.debug(' '.join(ssh))
-    p = subprocess.Popen(*args, **kwargs)
-    out, err = p.communicate()
-    if err:
-        logging.error(err)
-    return out, err
+usage = "usage: %prog [options] host-1 host-2 ... host-n"
+parser = OptionParser(usage=usage)
+parser.add_option("-c", "--compression", default="gzip",
+                  help="compression algorithm (gzip, bzip2, etc.)")
 
 
-def as_postgres(cmd, **kwargs):
-    return remote("sudo -u postgres " + cmd, **kwargs)
+class Backup(object):
 
+    def __init__(self, host, sudo='', compression='gzip'):
+        self.host = host
+        self.sudo_user = sudo
+        self.compression = compression
 
-def get_postgres_databases():
-    sql = "SELECT datname FROM pg_database"
-    out, err = \
-        as_postgres("psql -c '%s'" % sql, stdout=subprocess.PIPE)
-    out = out.split('\n')
-    out = out[2:len(out) - 3]
-    out = map(lambda x: x.strip(), out)
-    return out
+    def execute(self, cmd, comm=True, **kwargs):
+        if 'stderr' not in kwargs:
+            kwargs['stderr'] = subprocess.PIPE
+        logging.debug(cmd)
+        p = subprocess.Popen(cmd, shell=True, **kwargs)
+        if comm:
+            out, err = p.communicate()
+            if err:
+                logging.error(err)
+            p.out = out
+            p.err = err
+        return p
 
+    def remote(self, cmd, **kwargs):
+        args = {'host': self.host, 'cmd': cmd}
+        ssh = 'ssh -C {host} {cmd}'.format(**args)
+        return self.execute(ssh, **kwargs)
 
-def backup_postgres_globals():
-    path = os.path.join(ROOT, 'globals.gzip')
-    f = open(path, 'w+')
-    as_postgres("pg_dumpall --globals-only | gzip", stdout=f)
-    f.close()
+    def sudo(self, cmd):
+        args = {'cmd': cmd}
+        if self.sudo_user:
+            args['user'] = ' -u %(user)s '.format({'user': self.sudo_user})
+        else:
+            args = {'user': ''}
+        return 'sudo %(user)s %(cmd)s'.format(args)
 
 
-def backup_postgres_database(database):
-    path = os.path.join(ROOT, database + '.gzip')
-    f = open(path, 'w+')
-    as_postgres("pg_dump -i %s | gzip" % database, stdout=f)
-    f.close()
+class PostgreSQL(Backup):
 
+    def run(self):
+        self.backup_postgres_globals()
+        databases = filter(lambda x: x not in DATABASES_TO_IGNORE,
+                           self.get_postgres_databases())
+        logging.info('databases: %s', databases)
+        for database in databases:
+            logging.info('backing up %s' % database)
+            self.backup_postgres_database(database)
 
-databases = \
-    filter(lambda x: x not in DATABASES_TO_IGNORE, get_postgres_databases())
-logging.info('databases %s', databases)
-logging.info('backing up postgres globals')
-backup_postgres_globals()
-for database in databases:
-    logging.info('backing up %s' % database)
-    backup_postgres_database(database)
+    def get_postgres_databases(self):
+        psql = "psql -q -c \\'SELECT datname FROM pg_database\\'"
+        proc = self.remote(psql, stdout=subprocess.PIPE)
+        out = proc.out
+        out = out.split('\n')
+        out = out[2:len(out) - 3]
+        out = map(lambda x: x.strip(), out)
+        return out
+
+    def backup_postgres_globals(self):
+        filename = 'globals.{0}'.format(self.compression)
+        path = os.path.join(ROOT, filename)
+        fh = open(path, 'w+')
+        cmd = "pg_dumpall --globals-only | {0}".format(self.compression)
+        self.remote(cmd, stdout=fh)
+        fh.close()
+
+    def backup_postgres_database(self, database):
+        filename = '{0}.{1}'.format(database, self.compression)
+        path = os.path.join(ROOT, filename)
+        cmd = "pg_dump -i {0} | {1}".format(database, self.compression)
+        fh = open(path, 'w+')
+        self.remote(cmd, stdout=fh)
+        fh.close()
+
+
+def main():
+    (options, hosts) = parser.parse_args()
+    if not hosts:
+        parser.print_usage()
+        return -1
+    for host in hosts:
+        pg = PostgreSQL(host='postgres@192.168.56.3',
+                        compression=options.compression)
+        pg.run()
+
+
+if __name__ == "__main__":
+    sys.exit(main())