|
@@ -0,0 +1,180 @@
|
|
|
+#! /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()
|