Browse Source

[ADD] write some steps to create odoo instance

robert 6 years ago
parent
commit
0399da6b1b
2 changed files with 183 additions and 70 deletions
  1. 176 69
      models/odoo_instance.py
  2. 7 1
      utils/odoo_api.py

+ 176 - 69
models/odoo_instance.py

@@ -1,7 +1,14 @@
 # -*- coding: utf-8 -*-
 from openerp import models, fields, api
-from openerp.exceptions import Warning
-from ..utils import odoo_api
+from openerp.exceptions import Warning, ValidationError
+from jinja2 import Environment as JinjaEnv, PackageLoader as JinjaLoader
+from ..utils.docker_api import get_all_external_ports
+from ..utils.command import execute
+from random import randint
+import unicodedata
+import stringcase
+import time
+import os
 
 
 class OdooInstance(models.Model):
@@ -15,6 +22,94 @@ class OdooInstance(models.Model):
         ('destroyed', 'Eliminado')
     ]
 
+    DEFAULT_DIRS = [
+        'config',
+        'custom-addons',
+        'files'
+    ]
+
+    # 'config: /etc/odoo, custom-addons: /mnt/extra-addons, files: /var/lib/odoo'
+
+    def _snakeike_name(self, 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
+
+    def _check_port_availability(self, port):
+        return port not in get_all_external_ports()
+
+    def _check_name_availability(self, name):
+        if len(name) == 0:
+            return False
+
+        root_path = self.env['ir.values'].get_default(self._name, 'odoo_root_path')
+
+        if len(root_path) == 0:
+            raise Warning('La ruta por defecto para los sistemas no está definido')
+
+        full_path = os.path.join(root_path, name)
+
+        return os.path.exists(full_path)
+
+    def _randomize_port(self):
+        ports = self.env['ir.values'].get_default(self._name, 'odoo_ports_range')
+        ports = filter(lambda x: x != '', ports.split(','))
+
+        if len(ports) == 0:
+            raise Warning('El rango de puertos para los sistemas no está definido')
+
+        port = 0
+
+        while not self._check_port_availability(port):
+            port = randint(ports[0], ports[1])
+            time.sleep(1)
+
+        return port
+
+    def _make_default_dirs(self, name):
+        root_path = self.env['ir.values'].get_default(self._name, 'odoo_root_path')
+
+        for d in self.DEFAULT_DIRS:
+            full_path = os.path.join(root_path, name, d.strip())
+            os.makedirs(full_path)
+            time.sleep(1)
+
+    def _make_config_file(self, name):
+        root_path = self.env['ir.values'].get_default(self._name, 'odoo_root_path')
+        config_path = os.path.join(root_path, name, 'config')
+
+        if not os.path.exists(config_path):
+            raise Warning('No se creó el directorio para el archivo de configuración')
+
+        env = JinjaEnv(loader=JinjaLoader('assets', 'templates'))
+        tmpl = env.get_template('openerp-server.j2')
+
+        tmpl_rendered = tmpl.stream({
+            'admin_password': 'admin',
+            'db_host': '',
+            'db_port': '',
+            'db_name': '',
+            'db_user': '',
+            'db_password': ''
+        })
+
+        tmpl_rendered.dump(os.path.join(config_path, 'openerp-config.conf'))
+        
+    def _create_database(self, name):
+        odoo_db = self.env['ir.values'].get_default(self._name, 'odoo_db_link')
+        cmd = 'createdb -U %s %s' % ('odoo', name)
+
+        return execute(cmd)
+
+
     name = fields.Char(string='Nombre', size=50)
     normalized_name = fields.Char(string='Nombre normalizado', compute='_normalize_name', size=50)
     logo = fields.Binary(string='Logo')
@@ -29,6 +124,16 @@ class OdooInstance(models.Model):
     running = fields.Boolean(string='Está online?', default=False)
     payment_plan_id = fields.Many2one(string='Plan de pago', comodel_name='payment.plan', required=True)
 
+    @api.model
+    def create(self, values):
+        snaked_name = self._snakeike_name(values.get('name'))
+        name_is_available = self._check_name_availability(snaked_name)
+
+        if not name_is_available:
+            raise ValidationError('El nombre ya está siendo usado por otro sistema')
+
+        return super(self, OdooInstance).create(values)
+
     @api.one
     @api.onchange('name')
     def _onchange_name(self):
@@ -38,79 +143,81 @@ class OdooInstance(models.Model):
     @api.one
     @api.depends('name')
     def _normalize_name(self):
-        self.normalized_name = odoo_api.snakeize_name(self.name)
+        self.normalized_name = self._snakeike_name(self.name)
 
     @api.one
     def action_activate(self):
         if self.state not in ('draft', 'suspended'):
             raise Warning('No se puede activar un sistema ya activo')
 
-        # 1. Check name
-        name_is_available = odoo_api.check_name_availability(self.normalized_name)
-
-        if not name_is_available:
-            raise Warning('El nombre ya está siendo usado por otro sistema')
-
-        # 2. Get a port
-        port_to_use = odoo_api.randomize_port()
-
-        # 3. Create dirs
-        make_ok = odoo_api.make_default_dirs(self.normalized_name)
-
-        if not make_ok:
-            raise Warning('No se pudo crear la estructura de directorios')
-
-        # 4. Create configuration file
-        config_ok = odoo_api.make_config_file(self.normalized_name)
-
-        if not config_ok:
-            raise Warning('No se pudo crear el archivo de configuración')
-
-        # 5. Create database
-        db_ok = odoo_api.create_database(self.normalized_name)
-
-        if not db_ok:
-            raise Warning('No se pudo crear la base de datos')
-
-        # 6. Copy database seed
-        seed_copied = odoo_api.copy_database_seed()
-
-        if not seed_copied:
-            raise Warning('No se pudo copiar la estructura inicial de la base de datos')
-
-        # 7. Restore database schema
-        restored = odoo_api.restore_database(self.normalized_name)
-
-        if not restored:
-            raise Warning('No se pudo reestablecer la copia de base de datos')
-
-        # 8. Remove database seed
-        seed_removed = odoo_api.remove_database_seed()
-
-        if not seed_removed:
-            raise Warning('No se pudo remover la copia de base de datos')
-
-        # 9. Create odoo container
-        odoo_created = odoo_api.create_container(self.normalized_name, [port_to_use])
-
-        if not odoo_created:
-            raise Warning('No se pudo crear el contenedor')
-
-        # 10. Apply permissions
-        permissions_applied = odoo_api.apply_permissions(self.normalized_name)
-
-        if not permissions_applied:
-            raise Warning('No se pudo aplicar los permisos correspondientes')
-
-        # 11. Get internal ip
-        internal_ip = odoo_api.get_internal_ip(self.normalized_name)
-
-        # 12. Send email
-        # TODO
-
-        print(internal_ip)
-
-        self.state = 'activated'
+        self._check_name_availability(self.normalized_name)
+
+        # # 1. Check name
+        # name_is_available = odoo_api.check_name_availability(self.normalized_name)
+        #
+        # if not name_is_available:
+        #     raise Warning('El nombre ya está siendo usado por otro sistema')
+        #
+        # # 2. Get a port
+        # port_to_use = odoo_api.randomize_port()
+        #
+        # # 3. Create dirs
+        # make_ok = odoo_api.make_default_dirs(self.normalized_name)
+        #
+        # if not make_ok:
+        #     raise Warning('No se pudo crear la estructura de directorios')
+        #
+        # # 4. Create configuration file
+        # config_ok = odoo_api.make_config_file(self.normalized_name)
+        #
+        # if not config_ok:
+        #     raise Warning('No se pudo crear el archivo de configuración')
+        #
+        # # 5. Create database
+        # db_ok = odoo_api.create_database(self.normalized_name)
+        #
+        # if not db_ok:
+        #     raise Warning('No se pudo crear la base de datos')
+        #
+        # # 6. Copy database seed
+        # seed_copied = odoo_api.copy_database_seed()
+        #
+        # if not seed_copied:
+        #     raise Warning('No se pudo copiar la estructura inicial de la base de datos')
+        #
+        # # 7. Restore database schema
+        # restored = odoo_api.restore_database(self.normalized_name)
+        #
+        # if not restored:
+        #     raise Warning('No se pudo reestablecer la copia de base de datos')
+        #
+        # # 8. Remove database seed
+        # seed_removed = odoo_api.remove_database_seed()
+        #
+        # if not seed_removed:
+        #     raise Warning('No se pudo remover la copia de base de datos')
+        #
+        # # 9. Create odoo container
+        # odoo_created = odoo_api.create_container(self.normalized_name, [port_to_use])
+        #
+        # if not odoo_created:
+        #     raise Warning('No se pudo crear el contenedor')
+        #
+        # # 10. Apply permissions
+        # permissions_applied = odoo_api.apply_permissions(self.normalized_name)
+        #
+        # if not permissions_applied:
+        #     raise Warning('No se pudo aplicar los permisos correspondientes')
+        #
+        # # 11. Get internal ip
+        # internal_ip = odoo_api.get_internal_ip(self.normalized_name)
+        #
+        # # 12. Send email
+        # # TODO
+        #
+        # print(internal_ip)
+        #
+        # self.state = 'activated'
 
     @api.one
     def action_disapprove(self):

+ 7 - 1
utils/odoo_api.py

@@ -36,7 +36,13 @@ def check_name_availability(name):
 
 
 def randomize_port():
-    pass
+    ports = []
+    port = 0
+
+    while not check_port_availability(port):
+        port = randint(ports[0], ports[1])
+
+    return port
 
 
 def check_port_availability(port):