Преглед на файлове

[ADD] autoschema generation

Gogs преди 7 години
родител
ревизия
d1a0897dd5
променени са 4 файла, в които са добавени 106 реда и са изтрити 30 реда
  1. BIN
      api/files/odoo.tar
  2. 47 7
      api/resources/odoo_resource.py
  3. 32 20
      api/utils/docker_api.py
  4. 27 3
      api/utils/odoo_api.py

BIN
api/files/odoo.tar


+ 47 - 7
api/resources/odoo_resource.py

@@ -13,6 +13,9 @@ from api.utils.odoo_api import (
     create_folders,
     create_configuration,
     create_database,
+    copy_database_backup_file,
+    restore_database,
+    remove_database_backup_file,
     create_odoo_container,
     apply_permissions
 )
@@ -55,7 +58,7 @@ class OdooResource(Resource):
                 'error_message': 'name is required'
             })
 
-        # Check and get name
+        # 1. Check and get name
         name = normalize_name(name)
         name_exists = check_name(name)
 
@@ -68,10 +71,10 @@ class OdooResource(Resource):
                 'error_message': 'name is already exists'
             })
         
-        # Get port
+        # 2. Get port
         port = randomize_port()
 
-        # Folder structure create
+        # 3. Folder structure create
         folders_created = create_folders(name)
 
         if not folders_created:
@@ -83,7 +86,7 @@ class OdooResource(Resource):
                 'error_message': 'folders structure cannot be created'
             })
 
-        # Configuration create
+        # 4. Configuration create
         conf_created = create_configuration(name)
 
         if not conf_created:
@@ -95,7 +98,7 @@ class OdooResource(Resource):
                 'error_message': 'configuration cannot be created'
             })
 
-        # Database create
+        # 5. Database create
         db_created = create_database(name)
 
         if not db_created:
@@ -107,7 +110,44 @@ class OdooResource(Resource):
                 'error_message': 'database cannot be created'
             })
 
-        # Odoo create
+        # 6. Copy a database backup
+        backup_copied = copy_database_backup_file()
+
+        if not backup_copied:
+            r.issue = 'database backup cannot be copied'
+            r.status = 5
+            r.save()
+
+            return self.create_response(request, {
+                'error_message': 'database backup cannot be copied'
+            })
+        
+        # 7. Restore database schema 
+        db_restored = restore_database(name)
+        
+        if not db_restored:
+            r.issue = 'database cannot be restored'
+            r.status = 5
+            r.save()
+
+            return self.create_response(request, {
+                'error_message': 'database cannot be restored'
+            })
+
+        # 8. Remove unused bakup file
+        backup_removed = remove_database_backup_file()
+
+        if not backup_removed:
+            r.issue = 'backup cannot be removed'
+            r.status = 5
+            r.save()
+
+            return self.create_response(request, {
+                'error_message': 'backup cannot be removed'
+            })
+
+
+        # 9. Odoo create
         odoo_created = create_odoo_container(name, [port])
 
         if not odoo_created:
@@ -119,7 +159,7 @@ class OdooResource(Resource):
                 'error_message': 'odoo container cannot be created'
             })
 
-        # Apply permissions 
+        # 10. Apply permissions 
         permissions_applied = apply_permissions(name)
 
         if not permissions_applied:

+ 32 - 20
api/utils/docker_api.py

@@ -2,8 +2,10 @@
 from __future__ import unicode_literals
 from django.conf import settings
 from docker import DockerClient
-from docker.errors import DockerException, NotFound, APIError
+from docker.errors import DockerException, NotFound, APIError, ContainerError, ImageNotFound
 import time
+import tarfile as tar
+from io import BytesIO
 
 '''
 '''
@@ -49,7 +51,8 @@ def get_all_containers():
             'name': container.name,
             'image': container.image,
             'labels': container.labels,
-            'status': container.status
+            'status': container.status,
+            'attrs': container.attrs
         })
         
     return containers
@@ -68,9 +71,7 @@ def run_container(image=None, name=None, ports=[], volumes=None, net=None):
     try:
         client.containers.run(image, None, name=name, detach=True, ports=ports, volumes=volumes, network=net)
         return True
-    except NotFound:
-        return False
-    except APIError:
+    except (ContainerError, ImageNotFound, APIError):
         return False
 
 '''
@@ -100,9 +101,7 @@ def start_container(id=None):
             'labels': container.labels,
             'status': container.status
         }
-    except NotFound:
-        return None
-    except APIError:
+    except (NotFound, APIError):
         return None
 
 '''
@@ -132,9 +131,7 @@ def restart_container(id=None):
             'labels': container.labels,
             'status': container.status
         }
-    except NotFound:
-        return None
-    except APIError:
+    except (NotFound, APIError):
         return None
 
 '''
@@ -164,9 +161,7 @@ def stop_container(id=None):
             'labels': container.labels,
             'status': container.status
         }
-    except NotFound:
-        return None
-    except APIError:
+    except (NotFound, APIError):
         return None
 
 '''
@@ -182,10 +177,27 @@ def execute_command(container_id_or_name=None, command=None):
 
     try:
         container = client.containers.get(container_id_or_name)
-        container.exec_run(command)
-        
-        return True
-    except NotFound:
-        return None
-    except APIError:
+        (exit_code, unused_output) = container.exec_run(command)
+        return (False, True)[exit_code == 0]
+    except (NotFound, APIError):
         return None
+
+'''
+'''
+def copy_in(container_id_or_name=None, path=None, tarfile=None):
+    if not container_id_or_name or not path or not tarfile:
+        return False
+
+    client = get_docker_client()
+
+    if not client:
+        return False
+
+    try:
+        file = open(tarfile, 'r')
+        container = client.containers.get(container_id_or_name)
+        result = container.put_archive(path, file)
+        file.close()
+        return result
+    except (NotFound, APIError, IOError):
+        return False

+ 27 - 3
api/utils/odoo_api.py

@@ -4,7 +4,8 @@ from random import randint
 from jinja2 import Environment, PackageLoader, select_autoescape
 from api.utils.docker_api import (
     execute_command,
-    run_container
+    run_container,
+    copy_in
 )
 from api.utils.command import execute
 import os
@@ -12,6 +13,7 @@ import socket
 import time
 import unicodedata
 import stringcase
+import tarfile
 
 '''
 '''
@@ -132,7 +134,29 @@ def create_database(name=None):
     if not name:
         return False
 
-    return execute_command(settings.ODOO_DB_CONTAINER, 'createdb -U %s %s' % (settings.ODOO_DB_USER, name))
+    cmd = 'createdb -U %s %s' % (settings.ODOO_DB_USER, name)
+    return execute_command(settings.ODOO_DB_CONTAINER, cmd)
+
+'''
+'''
+def copy_database_backup_file():
+    backup_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'files', 'odoo.tar')
+    return copy_in(settings.ODOO_DB_CONTAINER, '/tmp', backup_path)
+
+'''
+'''
+def restore_database(name=None):
+    if not name:
+        return False
+
+    cmd = 'psql -U %s -d %s -f %s' % (settings.ODOO_DB_USER, name, '/tmp/odoo.sql')
+    return execute_command(settings.ODOO_DB_CONTAINER, cmd)
+
+'''
+'''
+def remove_database_backup_file():
+    cmd = 'rm -f %s' % ('/tmp/odoo.sql')
+    return execute_command(settings.ODOO_DB_CONTAINER, cmd)
 
 '''
 '''
@@ -146,6 +170,6 @@ def create_odoo_container(name=None, ports=[]):
         'mode': 'rw'
     })  , settings.ODOO_DEFAULT_FOLDERS))
 
-    run_container(settings.ODOO_IMAGE, name, ports, volumes, net=settings.DOCKER_NETWORK_NAME)
+    run_container(settings.ODOO_IMAGE, name, ports, volumes, settings.DOCKER_NETWORK_NAME)
 
     return True