Browse Source

[ADD] odoo container creation support

Gogs 7 years ago
parent
commit
73ab8af661

+ 9 - 6
.env

@@ -6,12 +6,15 @@ JWT_PREFIX_HEADER = 'JWT'
 JWT_SECRET_KEY = '123456789'
 DOCKER_SOCK_DIR = '/var/run/docker.sock'
 DOCKER_NETWORK = '127.0.0.1'
-ODOO_IMAGE = 'odoo:11'
+DOCKER_NETWORK_NAME = 'eiru'
+ODOO_IMAGE = 'odoo/robert:8.0'
 ODOO_ROOT_PATH = '/opt/odoo/'
-ODOO_DEFAULT_FOLDERS = 'config, custom-addons, files'
+ODOO_DEFAULT_FOLDERS = 'config: /etc/odoo, custom-addons: /mnt/extra-addons, files: /var/lib/odoo'
 ODOO_PORTS_RANGE = '10000, 30000'
 ODOO_CONF_FILENAME = 'openerp-server'
-ODOO_ADMIN_PASSWORD = '12345'
-ODOO_DB_HOST = '127.0.0.1'
-ODOO_DB_USER = 'postgres'
-ODOO_DB_PASSWORD = '54321'
+ODOO_ADMIN_PASSWORD = 'admin'
+ODOO_DB_CONTAINER = 'postgres'
+ODOO_DB_HOST = '172.20.0.2'
+ODOO_DB_PORT = '5432'
+ODOO_DB_USER = 'odoo'
+ODOO_DB_PASSWORD = 'odoo'

+ 48 - 5
api/resources/odoo_resource.py

@@ -5,10 +5,14 @@ from tastypie.resources import Resource
 from tastypie.utils import trailing_slash
 from simplejson import JSONDecodeError
 from api.utils.odoo_api import (
-    randomize_port,
+    normalize_name,
     check_name,
+    randomize_port,
     create_folders,
-    create_configuration
+    create_configuration,
+    create_database,
+    create_odoo_container,
+    apply_permissions
 )
 import simplejson as json
 
@@ -43,16 +47,55 @@ class OdooResource(Resource):
                 'error_message': 'name is required'
             })
 
+        # Check and get name
+        name = normalize_name(name)
         name_exists = check_name(name)
 
         if name_exists:
             return self.create_response(request, {
                 'error_message': 'name is already exists'
             })
+        
+        # Get port
+        port = randomize_port()
+
+        # Folder structure create
+        folders_created = create_folders(name)
+
+        if not folders_created:
+            return self.create_response(request, {
+                'error_message': 'folders structure cannot be created'
+            })
+
+        # Configuration create
+        conf_created = create_configuration(name)
+
+        if not conf_created:
+            return self.create_response(request, {
+                'error_message': 'configuration cannot be created'
+            })
+
+        # Database create
+        db_created = create_database(name)
+
+        if not db_created:
+            return self.create_response(request, {
+                'error_message': 'database cannot be created'
+            })
+
+        # Odoo create
+        odoo_created = create_odoo_container(name, [port])
+
+        if not odoo_created:
+            return self.create_response(request, {
+                'error_message': 'odoo container cannot be created'
+            })
 
-        create_folders(name)
-        create_configuration(name)
+        apply_permissions(name)
 
         return self.create_response(request, {
-            'message': 'ok'
+            'odoo': {
+                'name': name,
+                'port': port
+            }
         })

+ 2 - 0
api/templates/openerp-server.j2

@@ -5,6 +5,8 @@ data_dir = /var/lib/odoo
 admin_passwd = {{ admin_password }}
 ; csv_internal_sep = ,
 ; db_maxconn = 64
+db_host = {{ db_host }}
+db_port = {{ db_port }}
 db_name = {{ db_name }}
 db_user = {{ db_user }}
 db_password = {{ db_password }}

+ 2 - 3
api/utils/command.py

@@ -24,6 +24,5 @@ def list_files_and_folders(path, hiddens=True):
 
 '''
 '''
-def execute(command, *args):
-    print(command)
-    print(args)
+def execute(command=[]):
+    return check_output(command)

+ 40 - 0
api/utils/docker_api.py

@@ -54,6 +54,25 @@ def get_all_containers():
         
     return containers
 
+'''
+'''
+def run_container(image=None, name=None, ports=[], volumes=None, net=None):
+    if not name:
+        return False
+
+    client = get_docker_client()
+
+    if not client:
+        return False
+
+    try:
+        client.containers.run(image, None, name=name, detach=True, ports=ports, volumes=volumes, network=net)
+        return True
+    except NotFound:
+        return False
+    except APIError:
+        return False
+
 '''
 '''
 def start_container(id=None):
@@ -149,3 +168,24 @@ def stop_container(id=None):
         return None
     except APIError:
         return None
+
+'''
+'''
+def execute_command(container_id_or_name=None, command=None):
+    if not container_id_or_name or not command:
+        return None
+
+    client = get_docker_client()
+
+    if not client:
+        return None
+
+    try:
+        container = client.containers.get(container_id_or_name)
+        container.exec_run(command)
+        
+        return True
+    except NotFound:
+        return None
+    except APIError:
+        return None

+ 66 - 3
api/utils/odoo_api.py

@@ -2,9 +2,34 @@ from __future__ import unicode_literals
 from django.conf import settings
 from random import randint
 from jinja2 import Environment, PackageLoader, select_autoescape
+from api.utils.docker_api import (
+    execute_command,
+    run_container
+)
+from api.utils.command import execute
 import os
 import socket
 import time
+import unicodedata
+import stringcase
+
+'''
+'''
+def normalize_name(name = None):
+    if not name:
+        return name
+    
+    try:
+        name = unicodedata.normalize('NFKD', name)
+        name = name.encode('ASCII', 'ignore') 
+    except TypeError:
+        pass
+
+    name = stringcase.trimcase(name)
+    name = stringcase.lowercase(name)
+    name = stringcase.snakecase(name)
+
+    return name
 
 '''
 '''
@@ -18,7 +43,6 @@ def randomize_port():
 
     return port
     
-    
 '''
 '''
 def check_port(port=0):
@@ -54,10 +78,23 @@ def create_folders(name=None):
 
     folders = settings.ODOO_DEFAULT_FOLDERS
     for folder in folders:
-        full_path = os.path.join(settings.ODOO_ROOT_PATH, name, folder)
+        full_path = os.path.join(settings.ODOO_ROOT_PATH, name, folder.strip())
         os.makedirs(full_path)
         time.sleep(1)
 
+    return True
+
+'''
+'''
+def apply_permissions(name=None):
+    if not name:
+        return False
+    
+    full_path = os.path.join(settings.ODOO_ROOT_PATH, name)
+    execute(['chmod', '-Rf', '777', full_path])
+
+    return True
+
 '''
 '''
 def create_configuration(name=None):
@@ -78,6 +115,8 @@ def create_configuration(name=None):
 
     template_rendered = template.stream({
         'admin_password': settings.ODOO_ADMIN_PASSWORD, 
+        'db_host': settings.ODOO_DB_HOST,
+        'db_port': settings.ODOO_DB_PORT,
         'db_name': name, 
         'db_user': settings.ODOO_DB_USER, 
         'db_password': settings.ODOO_DB_PASSWORD
@@ -85,4 +124,28 @@ def create_configuration(name=None):
 
     template_rendered.dump(os.path.join(conf_path, settings.ODOO_CONF_FILENAME + '.conf'))
 
-    return True
+    return True
+
+'''
+'''
+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))
+
+'''
+'''
+def create_odoo_container(name=None, ports=[]):
+    if not name:
+        return False
+
+    ports = dict(map(lambda p: ('%d/tcp' % 8069, p), ports))
+    volumes = dict(map(lambda f: (os.path.join(settings.ODOO_ROOT_PATH, name, f.strip()), {
+        'bind': settings.ODOO_DEFAULT_FOLDERS[f].strip(),
+        'mode': 'rw'
+    })  , settings.ODOO_DEFAULT_FOLDERS))
+
+    run_container(settings.ODOO_IMAGE, name, ports, volumes, net=settings.DOCKER_NETWORK_NAME)
+
+    return True

+ 5 - 2
odoo_control/settings.py

@@ -80,13 +80,16 @@ JWT_ACCEPT_HEADER = config('JWT_ACCEPT_HEADER')
 JWT_PREFIX_HEADER = config('JWT_PREFIX_HEADER')
 JWT_SECRET_KEY = config('JWT_SECRET_KEY')
 DOCKER_SOCK_DIR = config('DOCKER_SOCK_DIR')
-DOCKER_NETWORK = config('DOCKER_NETWORK')
+DOCKER_NETWORK = config('DOCKER_NETWORK', '127.0.0.1')
+DOCKER_NETWORK_NAME = config('DOCKER_NETWORK_NAME', 'default')
 ODOO_IMAGE = config('ODOO_IMAGE')
 ODOO_ROOT_PATH = config('ODOO_ROOT_PATH')
-ODOO_DEFAULT_FOLDERS = config('ODOO_DEFAULT_FOLDERS', cast=Csv())
+ODOO_DEFAULT_FOLDERS = config('ODOO_DEFAULT_FOLDERS', cast=lambda x: dict([s.split(':') for s in x.split(',')]))
 ODOO_PORTS_RANGE = config('ODOO_PORTS_RANGE', cast=Csv(int))
 ODOO_CONF_FILENAME = config('ODOO_CONF_FILENAME', 'openerp-server')
 ODOO_ADMIN_PASSWORD = config('ODOO_ADMIN_PASSWORD', 'admin')
+ODOO_DB_CONTAINER = config('ODOO_DB_CONTAINER', 'postgres')
 ODOO_DB_HOST = config('ODOO_DB_HOST', 'localhost')
+ODOO_DB_PORT = config('ODOO_DB_PORT', default=5432, cast=int)
 ODOO_DB_USER = config('ODOO_DB_USER', 'postgres')
 ODOO_DB_PASSWORD = config('ODOO_DB_PASSWORD', 'root')

+ 1 - 0
requirements.txt

@@ -30,6 +30,7 @@ requests==2.18.4
 simplejson==3.13.2
 singledispatch==3.4.0.3
 six==1.11.0
+stringcase==1.2.0
 typing==3.6.4
 urllib3==1.22
 websocket-client==0.46.0