backup.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #! /usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import os
  4. import dropbox
  5. import docker
  6. from dropbox.exceptions import ApiError, AuthError
  7. from docker.errors import NotFound, APIError
  8. import time
  9. DOCKER_SOCK = 'unix://var/run/docker.sock'
  10. POSTGRES_CONTAINER = 'postgres'
  11. POSTGRES_USER = 'postgres'
  12. '''
  13. '''
  14. def get_dropbox_connection():
  15. token_file = open('token', 'r')
  16. token_str = token_file.read()
  17. token_file.close()
  18. dbx = dropbox.Dropbox(token_str)
  19. try:
  20. dbx.users_get_current_account()
  21. return dbx
  22. except AuthError:
  23. return None
  24. '''
  25. '''
  26. def delete_dropbox_old_folder(dbx=None):
  27. if dbx == None:
  28. return
  29. '''
  30. '''
  31. def create_folder_path():
  32. return '/' + time.strftime('%Y_%m_%d')
  33. '''
  34. '''
  35. def create_dropbox_folder(folder_path, dbx=None):
  36. if dbx == None:
  37. return False
  38. try:
  39. result = dbx.files_search('', folder_path)
  40. if len(result.matches) > 0:
  41. return False
  42. folder_metadata = dbx.files_create_folder(folder_path)
  43. print(folder_metadata)
  44. return True
  45. except ApiError:
  46. return False
  47. '''
  48. '''
  49. def upload_to_dropbox(folder_path, file):
  50. pass
  51. '''
  52. '''
  53. def get_docker_client():
  54. return docker.DockerClient(base_url=DOCKER_SOCK)
  55. '''
  56. '''
  57. def get_pg_container(docker_client):
  58. try:
  59. pg_container = docker_client.containers.get(POSTGRES_CONTAINER)
  60. return pg_container
  61. except (NotFound, APIError):
  62. return None
  63. '''
  64. '''
  65. def list_postgres_databases(docker_client):
  66. pg_container = get_pg_container(docker_client)
  67. if pg_container is None or pg_container.status == 'exited':
  68. return []
  69. command = "psql -U %s -t -c 'SELECT datname FROM pg_database'" % POSTGRES_USER
  70. result = pg_container.exec_run(command)
  71. if result.exit_code == -1:
  72. return []
  73. output = result.output.split('\n')
  74. output = map(lambda x: x.strip(), output)
  75. output = filter(lambda x: x != '', output)
  76. BLACK_LIST = ['postgres', 'template1', 'template0']
  77. output = filter(lambda x: x not in BLACK_LIST, output)
  78. return output
  79. '''
  80. '''
  81. def create_postgres_backup(database, docker_client):
  82. pg_container = get_pg_container(docker_client)
  83. if pg_container is None or pg_container.status == 'exited':
  84. return (False, None)
  85. tmp_file = '%s_%s.tar' % (database, time.strftime('%Y-%m-%d_%H:%M:%S'))
  86. command = 'pg_dump -U %s -d %s -F tar -C -b -c -f %s' % (POSTGRES_USER, database, tmp_file)
  87. result = pg_container.exec_run(command)
  88. if result.exit_code == -1:
  89. (False, tmp_file)
  90. return (True, tmp_file)
  91. '''
  92. '''
  93. def delete_backup_file(backup_name, docker_client):
  94. pg_container = get_pg_container(docker_client)
  95. if pg_container is None or pg_container.status == 'exited':
  96. return False
  97. command = 'rm %s' % backup_name
  98. result = pg_container.exec_run(command)
  99. if result.exit_code == -1:
  100. return False
  101. print(result.output)
  102. return True
  103. '''
  104. '''
  105. def run_backup():
  106. # 1. get connection
  107. dbx = get_dropbox_connection()
  108. # 2. create folder name
  109. folder_path = create_folder_path()
  110. # 3. create dropbox folder
  111. create_ok = create_dropbox_folder(folder_path, dbx)
  112. # 4. get docker client
  113. docker_client = get_docker_client()
  114. # 5. list database
  115. databases = list_postgres_databases(docker_client)
  116. # 6. backup databases
  117. for db in databases:
  118. (backup_ok, backup_name) = create_postgres_backup(db, docker_client)
  119. if not backup_ok:
  120. if backup_name:
  121. delete_backup_file(backup_name, docker_client)
  122. continue
  123. upload_to_dropbox(folder_path)
  124. delete_backup_file(backup_name, docker_client)
  125. time.sleep(1)
  126. docker_client.close()
  127. # run_backup()
  128. c = get_docker_client()
  129. (ok, name) = create_postgres_backup('test_01', c)
  130. print(ok)
  131. print(name)
  132. delete_backup_file(name, c)
  133. c.close()