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 ( get_all_external_ports, get_internal_ip, execute_command, run_container, start_container, stop_container, copy_in, container_is_running ) from api.utils.git_api import clone_repo from api.utils.command import execute from api.utils.email import send_email from api.utils.logger import ( info, error, warning ) import os import socket import time import unicodedata import stringcase import tarfile ''' ''' 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 ''' ''' def randomize_port(): ports = settings.ODOO_PORTS_RANGE port = 0 while not check_port_from_docker(port): time.sleep(1) port = randint(ports[0], ports[1]) return port ''' ''' def check_port(port=0): if port == 0: return False ok = False info('cheking port %d at %s' % (settings.EXTERNAL_IP, port)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.bind((settings.EXTERNAL_IP, port)) info('%s checked at %s is success' % (settings.EXTERNAL_IP, port)) ok = True except socket.error: info('%s checked at %s is failed' % (settings.EXTERNAL_IP, port)) ok = False s.close() return ok ''' ''' def check_port_from_docker(port=0): if port == 0: return False if port in get_all_external_ports(): return False return True ''' ''' def check_name(name=None): if not name: return False full_path = os.path.join(settings.ODOO_ROOT_PATH, name) return os.path.exists(full_path) ''' ''' def create_folders(name=None): if not name: return False folders = settings.ODOO_DEFAULT_FOLDERS for folder in folders: 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): if not name: return False conf_path = os.path.join(settings.ODOO_ROOT_PATH, name, 'config') if not os.path.exists(conf_path): return False env = Environment( loader=PackageLoader('api', 'templates'), autoescape=select_autoescape(['j2']) ) template = env.get_template(settings.ODOO_CONF_FILENAME + '.j2') 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 }) template_rendered.dump(os.path.join(conf_path, settings.ODOO_CONF_FILENAME + '.conf')) return True ''' ''' def create_database(name=None): if not name: return False cmd = 'createdb -U %s %s' % (settings.ODOO_DB_USER, name) return execute_command(settings.ODOO_DB_CONTAINER, cmd) ''' ''' def copy_database_seed(): 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_seed(): cmd = 'rm -f %s' % ('/tmp/odoo.sql') return execute_command(settings.ODOO_DB_CONTAINER, cmd) ''' ''' 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, settings.INTERNAL_NETWORK_NAME, '150m', '150m' ) time.sleep(5) return True ''' ''' def get_odoo_internal_ip(name=None): if not name: return None return get_internal_ip(name) ''' ''' def install_modules(system_name=None, module_names=[]): if not system_name: return {'error': 'system name is required'} if len(module_names) == 0: return {'error': 'module names is required'} # 1. check system path system_path = os.path.join(settings.ODOO_ROOT_PATH, system_name) if not os.path.exists(system_path): error('%s path not exists' % system_name) return {'error': 'system path not exists'} info('%s path checked' % system_name) # 2. check system status system_is_up = container_is_running(system_name) info('%s system state detected' % system_name) # 3. stop system container if necesary if system_is_up: stopped = stop_container(system_name) if not stopped: error('%s system cannot be stopped' % system_name) return {'error': 'cannot stop system'} info('%s system state successfully passed [state=%s]' % (system_name, system_is_up)) for module_name in module_names: # 4. check module path and remove it module_path = os.path.join(system_path, 'custom-addons', module_name) if os.path.exists(module_path): execute(['rm', '-Rf', module_path]) # 5. clone repo addons_path = os.path.join(system_path, 'custom-addons') cloned = clone_repo(module_name, addons_path) if not cloned: return {'error': 'cannot clone repo'} # 6. remove git data git_data_path = os.path.join(module_path, '.git') if os.path.exists(git_data_path): execute(['rm', '-Rf', git_data_path]) try: execute(['chmod', '-R', '777', module_path]) except Exception: pass info('%s is installed in %s system' % (module_name, system_name)) # 7. start system container if system_is_up: started = start_container(system_name) if not started: error('%s system cannot be started' % system_name) return {'error': 'cannot start system'} info('all modules requested installed') return {'result': '%s installed' % module_name} ''' ''' def install_module(system_name=None, module_name=None): return install_modules(system_name, [module_name])