#!/usr/bin/env python # vim: set shiftwidth=4 softtabstop=4: """Script to run test with local modules """ # Version 2.15 import argparse import json import logging import os import signal from subprocess import call import sys import ConfigParser import docker # apt python-docker (1.9) or pip install docker # local file import docker_dev_start if docker.__version__ > '3.0.0': from docker import APIClient as docker_api else: from docker import Client as docker_api _logger = logging.getLogger(__name__) __version__ = '0.0.1' __date__ = '2018-04-13' __updated__ = '2018-04-13' def main(argv=None): # IGNORE:C0111 """Parse arguments and docker build """ program_version = __version__ program_build_date = str(__updated__) program_version_message = '%%(prog)s %s (%s)' % ( program_version, program_build_date) program_shortdesc = __doc__.split(".")[0] program_license = '''%s Created by Vincent Hatakeyama on %s. Copyright 2018 XCG Consulting. All rights reserved. Licensed under the MIT License Distributed on an "AS IS" basis without warranties or conditions of any kind, either express or implied. USAGE ''' % (program_shortdesc, str(__date__)) # TODO the script assume it is launched from the parent super project project_path = os.path.realpath('.') project_name = os.path.basename(project_path) if project_name == 'odoo_scripts': logging.fatal( "You must run this script from the super project" " (./odoo_scripts/docker_build.py)") return 1 setup_path = 'setup.cfg' # TODO add a way to store configuration options in a project file # Argument parsing parser = argparse.ArgumentParser( description=program_license, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument( '-V', '--version', action='version', version=program_version_message) parser.add_argument( '-v', '--verbose', dest='verbose', action='count', help="set verbosity level [default: %(default)s]") docker_group = parser.add_mutually_exclusive_group() docker_group.add_argument( '--docker', help="Use docker to launch tests", action='store_true', default=True, dest='docker', ) docker_group.add_argument( '--no-docker', help="Do not use docker to launch tests", action='store_false', dest='docker', ) parser.add_argument( '-d', '--dbname', help="Database name [default: %(default)s]", default='%s_test' % project_name, ) parser.add_argument( '--db_user', help="Odoo database user [default: %(default)s]", default=None, ) parser.add_argument( '--db_password', help="Odoo database password [default: %(default)s]", default=None, ) # TODO options # - db host/uri (include socket) # - db user for creation/remove # - odoo log level # - create db nmspc = parser.parse_args(argv) verbose = nmspc.verbose if not verbose: logging.basicConfig(level=logging.WARN) if verbose == 1: logging.basicConfig(level=logging.INFO) if verbose and verbose > 1: logging.basicConfig(level=logging.DEBUG) dbname = nmspc.dbname odoo_db_user = nmspc.db_user odoo_db_password = nmspc.db_password recreate_db = True extensions = [] install_log_level = None test_log_level = None # Get parameters from setup file c = ConfigParser.ConfigParser() if not os.path.exists(setup_path): logging.fatal('Missing %s', setup_path) return 12 c.read(setup_path) if c.has_option('odoo_scripts', 'addon_dirs'): addon_dirs = c.get('odoo_scripts', 'addon_dirs', '').split() else: addon_dirs = '' logging.debug("addon directories: %s", addon_dirs) registry = ( c.has_section('odoo_scripts') and c.has_option('odoo_scripts', 'registry') and c.get('odoo_scripts', 'registry')) or 'dockerhub.xcg.io' project = ( c.has_section('odoo_scripts') and c.has_option('odoo_scripts', 'image') and c.get('odoo_scripts', 'image')) or os.path.basename(project_path) odoo_type = ( c.has_section('odoo_scripts') and c.has_option('odoo_scripts', 'odoo_type') and c.get('odoo_scripts', 'odoo_type')) or 'odoo7' image = "%s/%s:latest" % (registry, project) logging.debug("Docker image: %s", image) # read from odoo.conf if it exists sample_conf = 'conf/dev/odoo.conf' if os.path.exists(sample_conf): logging.info('Reading from sample configuration %s', sample_conf) c.read(sample_conf) if not odoo_db_user: odoo_db_user = c.get('options', 'db_user') if ( c.has_option('options', 'unaccent') and c.getboolean('options', 'unaccent') ): extensions.append('unaccent') else: logging.debug('No sample configuration %s', sample_conf) extensions.append('unaccent') # Do stuff if nmspc.docker: # TODO detect that user is member of docker group args = [ '-d', dbname, '--stop-after-init', '--max-cron-threads', '0', '--no-flake8', '--no-dev', ] if odoo_db_user: args.append('--db_user') args.append(odoo_db_user) else: # TODO find from odoo version and conf file pass if odoo_db_password: args.append('--db_password') args.append(odoo_db_password) docker_dev_start.flake8() if recreate_db: # XXX use psycopg2 # drop database logging.info("Drop any existing database %s", dbname) result = call(['dropdb', dbname, '--if-exists', '--no-password']) if result: return result # create database logging.info("Create database %s", dbname) if not odoo_db_user: logging.fatal( 'Owner of database is mandatory when creating database') return 14 result = call(['createdb', dbname, '-O', odoo_db_user, '--no-password']) if result: return result # add unaccent if needed for extension in extensions: logging.info("Adding extension %s", extension) result = call([ 'psql', dbname, '-c', 'CREATE EXTENSION %s;' % extension]) if result: return result # TODO start odoo and detect if install fails if nmspc.docker: install_args = list(args) install_args.append('--install-default') if install_log_level: install_args.append('--log-level=%s' % install_log_level) docker_dev_start.main(install_args) if result: return result else: raise NotImplementedError # TODO start odoo and detect if test fails if nmspc.docker: test_args = list(args) test_args.append('--test-default') if test_log_level: install_args.append('--log-level=%s' % test_log_level) return docker_dev_start.main(test_args) else: raise NotImplementedError return 255 if __name__ == "__main__": return_code = main(sys.argv[1:]) if return_code: exit(return_code)