# -*- 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 # print(config['docker_sock']) class SystemInstance(models.Model): _name = 'system.instance' CONTAINER_STATUS = [ ('draft', 'Por activar'), ('activated', 'Activado'), ('disapproved', 'No aprobado'), ('suspended', 'Suspendido'), ('destroyed', 'Eliminado') ] name = fields.Char(string='Nombre', size=50) normalized_name = fields.Char(string='Nombre normalizado', compute='_normalize_name', size=50) logo = fields.Binary(string='Logo') internal_ip = fields.Char(string='IP interno', size=15) internal_port = fields.Integer(string='Puerto interno') external_ip = fields.Char(string='IP externo', size=15) external_port = fields.Integer(string='Puerto externo') expose_ip = fields.Boolean(string='Exponer IP', default=True) state = fields.Selection(string='Estado', selection=CONTAINER_STATUS, default='draft') demo = fields.Boolean(string='Es un demo?', default=False) domain = fields.Char(string='Dominio', size=100) running = fields.Boolean(string='Está online?', default=False) payment_plan_id = fields.Many2one(string='Plan de pago', comodel_name='payment.plan', required=True) @api.one @api.onchange('name') def _onchange_name(self): if self.name: self.name = self.name.title() @api.one @api.depends('name') def _normalize_name(self): name = None try: name = unicodedata.normalize('NFKD', self.name) name = name.encode('ASCII', 'ignore') except TypeError: pass if not name: return name = stringcase.trimcase(name) name = stringcase.lowercase(name) self.normalized_name = stringcase.snakecase(name) @api.one def action_activate(self): if self.state not in ('draft', 'suspended'): raise Warning('No se puede activar un sistema ya activo') self.state = 'activated' @api.one def action_disapprove(self): if self.state != 'draft': raise Warning('No se puede desaprobar un sistema ya activo') self.state = 'disapproved' @api.one def action_suspend(self): if self.state != 'activated': raise Warning('No se puede suspender un sistema no activo') self.state = 'suspended' self.running = False @api.one def copy(self): raise Warning('Atención', 'No se puede duplicar una instancia. Por favor, cree uno nuevo') @api.one def action_destroy(self): if self.state == 'destroyed': raise Warning('No se puede eliminar un sistema ya eliminado') self.state = 'destroyed' self.running = False @api.one def action_start(self): if self.running: raise Warning('Atención', 'No se puede arrancar una instancia que ya está arrancada') self.running = True @api.one def action_restart(self): if not self.running: raise Warning('Atención', 'No se puede parar y arrancar una instancia que ya está parada') self.running = True # 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)