|
@@ -7,6 +7,7 @@ import os.path
|
|
|
import docker
|
|
|
import tarfile
|
|
|
import time
|
|
|
+import logging
|
|
|
from googleapiclient.discovery import build
|
|
|
from googleapiclient.http import MediaIoBaseUpload, MediaFileUpload
|
|
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
|
@@ -23,9 +24,26 @@ ODOO_IMAGE = 'odoo/robert:8.0'
|
|
|
# ODOO_PATH = '/opt/odoo'
|
|
|
ODOO_PATH = '/home/robert'
|
|
|
|
|
|
+'''
|
|
|
+'''
|
|
|
+def configure_logging():
|
|
|
+ root_path = './logs'
|
|
|
+
|
|
|
+ if not os.path.exists(root_path):
|
|
|
+ os.mkdir(root_path)
|
|
|
+
|
|
|
+ log_name = 'backup_log_%s.txt' % datetime.now().strftime('%Y_%m_%d')
|
|
|
+ logging.basicConfig(filename=os.path.join(root_path, log_name), filemode='w', format='%(levelname)s - %(asctime)s - %(message)s', datefmt='%Y/%m/%d %H:%M:%S', level=logging.INFO)
|
|
|
+
|
|
|
+'''
|
|
|
+'''
|
|
|
+def log(message, level=logging.INFO):
|
|
|
+ logging.log(level, message)
|
|
|
+
|
|
|
'''
|
|
|
'''
|
|
|
def get_drive_service():
|
|
|
+ log('Obteniendo credenciales')
|
|
|
creds = None
|
|
|
|
|
|
if os.path.exists('token.pickle'):
|
|
@@ -54,9 +72,14 @@ def delete_drive_old_folders(service=None):
|
|
|
date_old = date_old.strftime("%Y-%m-%dT00:00:00")
|
|
|
|
|
|
query = "mimeType='application/vnd.google-apps.folder' and createdTime < '%s'" % date_old
|
|
|
- result = service.files().list(q=query, fields='files(id, name)').execute()
|
|
|
+ result = service.files().list(q=query, fields='files(id)').execute()
|
|
|
+
|
|
|
+ files = result.get('files', [])
|
|
|
|
|
|
- for item in result.get('files', []):
|
|
|
+ if len(files) > 0:
|
|
|
+ log('Eliminando copias antiguas')
|
|
|
+
|
|
|
+ for item in files:
|
|
|
service.files().delete(fileId=item.get('id')).execute()
|
|
|
|
|
|
'''
|
|
@@ -70,6 +93,8 @@ def create_drive_folder(folder_name, service=None):
|
|
|
if service == None:
|
|
|
return None
|
|
|
|
|
|
+ log('Obteniedo carpeta remota')
|
|
|
+
|
|
|
result = service.files().list(q="name='{}'".format(folder_name)).execute()
|
|
|
items = result.get('files', [])
|
|
|
|
|
@@ -96,6 +121,7 @@ def get_pg_container(docker_client):
|
|
|
pg_container = docker_client.containers.get(POSTGRES_CONTAINER)
|
|
|
return pg_container
|
|
|
except (NotFound, APIError):
|
|
|
+ log('Error al obtener el cliente de docker', logging.FATAL)
|
|
|
return None
|
|
|
|
|
|
'''
|
|
@@ -105,11 +131,14 @@ def list_postgres_databases(docker_client):
|
|
|
|
|
|
if pg_container is None or pg_container.status == 'exited':
|
|
|
return []
|
|
|
+
|
|
|
+ log('Obteniendo los nombres de base de datos')
|
|
|
|
|
|
command = "psql -U %s -t -c 'SELECT datname FROM pg_database'" % POSTGRES_USER
|
|
|
result = pg_container.exec_run(command)
|
|
|
|
|
|
if result.exit_code == -1:
|
|
|
+ log('Error al obtener los nombres de base de datos')
|
|
|
return []
|
|
|
|
|
|
output = result.output.split('\n')
|
|
@@ -128,8 +157,10 @@ def filter_databases_by_active_containers(databases, docker_client):
|
|
|
containers = docker_client.containers.list(filters={'status': 'running', 'ancestor': ODOO_IMAGE})
|
|
|
containers_name = map(lambda x: x.name, containers)
|
|
|
|
|
|
+ log('Filtrando base de datos con sistema activos')
|
|
|
return filter(lambda x: x in containers_name, databases)
|
|
|
except APIError:
|
|
|
+ log('Error al filtrar las base de datos con sistemas activos')
|
|
|
return []
|
|
|
|
|
|
'''
|
|
@@ -140,13 +171,16 @@ def create_postgres_backup(database, docker_client):
|
|
|
if pg_container is None or pg_container.status == 'exited':
|
|
|
return (False, None)
|
|
|
|
|
|
+ log('Creando copia de seguridad de la base de datos: %s' % database)
|
|
|
+
|
|
|
tmp_file = '%s_database_%s.tar' % (database, datetime.now().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)
|
|
|
+ log('Error al crear la copia de seguridad de la base de datos: %s' % database)
|
|
|
+ return (False, tmp_file)
|
|
|
|
|
|
return (True, tmp_file)
|
|
|
|
|
@@ -158,6 +192,8 @@ def create_odoo_filestore_backup(folder_name):
|
|
|
if not os.path.exists(root_path):
|
|
|
os.mkdir(root_path)
|
|
|
|
|
|
+ log('Creando copia de seguridad de los archivos adjuntos: %s' % folder_name)
|
|
|
+
|
|
|
tar_name = '%s_filestore_%s.tar' % (folder_name, datetime.now().strftime('%Y-%m-%d_%H:%M:%S'))
|
|
|
tar_path = os.path.join(root_path, tar_name)
|
|
|
filestore_path = os.path.join(ODOO_PATH, folder_name, 'files', 'filestore', folder_name)
|
|
@@ -179,6 +215,8 @@ def upload_postgres_to_drive(backup_file_name, backup_folder_id, docket_client,
|
|
|
if pg_container is None or pg_container.status == 'exited':
|
|
|
return None
|
|
|
|
|
|
+ log('Subiendo copia de seguridad de la base de datos: %s' % backup_file_name)
|
|
|
+
|
|
|
(backup_file, _) = pg_container.get_archive('/%s' % backup_file_name)
|
|
|
raw_data = BytesIO()
|
|
|
|
|
@@ -205,6 +243,7 @@ def upload_filestore_to_drive(backup_path, backup_folder_id, service):
|
|
|
return None
|
|
|
|
|
|
backup_name = os.path.basename(backup_path)
|
|
|
+ log('Subiendo copia de seguridad de los archivos adjuntos: %s' % backup_name)
|
|
|
|
|
|
backup_metadata = {
|
|
|
'name': backup_name,
|
|
@@ -223,11 +262,14 @@ def delete_postgres_backup(backup_name, docker_client):
|
|
|
|
|
|
if pg_container is None or pg_container.status == 'exited':
|
|
|
return False
|
|
|
+
|
|
|
+ log('Eliminando copia temporal de la base de datos: %s' % backup_name)
|
|
|
|
|
|
command = 'rm %s' % backup_name
|
|
|
result = pg_container.exec_run(command)
|
|
|
|
|
|
if result.exit_code == -1:
|
|
|
+ log('Error al eliminar copia temporal de la base de datos: %s' % backup_name, level=logging.FATAL)
|
|
|
return False
|
|
|
|
|
|
return True
|
|
@@ -235,11 +277,17 @@ def delete_postgres_backup(backup_name, docker_client):
|
|
|
'''
|
|
|
'''
|
|
|
def delete_filestore_backup(backup_path):
|
|
|
+ log('Eliminando copia temporal de los archivos adjuntos: %s' % os.path.basename(backup_path))
|
|
|
os.remove(backup_path)
|
|
|
|
|
|
'''
|
|
|
'''
|
|
|
def run_backup():
|
|
|
+ configure_logging()
|
|
|
+
|
|
|
+ start_time = datetime.now()
|
|
|
+ log('Iniciando backup...')
|
|
|
+
|
|
|
# 1. get connection
|
|
|
service = get_drive_service()
|
|
|
|
|
@@ -282,4 +330,7 @@ def run_backup():
|
|
|
|
|
|
docker_client.close()
|
|
|
|
|
|
+ end_time = datetime.now() - start_time
|
|
|
+ log('Backup finalizado en %s' % str(end_time))
|
|
|
+
|
|
|
run_backup()
|