def stop_environment(self, client_name): self._client = Client(self, client_name) ret = [] img2 = 'pg-{}'.format(self.client.name) images = [] if self.client.get_image('aeroo'): images.append('aeroo') images.append(img2) for image in images: cmd = Command( self, command='sudo docker stop {}'.format(image), usr_msg='Stopping image {} please wait...'.format(image), ) ret.append(cmd) for image in images: cmd = Command( self, command='sudo docker rm {}'.format(image), usr_msg='Removing image {}'.format(image), ) ret.append(cmd) if self.debug: cmd = Command( self, command='sudo docker rm -f {}'.format('wdb'), usr_msg='Removing image {}'.format('wdb'), ) ret.append(cmd) return ret
def backup_list(self, client_name): """ Listar los archivos disponibles para restore """ self._client = Client(self, client_name) ret = [] filenames = [] # walk the backup dir for root, dirs, files in os.walk(self.client.backup_dir): for filedesc in files: filename, file_extension = os.path.splitext(filedesc) if file_extension == '.zip': filenames.append(filedesc) if len(filenames): filenames.sort() msg = 'List of available backups for client {} \n\n'.format( client_name) for filedesc in filenames: msg += filedesc + '\n' else: msg = 'There are no files to restore' cmd = MessageOnly( self, command=False, usr_msg=msg, ) ret.append(cmd) return ret
def write_config(self, client_name): """ Escribe el config file """ self._client = Client(self, client_name) ret = [] client = self._client CPUs = client.CPUs # You should use 2 worker threads + 1 cron thread per available CPU, # and 1 CPU per 10 concurent users. Make sure you tune the memory # limits and cpu limits in your configuration file. workers = CPUs * 2 + 1 if not self.debug else 0 max_cron_threads = 1 # Number of requests a worker will process before being recycled and # restarted. Defaults to 8196 limit_request = client.limit_request # Maximum allowed virtual memory per worker. If the limit is exceeded, # the worker is killed and recycled at the end of the current request. # Defaults to 640MB limit_memory_soft = client.limit_memory_soft # Hard limit on virtual memory, any worker exceeding the limit will be # immediately killed without waiting for the end of the current request # processing. Defaults to 768MB. limit_memory_hard = client.limit_memory_hard # Prevents the worker from using more than CPU seconds for each # request. If the limit is exceeded, the worker is killed. Defaults # to 60. limit_time_cpu = client.limit_time_cpu if not self.debug else 9999999 # Prevents the worker from taking longer than seconds to process a # request. If the limit is exceeded, the worker is killed. Defaults to # 120. Differs from --limit-time-cpu in that this is a "wall time" # limit including e.g. SQL queries. limit_time_real = client.limit_time_real if not self.debug else 9999999 if self._client.numeric_ver not in [8, 9, 10]: cmd = WriteConfigFile(self, args={ 'client': client, 'workers': workers, 'max_cron_threads': max_cron_threads, 'limit_request': limit_request, 'limit_memory_soft': limit_memory_soft, 'limit_memory_hard': limit_memory_hard, 'limit_time_cpu': limit_time_cpu, 'limit_time_real': limit_time_real, 'data_dir': IN_DATA }, usr_msg='Writing config file') ret.append(cmd) else: ret += self.run_client(client_name, write_config=True) return ret
def pull_images(self, client_name): """ Forzar la bajada de las imagenes """ ret = [] self._client = Client(self, client_name) for image in self._client._images: cmd = PullImage(self, command='sudo docker pull {}'.format(image.name), usr_msg='Pulling Image {}'.format( image.short_name)) ret.append(cmd) return ret
def write_config(self, client_name): """ Sobreescribe el config con los datos que vienen en el manifiesto """ self._client = Client(self, client_name) ret = [] if self._client.numeric_ver not in WRITE_CONFIG_OLD_MODE: cmd = WriteConfigFile(self, args={'client': self._client}, usr_msg='Writing config file') ret.append(cmd) else: ret += self.run_client(client_name, write_config=True) return ret
def server_help(self, client_name): ret = [] self._client = Client(self, client_name) command = 'sudo docker run --rm -it ' # command += self._add_normal_mountings() command += '--link pg-{}:db '.format(self.client.name) command += '--name help ' command += '{} '.format(self.client.get_image('odoo').name) command += '-- ' command += '--help ' cmd = Command( self, command=command, usr_msg='Getting odoo help', ) ret.append(cmd) return ret
def update(self, client_name, database, modules): self._client = Client(self, client_name) ret = [] command = 'sudo docker run --rm -it ' command += self._add_normal_mountings() if self.debug: command += self._add_debug_mountings(self.client.numeric_ver) command += '--link pg-{}:db '.format(self.client.name) command += '-e ODOO_CONF=/dev/null ' command += '{} -- '.format(self.client.get_image('odoo').name) command += '--stop-after-init ' command += '--logfile=false ' command += '-d {} '.format(database) command += '-u {} '.format(', '.join(modules)) cmd = Command(self, command=command, usr_msg='Performing update of {} on database {}'.format( ', '.join(modules), database)) ret.append(cmd) return ret
def restore(self, client_name, database=False, backup_file=False, deactivate=False): """ Restaurar un backup desde el directorio backup_dir """ self._client = Client(self, client_name) ret = [] msg = 'Restoring database %s ' % database if backup_file: msg += 'from backup %s ' % backup_file else: msg += 'from newest backup ' if deactivate: msg += 'and performing deactivation.' command = 'sudo docker run --rm -i ' command += '--link pg-{}:db '.format(client_name) command += '-v {}:/backup '.format(self.client.backup_dir) command += '-v {}data_dir/filestore:/filestore '.format( self.client.base_dir) command += '--env NEW_DBNAME={} '.format(database) if backup_file: command += '--env ZIPFILE={} '.format(backup_file) if deactivate: command += '--env DEACTIVATE=True ' command += 'jobiols/dbtools ' cmd = Command( self, command=command, usr_msg=msg, ) ret.append(cmd) return ret
def test_qa(self): """ ########################################################### TEST QA """ options = {'debug': False} client_name = 'test_client' database = 'cliente_test' modules = 'modulo_a_testear' oe = OdooEnv(options) client = Client(oe, client_name) cmds = oe.qa(client_name, database, modules, client_test=client) cmd = cmds[0] self.assertEqual( cmd.usr_msg, 'Performing tests on module ' 'modulo_a_testear for client ' 'test_client and database cliente_test') command = \ "sudo docker run --rm -it " \ "-v /odoo_ar/odoo-9.0/test_client/config:/opt/odoo/etc/ " \ "-v /odoo_ar/odoo-9.0/test_client/data_dir:/opt/odoo/data " \ "-v /odoo_ar/odoo-9.0/test_client/log:/var/log/odoo " \ "-v /odoo_ar/odoo-9.0/test_client/sources:" \ "/opt/odoo/custom-addons " \ "-v /odoo_ar/odoo-9.0/test_client/backup_dir:/var/odoo/backups/ " \ "--link wdb " \ "-e WDB_SOCKET_SERVER=wdb " \ "-e ODOO_CONF=/dev/null " \ "--link pg-test_client:db jobiols/odoo-jeo:9.0.debug -- " \ "-d cliente_test " \ "--stop-after-init " \ "--log-level=test " \ "--test-enable " \ "-u modulo_a_testear " self.assertEqual(cmd.command, command)
def qa(self, client_name, database, module_name, client_test=False): """ Corre un test especifico, los parametros necesarios son: :param client_name: parametro -c :param database: parametro -d :param modules: parametro -m (es una lista) :return: lista con los comandos para correr """ # solo para que corran los tests if client_test: self._client = client_test else: self._client = Client(self, client_name) ret = [] command = 'sudo docker run --rm -it ' command += self._add_normal_mountings() if self.debug: command += self._add_debug_mountings(self.client.numeric_ver) command += '--link wdb ' # linkeamos con test y setamos nombre command += '-e WDB_SOCKET_SERVER=wdb ' command += '-e ODOO_CONF=/dev/null ' command += '--link pg-{}:db '.format(self.client.name) command += '{}.debug -- '.format(self.client.get_image('odoo').name) command += '-d {} '.format(database) command += '--stop-after-init ' command += '--log-level=test ' command += '--test-enable ' command += '-u {} '.format(module_name) msg = 'Performing tests on module {} for client {} ' \ 'and database {}'.format(module_name, client_name, database) cmd = Command(self, command=command, usr_msg=msg) ret.append(cmd) return ret
def run_client(self, client_name, write_config=False): self._client = Client(self, client_name) ret = [] if write_config: msg = 'Writing config file for client {}'.format(client_name) else: msg = 'Starting Odoo image for client {} on port {}'.format( client_name, self.client.port) if write_config: command = 'sudo docker run --rm ' else: if self.debug: command = 'sudo docker run --rm -it ' else: command = 'sudo docker run -d ' if self.client.get_image('aeroo'): command += '--link aeroo:aeroo ' # open link to wdb image if self.debug: command += '--link wdb ' # si tenemos nginx o si estamos escribiendo la configuracion no hay # que exponer los puertos if not (self.nginx or write_config): command += '-p {}:8069 '.format(self.client.port) command += '-p 8072:8072 ' command += self._add_normal_mountings() if self.debug: command += self._add_debug_mountings(self.client.numeric_ver) command += '--link pg-{}:db '.format(self.client.name) if not (self.debug or write_config): command += '--restart=always ' # si estamos escribiendo el config no le ponemos el nombre para que # pueda correr aunque este levantado el cliente if not write_config: command += '--name {} '.format(self.client.name) if write_config: command += self.set_config_environment() else: command += '-e ODOO_CONF=/dev/null ' # si estamos en modo debug agregarlo al nombre de la imagen if self.debug: command += '-e SERVER_MODE=test ' command += '-e WDB_SOCKET_SERVER=wdb ' command += '{}.debug '.format(self.client.get_image('odoo').name) else: command += '-e SERVER_MODE= ' command += '{} '.format(self.client.get_image('odoo').name) if not self.debug: command += '--logfile=/var/log/odoo/odoo.log ' else: command += '--logfile=/dev/stdout ' if write_config: command += '--stop-after-init ' cmd = Command( self, command=command, usr_msg=msg, ) ret.append(cmd) ################################################################## # Launching nginx proxy if needed ################################################################## if self.nginx: msg = 'Starting nginx reverse proxy' image = self.client.get_image('nginx') nginx_dir = self.client.nginx_dir command = 'sudo docker run -d ' command += '-v {}conf:/etc/nginx/conf.d:ro '.format(nginx_dir) command += '-v {}data_dir/letsencrypt:/etc/letsencrypt '.format( self.client.base_dir) command += '-v {}log:/var/log/nginx/ '.format(nginx_dir) command += '-p 80:80 ' command += '-p 443:443 ' command += '--name={} '.format(image.short_name) command += '--link {}:odoo '.format(client_name) command += '--restart=always ' command += image.name cmd = Command( self, command=command, usr_msg=msg, ) ret.append(cmd) return ret
def run_environment(self, client_name): """ :return: devuelve los comandos en una lista """ self._client = Client(self, client_name) ret = [] ################################################################## # Launching postgres Image ################################################################## image = self.client.get_image('postgres') msg = 'Starting postgres image v{}'.format(image.version) command = 'sudo docker run -d ' if self.debug: command += '-p 5432:5432 ' command += '-e POSTGRES_USER=odoo ' command += '-e POSTGRES_PASSWORD=odoo ' command += '-v {}:/var/lib/postgresql/data '.format( self.client.psql_dir) command += '--restart=always ' command += '--name pg-{} '.format(self.client.name) command += image.name cmd = Command( self, command=command, usr_msg=msg, ) ret.append(cmd) ################################################################## # Launching aeroo Image ################################################################## image = self.client.get_image('aeroo') if image: msg = 'Starting aeroo image' command = 'sudo docker run -d ' command += '--name={} '.format(image.short_name) command += '--restart=always ' command += image.name cmd = Command( self, command=command, usr_msg=msg, ) ret.append(cmd) ################################################################## # Launching wdb Image if debug ################################################################## if self.debug: msg = 'Starting wdb image' command = 'sudo docker run -d ' command += '-p 1984:1984 ' command += '--name=wdb ' command += '--restart=always ' command += 'kozea/wdb' cmd = Command( self, command=command, usr_msg=msg, ) ret.append(cmd) return ret
def install(self, client_name): """ Instalacion de cliente, """ self._client = Client(self, client_name) ret = [] ################################################################## # Create base dir with sudo ################################################################## msg = 'Installing client %s' % client_name cmd = MakedirCommand(self, command='sudo mkdir %s' % BASE_DIR, args=BASE_DIR, usr_msg=msg) ret.append(cmd) ################################################################## # change ownership of base dir ################################################################## username = pwd.getpwuid(os.getuid()).pw_name cmd = Command(self, command='sudo chown %s:%s %s' % (username, username, BASE_DIR)) ret.append(cmd) ################################################################## # create all client hierarchy ################################################################## for w_dir in [ 'postgresql', 'config', 'data_dir', 'backup_dir', 'log', 'sources' ]: r_dir = '%s%s' % (self.client.base_dir, w_dir) cmd = MakedirCommand(self, command='mkdir -p {}'.format(r_dir), args='{}'.format(r_dir)) ret.append(cmd) ################################################################## # create dirs for extracting sources, only for debug ################################################################## if self.debug: for w_dir in self._get_packs(): r_dir = '{}{}'.format(self.client.version_dir, w_dir) cmd = MakedirCommand(self, command='mkdir -p {}'.format(r_dir), args='{}'.format(r_dir)) ret.append(cmd) ################################################################## # change og+w for those dirs ################################################################## if self.debug: for w_dir in self._get_packs(): r_dir = '{}{}'.format(self.client.version_dir, w_dir) cmd = Command(self, command='chmod og+w {}'.format(r_dir)) ret.append(cmd) ################################################################## # change o+w for config, data, log and backup_dir ################################################################## for w_dir in ['config', 'data_dir', 'log', 'backup_dir']: r_dir = '{}{}'.format(self.client.base_dir, w_dir) cmd = Command(self, command='chmod o+w {}'.format(r_dir)) ret.append(cmd) ################################################################## # create dirs for nginx if needed ################################################################## if self.nginx: for w_dir in ['cert', 'conf', 'log']: r_dir = '{}{}'.format(BASE_DIR, 'nginx/' + w_dir) cmd = MakedirCommand(self, command='mkdir -p {}'.format(r_dir), args='{}'.format(r_dir)) ret.append(cmd) ################################################################## # create nginx.conf template if needed. Do not overwrite ################################################################## if self.nginx: r_dir = '{}{}'.format(BASE_DIR, 'nginx/conf/') cmd = CreateNginxTemplate(self, command='{}nginx.conf'.format(r_dir), args='{}nginx.conf'.format(r_dir), usr_msg='Generating nginx.conf template', client_name=client_name) ret.append(cmd) ################################################################## # Extracting sources from image if debug enabled ################################################################## if self.debug: for module in self._get_packs(): msg = 'Extracting {} from image {}.debug'.format( module, self.client.get_image('odoo').name) command = 'sudo docker run -it --rm ' command += '--entrypoint=/extract_{}.sh '.format(module) command += '-v {}{}/:/mnt/{} '.format(self.client.version_dir, module, module) command += '{}.debug '.format( self.client.get_image('odoo').name) cmd = ExtractSourcesCommand( self, command=command, args='{}{}'.format(self.client.version_dir, module), usr_msg=msg, ) ret.append(cmd) # poner permisos de escritura for module in self._get_packs(): r_dir = '{}{}'.format(self.client.version_dir, module) cmd = Command(self, command='sudo chmod -R og+w %s/' % r_dir, usr_msg='Making writable %s' % r_dir) ret.append(cmd) # agregar un gitignore for module in self._get_packs(): r_dir = '{}{}'.format(self.client.version_dir, module) cmd = CreateGitignore(self, command='%s/.gitignore' % r_dir, usr_msg='Creating gitignore file in %s' % r_dir) ret.append(cmd) for module in self._get_packs(): # create git repo command = 'git -C {}{}/ init '.format(self._client.version_dir, module) cmd = Command(self, command=command, usr_msg='Init repository for %s' % module) ret.append(cmd) for module in self._get_packs(): command = 'git -C {}{}/ add . '.format( self._client.version_dir, module) cmd = Command(self, command=command, usr_msg='Add files to repository for %s' % module) ret.append(cmd) for module in self._get_packs(): command = 'git -C {}{}/ commit -m inicial '.format( self._client.version_dir, module) cmd = Command(self, command=command, usr_msg='Commit repository for %s' % module) ret.append(cmd) ################################################################## # Clone or update repos as needed ################################################################## ret += self._process_repos() return ret