odoo_api.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. from __future__ import unicode_literals
  2. from django.conf import settings
  3. from random import randint
  4. from jinja2 import Environment, PackageLoader, select_autoescape
  5. from api.utils.docker_api import (
  6. get_all_external_ports,
  7. get_internal_ip,
  8. execute_command,
  9. run_container,
  10. start_container,
  11. stop_container,
  12. copy_in
  13. )
  14. from api.utils.git_api import clone_repo
  15. from api.utils.command import execute
  16. from api.utils.logger import info
  17. import os
  18. import socket
  19. import time
  20. import unicodedata
  21. import stringcase
  22. import tarfile
  23. '''
  24. '''
  25. def normalize_name(name = None):
  26. if not name:
  27. return name
  28. try:
  29. name = unicodedata.normalize('NFKD', name)
  30. name = name.encode('ASCII', 'ignore')
  31. except TypeError:
  32. pass
  33. name = stringcase.trimcase(name)
  34. name = stringcase.lowercase(name)
  35. name = stringcase.snakecase(name)
  36. return name
  37. '''
  38. '''
  39. def randomize_port():
  40. ports = settings.ODOO_PORTS_RANGE
  41. port = 0
  42. while not check_port_from_docker(port):
  43. time.sleep(1)
  44. port = randint(ports[0], ports[1])
  45. return port
  46. '''
  47. '''
  48. def check_port(port=0):
  49. if port == 0:
  50. return False
  51. ok = False
  52. info('cheking port %d at %s' % (settings.EXTERNAL_IP, port))
  53. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  54. try:
  55. s.bind((settings.EXTERNAL_IP, port))
  56. info('%s checked at %s is success' % (settings.EXTERNAL_IP, port))
  57. ok = True
  58. except socket.error:
  59. info('%s checked at %s is failed' % (settings.EXTERNAL_IP, port))
  60. ok = False
  61. s.close()
  62. return ok
  63. '''
  64. '''
  65. def check_port_from_docker(port=0):
  66. if port == 0:
  67. return False
  68. if port in get_all_external_ports():
  69. return False
  70. return True
  71. '''
  72. '''
  73. def check_name(name=None):
  74. if not name:
  75. return False
  76. full_path = os.path.join(settings.ODOO_ROOT_PATH, name)
  77. return os.path.exists(full_path)
  78. '''
  79. '''
  80. def create_folders(name=None):
  81. if not name:
  82. return False
  83. folders = settings.ODOO_DEFAULT_FOLDERS
  84. for folder in folders:
  85. full_path = os.path.join(settings.ODOO_ROOT_PATH, name, folder.strip())
  86. os.makedirs(full_path)
  87. time.sleep(1)
  88. return True
  89. '''
  90. '''
  91. def apply_permissions(name=None):
  92. if not name:
  93. return False
  94. full_path = os.path.join(settings.ODOO_ROOT_PATH, name)
  95. execute(['chmod', '-Rf', '777', full_path])
  96. return True
  97. '''
  98. '''
  99. def create_configuration(name=None):
  100. if not name:
  101. return False
  102. conf_path = os.path.join(settings.ODOO_ROOT_PATH, name, 'config')
  103. if not os.path.exists(conf_path):
  104. return False
  105. env = Environment(
  106. loader=PackageLoader('api', 'templates'),
  107. autoescape=select_autoescape(['j2'])
  108. )
  109. template = env.get_template(settings.ODOO_CONF_FILENAME + '.j2')
  110. template_rendered = template.stream({
  111. 'admin_password': settings.ODOO_ADMIN_PASSWORD,
  112. 'db_host': settings.ODOO_DB_HOST,
  113. 'db_port': settings.ODOO_DB_PORT,
  114. 'db_name': name,
  115. 'db_user': settings.ODOO_DB_USER,
  116. 'db_password': settings.ODOO_DB_PASSWORD
  117. })
  118. template_rendered.dump(os.path.join(conf_path, settings.ODOO_CONF_FILENAME + '.conf'))
  119. return True
  120. '''
  121. '''
  122. def create_database(name=None):
  123. if not name:
  124. return False
  125. cmd = 'createdb -U %s %s' % (settings.ODOO_DB_USER, name)
  126. return execute_command(settings.ODOO_DB_CONTAINER, cmd)
  127. '''
  128. '''
  129. def copy_database_seed():
  130. backup_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'files', 'odoo.tar')
  131. return copy_in(settings.ODOO_DB_CONTAINER, '/tmp', backup_path)
  132. '''
  133. '''
  134. def restore_database(name=None):
  135. if not name:
  136. return False
  137. cmd = 'psql -U %s -d %s -f %s' % (settings.ODOO_DB_USER, name, '/tmp/odoo.sql')
  138. return execute_command(settings.ODOO_DB_CONTAINER, cmd)
  139. '''
  140. '''
  141. def remove_database_seed():
  142. cmd = 'rm -f %s' % ('/tmp/odoo.sql')
  143. return execute_command(settings.ODOO_DB_CONTAINER, cmd)
  144. '''
  145. '''
  146. def create_odoo_container(name=None, ports=[]):
  147. if not name:
  148. return False
  149. ports = dict(map(lambda p: ('%d/tcp' % 8069, p), ports))
  150. volumes = dict(map(lambda f: (os.path.join(settings.ODOO_ROOT_PATH, name, f.strip()), {
  151. 'bind': settings.ODOO_DEFAULT_FOLDERS[f].strip(),
  152. 'mode': 'rw'
  153. }) , settings.ODOO_DEFAULT_FOLDERS))
  154. run_container(settings.ODOO_IMAGE, name, ports, volumes, settings.INTERNAL_NETWORK_NAME)
  155. time.sleep(5)
  156. return True
  157. '''
  158. '''
  159. def get_odoo_internal_ip(name=None):
  160. if not name:
  161. return None
  162. return get_internal_ip(name)
  163. '''
  164. '''
  165. def install_module(system_name=None, module_name=None):
  166. if not system_name:
  167. return {'error': 'system name is required'}
  168. if not module_name:
  169. return {'error': 'module name is required'}
  170. # 1. check system path
  171. system_path = os.path.join(settings.ODOO_ROOT_PATH, system_name)
  172. if not os.path.exists(system_path):
  173. return {'error': 'system path not exists'}
  174. # 2. stop system container
  175. stopped = stop_container(system_name)
  176. if not stopped:
  177. return {'error': 'cannot stop system'}
  178. # 3. check module path and remove it
  179. module_path = os.path.join(system_path, 'custom-addons', module_name)
  180. if os.path.exists(module_path):
  181. execute(['rm', '-Rf', module_path])
  182. # 4. clone repo
  183. cloned = clone_repo(module_name, os.path.join(system_path, 'custom/addons'))
  184. if not cloned:
  185. return {'error': 'cannot clone repo'}
  186. # 5. start system container
  187. started = start_container(system_name)
  188. if not started:
  189. return {'error': 'cannot start system'}
  190. return {'result': '%s installed' % module_name}
  191. '''
  192. '''
  193. def up():
  194. pass
  195. '''
  196. '''
  197. def kill():
  198. pass