Something went wrong on our end
-
Vincent Hatakeyama authoredVincent Hatakeyama authored
docker_build.py 5.92 KiB
#!/usr/bin/env python
# vim: set shiftwidth=4 softtabstop=4:
"""Script to locally build a docker image
"""
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
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.1.0'
__date__ = '2018-04-04'
__updated__ = '2018-04-06'
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
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]")
# TODO add tag option, and maybe force tag option
parser.add_argument(
'--ensureconf',
help="ensureconf [default: %(default)s]",
action='store_true',
)
parser.add_argument(
'--push',
help="Push image [default: %(default)s]",
action='store_true',
)
parser.add_argument(
'--dev',
help="add dev feature to generated image [default: %(default)s]",
action='store_true',
)
# TODO (maybe) add argument for other build arg
# TODO detect that user is member of docker group
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)
ensureconf = nmspc.ensureconf
dev = nmspc.dev
push = nmspc.push
c = ConfigParser.ConfigParser()
logging.debug('setup file path %s', setup_path)
# TODO test that setup file exists
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)
# TODO ensureconf
if ensureconf:
raise NotImplementedError
# call build copy
cmd = ['./odoo_scripts/docker_build_copy']
logging.debug(' '.join(cmd))
call(cmd)
# clean on exit
def signal_handler(code, frame):
cmd = ['./odoo_scripts/docker_build_clean']
logging.debug(' '.join(cmd))
call(cmd)
# XXX needed?
# sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
# TODO docker build
buildargs = {}
dockerfile = 'Dockerfile'
if dev:
debug_dockerfile = 'Dockerfile.debug'
call(['cp', dockerfile, debug_dockerfile])
with open(debug_dockerfile, 'a') as myfile:
myfile.write('\n# Developer helpers\n'
'RUN apt-get update -qq\n')
myfile.write(
'RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ')
if odoo_type == 'odoo11':
myfile.write(
'python3-watchdog python3-ipdb\n')
if odoo_type == 'odoo10':
myfile.write(
'python-watchdog python-ipdb\n')
dockerfile = debug_dockerfile
# TODO remove temp image
docker_client = docker_api(base_url='unix://var/run/docker.sock')
builder = docker_client.build(
path='.', rm=True, pull=True, buildargs=buildargs,
tag=image, dockerfile=dockerfile)
# this is for python docker 1.8-1.9
# TODO add compatibility with newer python docker
for line in builder:
d = json.loads(line)
if 'stream' in d:
logging.info(d['stream'])
if dev:
call(['rm', dockerfile])
# TODO exit if build failed
# TODO docker tag with tags/bookmarks (unused so maybe no need)
# TODO docker push (only when asked for)
if push:
raise NotImplementedError
# XXX call cleanup more intelligently
signal_handler(0, None)
return 0
if __name__ == "__main__":
return_code = main(sys.argv[1:])
if return_code:
exit(return_code)