# -*- coding: utf-8 -*- from openerp import models, fields, api from openerp.tools import config from openerp.exceptions import Warning from random import randint from jinja2 import Environment, PackageLoader from subprocess import check_output from ..utils import docker_api import os import unicodedata import stringcase import time class OdooContainer(models.Model): _name = 'odoo.management.odoo.container' CONTAINER_STATUS = [ ('to_activate', 'Por activar'), ('activated', 'Activado'), ('disapproved', 'No aprobado'), ('suspended', 'Suspendido'), ('destroyed', 'Eliminado') ] normalized_name = fields.Char(string='Normalized Name', compute='_normalize_name', size=50) logo = fields.Binary(string='Logo') internal_ip = fields.Char(string='Internal IP', size=15) internal_port = fields.Integer(string='Internal Port') external_ip = fields.Char(string='External IP', size=15) external_port = fields.Integer(string='External Port') expose_service = fields.Boolean(string='Expose Service', default=True) status = fields.Selection(string='Estado', selection=CONTAINER_STATUS, default='draft') demo = fields.Boolean(string='Is Demo?', default=False) active = fields.Boolean(string='Is Active', default=False) payment_plan_id = fields.Many2one(string='Payment Plan', comodel_name='odoo.management.payment.plan', required=True) @api.one # @api.depends('name') def _normalize_name(self): try: name = unicodedata.normalize('NFKD', self.name) name = name.encode('ASCII', 'ignore') except TypeError: pass name = stringcase.trimcase(name) name = stringcase.lowercase(name) self.normalized_name = stringcase.snakecase(name) def check_existence(self): root_path = config['odoo_root_path'] or None if not root_path: raise Warning('No se puede encontrar la configuraciĆ³n') system_path = os.path.join(root_path, self.normalized_name) if system_path: raise Warning('Ya existe un sistema con este nombre') return True def check_docker_port(self, port): if port == 0: return False if port in docker_api.get_all_external_ports(): return False return True def take_randomized_port(self): port_range = config['odoo_ports_range'] port_range = map(lambda x: int(x.strip()), port_range.split(',')) port = 0 while not self.check_docker_port(port): port = randint(port_range[0], port_range[1]) time.sleep(0.3) self.external_port = port def create_odoo_folders(self): root_path = config('odoo_root_path') defaults_path = config('odoo_defaults_path') for p in defaults_path: full_path = os.path.join(root_path, self.normalized_name, p.strip()) os.makedirs(full_path) time.sleep(0.3) return True def create_odoo_config(self): config_path = os.path.join(config('odoo_root_path'), self.normalized_name, 'config') if not os.path.exists(config_path): return False env = Environment(loader=PackageLoader('resources')) template = env.get_template('openerp-server.j2') rendered = template.stream({ 'admin_password': config('odoo_default_password'), 'db_host': config('odoo_db_host'), 'db_name': self.normalized_name, 'db_user': config('db_user'), 'db_password': config('db_password') }) rendered.dump(os.path.join(config_path, 'openerp-server.conf')) return True def create_odoo_db(self): cmd = 'createdb -U %s %s' % (config('db_user'), self.normalized_name) result = docker_api.run_command(config('odoo_db_container'), cmd) return result def copy_odoo_db_seed(self): backup_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'resources', 'odoo.tar') return docker_api.copy_in(config('odoo_db_container'), '/tmp', backup_path) def restore_odoo_db(self): cmd = 'psql -U %s -d %s -f %s' % (config('db_user'), self.normalized_name, '/tmp/odoo.sql') return docker_api.run_command(config('odoo_db_container'), cmd) def remove_odoo_db_seed(self): cmd = 'rm -f %s' % '/tmp/odoo.sql' return docker_api.run_command(config('odoo_db_container'), cmd) def create_odoo_container(self): result = docker_api.run_container( image=config('odoo_image'), name=self.normalized_name, ports={'8069/tcp': self.external_port}, volumes=None, network=config('odoo_network'), memory_limit='150M', memory_swap_limit='150M' ) if not result: raise Warning('No se pudo crear el contenedor') return True def apply_odoo_folders_permission(self): full_path = os.path.join(config('odoo_root_path'), self.normalized_name) check_output(['chmod', '-Rf', '777'], full_path) return True def take_internal_ip(self): self.internal_ip = docker_api.get_internal_ip(self.normalized_name)