#! /usr/bin/python # -*- coding: utf-8 -*- import os import dropbox import docker from dropbox.exceptions import ApiError, AuthError from docker.errors import NotFound, APIError import time DOCKER_SOCK = 'unix://var/run/docker.sock' POSTGRES_CONTAINER = 'postgres' POSTGRES_USER = 'postgres' ''' ''' def get_dropbox_connection(): token_file = open('token', 'r') token_str = token_file.read() token_file.close() dbx = dropbox.Dropbox(token_str) try: dbx.users_get_current_account() return dbx except AuthError: return None ''' ''' def delete_dropbox_old_folder(dbx=None): if dbx == None: return ''' ''' def create_folder_path(): return '/' + time.strftime('%Y_%m_%d') ''' ''' def create_dropbox_folder(folder_path, dbx=None): if dbx == None: return False try: result = dbx.files_search('', folder_path) if len(result.matches) > 0: return False folder_metadata = dbx.files_create_folder(folder_path) print(folder_metadata) return True except ApiError: return False ''' ''' def upload_to_dropbox(folder_path, file): pass ''' ''' def get_docker_client(): return docker.DockerClient(base_url=DOCKER_SOCK) ''' ''' def get_pg_container(docker_client): try: pg_container = docker_client.containers.get(POSTGRES_CONTAINER) return pg_container except (NotFound, APIError): return None ''' ''' def list_postgres_databases(docker_client): pg_container = get_pg_container(docker_client) if pg_container is None or pg_container.status == 'exited': return [] command = "psql -U %s -t -c 'SELECT datname FROM pg_database'" % POSTGRES_USER result = pg_container.exec_run(command) if result.exit_code == -1: return [] output = result.output.split('\n') output = map(lambda x: x.strip(), output) output = filter(lambda x: x != '', output) BLACK_LIST = ['postgres', 'template1', 'template0'] output = filter(lambda x: x not in BLACK_LIST, output) return output ''' ''' def create_postgres_backup(database, docker_client): pg_container = get_pg_container(docker_client) if pg_container is None or pg_container.status == 'exited': return (False, None) tmp_file = '%s_%s.tar' % (database, time.strftime('%Y-%m-%d_%H:%M:%S')) command = 'pg_dump -U %s -d %s -F tar -C -b -c -f %s' % (POSTGRES_USER, database, tmp_file) result = pg_container.exec_run(command) if result.exit_code == -1: (False, tmp_file) return (True, tmp_file) ''' ''' def delete_backup_file(backup_name, docker_client): pg_container = get_pg_container(docker_client) if pg_container is None or pg_container.status == 'exited': return False command = 'rm %s' % backup_name result = pg_container.exec_run(command) if result.exit_code == -1: return False print(result.output) return True ''' ''' def run_backup(): # 1. get connection dbx = get_dropbox_connection() # 2. create folder name folder_path = create_folder_path() # 3. create dropbox folder create_ok = create_dropbox_folder(folder_path, dbx) # 4. get docker client docker_client = get_docker_client() # 5. list database databases = list_postgres_databases(docker_client) # 6. backup databases for db in databases: (backup_ok, backup_name) = create_postgres_backup(db, docker_client) if not backup_ok: if backup_name: delete_backup_file(backup_name, docker_client) continue upload_to_dropbox(folder_path) delete_backup_file(backup_name, docker_client) time.sleep(1) docker_client.close() # run_backup() c = get_docker_client() (ok, name) = create_postgres_backup('test_01', c) print(ok) print(name) delete_backup_file(name, c) c.close()