Skip to content
Snippets Groups Projects
Commit 425ed2d0d7de authored by Vincent Hatakeyama's avatar Vincent Hatakeyama
Browse files

:sparkles: option to run start postgresql docker, also uses docker-py instead of subprocess.call

parent 2546f9b90bc9
No related branches found
No related tags found
No related merge requests found
...@@ -6,5 +6,6 @@ ...@@ -6,5 +6,6 @@
import argparse import argparse
import logging import logging
import pwd import pwd
import signal
from subprocess import call from subprocess import call
import sys import sys
...@@ -9,6 +10,7 @@ ...@@ -9,6 +10,7 @@
from subprocess import call from subprocess import call
import sys import sys
from threading import Thread
import os import os
import ConfigParser import ConfigParser
...@@ -11,9 +13,10 @@ ...@@ -11,9 +13,10 @@
import os import os
import ConfigParser import ConfigParser
import docker # apt python-docker (1.9) import docker # apt python-docker (1.9)
from psycopg2 import connect, OperationalError # apt python-psycopg2 from psycopg2 import connect, OperationalError # apt python-psycopg2
from requests.exceptions import ConnectionError
# TODO auto create list of module # TODO auto create list of module
...@@ -136,6 +139,11 @@ ...@@ -136,6 +139,11 @@
help="Append the module_list from setup.cfg to the modules to install [default: %(default)s]", help="Append the module_list from setup.cfg to the modules to install [default: %(default)s]",
action='store_true', action='store_true',
) )
parser.add_argument(
'--start-postgresql',
help="Start a Postgresql docker",
action='store_true',
)
network_group = parser.add_mutually_exclusive_group() network_group = parser.add_mutually_exclusive_group()
network_group.add_argument( network_group.add_argument(
'--host-network', '--host-network',
...@@ -164,6 +172,7 @@ ...@@ -164,6 +172,7 @@
db_user = nmspc.db_user db_user = nmspc.db_user
db_password = nmspc.db_password db_password = nmspc.db_password
use_host_network = nmspc.host_network use_host_network = nmspc.host_network
start_postgresql = nmspc.start_postgresql
if project_name == 'odoo_scripts': if project_name == 'odoo_scripts':
logging.fatal( logging.fatal(
...@@ -192,6 +201,10 @@ ...@@ -192,6 +201,10 @@
c.has_option('odoo_scripts', 'odoo_type') and c.has_option('odoo_scripts', 'odoo_type') and
c.get('odoo_scripts', 'odoo_type')) or 'odoo7' c.get('odoo_scripts', 'odoo_type')) or 'odoo7'
image = "%s/%s:latest" % (registry, project) image = "%s/%s:latest" % (registry, project)
postgresql_version = (
c.has_section('odoo_scripts') and
c.has_option('odoo_scripts', 'postgresql_version') and
c.get('odoo_scripts', 'postgresql_version')) or '9.6'
logging.debug("Docker image: %s", image) logging.debug("Docker image: %s", image)
# detect if docker image already exists # detect if docker image already exists
docker_client = docker.Client(base_url='unix://var/run/docker.sock') docker_client = docker.Client(base_url='unix://var/run/docker.sock')
...@@ -201,15 +214,7 @@ ...@@ -201,15 +214,7 @@
else: else:
logging.info("Test image found") logging.info("Test image found")
options = [ binds = []
'--name',
project_name,
'--rm',
'--publish',
'8069:8069',
'--tty',
'--interactive',
]
arg = [ arg = [
'start', 'start',
] ]
...@@ -249,8 +254,6 @@ ...@@ -249,8 +254,6 @@
# auto detect local ip # auto detect local ip
if use_host_network: if use_host_network:
local_ip = '127.0.0.1' local_ip = '127.0.0.1'
options.append('--network')
options.append('host')
else: else:
local_ip = None local_ip = None
try: try:
...@@ -275,8 +278,7 @@ ...@@ -275,8 +278,7 @@
password = db_password password = db_password
if os.path.isfile(local_conf_path): if os.path.isfile(local_conf_path):
logging.info('Local configuration file found: %s' % local_conf_path) logging.info('Local configuration file found: %s' % local_conf_path)
options.append('--volume') binds.append('%s:/opt/odoo/etc/odoo.conf' % os.path.join(
options.append('%s:/opt/odoo/etc/odoo.conf' % os.path.join(
project_path, local_conf_path)) project_path, local_conf_path))
cp_local = ConfigParser.ConfigParser() cp_local = ConfigParser.ConfigParser()
cp_local.read(local_conf_path) cp_local.read(local_conf_path)
...@@ -287,6 +289,5 @@ ...@@ -287,6 +289,5 @@
# data volume handling # data volume handling
if odoo_type != 'odoo7': if odoo_type != 'odoo7':
options.append('--mount')
data_volume_name = '{}_data'.format(project_name) data_volume_name = '{}_data'.format(project_name)
logging.debug('Using data volume %s', data_volume_name) logging.debug('Using data volume %s', data_volume_name)
...@@ -291,13 +292,6 @@ ...@@ -291,13 +292,6 @@
data_volume_name = '{}_data'.format(project_name) data_volume_name = '{}_data'.format(project_name)
logging.debug('Using data volume %s', data_volume_name) logging.debug('Using data volume %s', data_volume_name)
volumes = docker_client.volumes(filters={'name': data_volume_name}) volume = getVolume(docker_client, data_volume_name)
if volumes['Volumes']:
logging.debug('Volume %s already exist', data_volume_name)
volume = volumes['Volumes'][0]
else:
logging.debug('Creating volume %s', data_volume_name)
volume = docker_client.create_volume(name=data_volume_name)
mount_opts = 'source={},target=/mnt/data'.format(data_volume_name)
# make sure the permission in the volume are correct # make sure the permission in the volume are correct
# TODO replace by something cleaner if possible # TODO replace by something cleaner if possible
call(['docker', 'run', '--rm', '--mount', mount_opts, 'busybox', 'chmod', '777', '/mnt/data']) call(['docker', 'run', '--rm', '--mount', mount_opts, 'busybox', 'chmod', '777', '/mnt/data'])
...@@ -301,8 +295,8 @@ ...@@ -301,8 +295,8 @@
# make sure the permission in the volume are correct # make sure the permission in the volume are correct
# TODO replace by something cleaner if possible # TODO replace by something cleaner if possible
call(['docker', 'run', '--rm', '--mount', mount_opts, 'busybox', 'chmod', '777', '/mnt/data']) call(['docker', 'run', '--rm', '--mount', mount_opts, 'busybox', 'chmod', '777', '/mnt/data'])
options.append(mount_opts) binds.append('{}:/mnt/data'.format(data_volume_name))
arg.append('--data-dir /mnt/data') arg.append('--data-dir /mnt/data')
else: else:
logging.debug('No data volume for this odoo version') logging.debug('No data volume for this odoo version')
...@@ -305,6 +299,27 @@ ...@@ -305,6 +299,27 @@
arg.append('--data-dir /mnt/data') arg.append('--data-dir /mnt/data')
else: else:
logging.debug('No data volume for this odoo version') logging.debug('No data volume for this odoo version')
if start_postgresql:
pg_repository = 'xcgd/postgresql'
pg_image = '{}:{}'.format(pg_repository, postgresql_version)
name = 'pg{}'.format(postgresql_version)
docker_client.pull(repository=pg_repository, tag=postgresql_version)
pg_data_volume_name = 'postgresql_{}-{}'.format(postgresql_version, project_name)
host_pg_port = 5433
volume = getVolume(docker_client, pg_data_volume_name)
host_config = docker_client.create_host_config(
binds=['{}:/var/lib/postgresql'.format(pg_data_volume_name)],
port_bindings={5432: host_pg_port},
)
logging.debug('Creating postgresql container')
pg = docker_client.create_container(image=pg_image, host_config=host_config, name=name)
logging.debug('Starting postgresql container')
docker_client.start(pg.get('Id'))
# give pg the time to start up
import time
time.sleep(5)
arg.append('--db_port')
arg.append(str(host_pg_port))
# Check that connection can be done, try to create user if asked to # Check that connection can be done, try to create user if asked to
...@@ -309,3 +324,4 @@ ...@@ -309,3 +324,4 @@
# Check that connection can be done, try to create user if asked to # Check that connection can be done, try to create user if asked to
# TODO handle the case where the database is still starting up (and remove the sleep)
try: try:
...@@ -311,7 +327,11 @@ ...@@ -311,7 +327,11 @@
try: try:
test_connection = connect(user=user, password=password, database='postgres', host=local_ip) if local_ip or start_postgresql:
port = host_pg_port if start_postgresql else None
test_connection = connect(user=user, password=password, database='postgres', host=local_ip, port=port)
else:
test_connection = connect(user=user, password=password, database='postgres')
except OperationalError as exception: except OperationalError as exception:
if nmspc.create_user: if nmspc.create_user:
logging.info('Cannot connect to database with user %s', user) logging.info('Cannot connect to database with user %s', user)
logging.info(exception) logging.info(exception)
logging.info('Creating user %s', user) logging.info('Creating user %s', user)
...@@ -313,10 +333,13 @@ ...@@ -313,10 +333,13 @@
except OperationalError as exception: except OperationalError as exception:
if nmspc.create_user: if nmspc.create_user:
logging.info('Cannot connect to database with user %s', user) logging.info('Cannot connect to database with user %s', user)
logging.info(exception) logging.info(exception)
logging.info('Creating user %s', user) logging.info('Creating user %s', user)
loginname = pwd.getpwuid(os.getuid())[0] if start_postgresql:
connection = connect(user=loginname, database='postgres') connection = connect(user='pg', database='postgres', host=local_ip, port=host_pg_port)
else:
loginname = pwd.getpwuid(os.getuid())[0]
connection = connect(user=loginname, database='postgres')
with connection.cursor() as cursor: with connection.cursor() as cursor:
# not injection safe but you are on your own machine # not injection safe but you are on your own machine
# with already full access to db # with already full access to db
...@@ -342,11 +365,16 @@ ...@@ -342,11 +365,16 @@
arg.append('--addons-path') arg.append('--addons-path')
arg.append(','.join(all_addons_dir)) arg.append(','.join(all_addons_dir))
cmd = ['docker', 'run'] # add volumes
cmd.extend(options) odoo_host_config = docker_client.create_host_config(
cmd.append(image) binds=binds,
cmd.extend(arg) port_bindings={8069: 8069},
logging.debug(cmd) network_mode='host' if use_host_network else 'bridge',
# TODO directly use docker-py instead )
call(cmd) logging.debug('Creating odoo container')
odoo = docker_client.create_container(
name=project_name, host_config=odoo_host_config,
image=image, command=arg, tty=True)
logging.debug('Starting odoo container')
docker_client.start(odoo.get('Id'))
...@@ -352,5 +380,46 @@ ...@@ -352,5 +380,46 @@
# TODO add handling of signal to reload def signal_handler(code, frame):
if code == signal.SIGINT:
logging.debug('You pressed Ctrl+C!')
logging.info('Stopping odoo')
docker_client.stop(odoo.get('Id'))
logging.info('Removing container odoo')
docker_client.remove_container(odoo.get('Id'))
if start_postgresql:
logging.info('Stopping postgresql')
docker_client.stop(pg.get('Id'))
logging.info('Removing container postgresql')
docker_client.remove_container(pg.get('Id'))
sys.exit(0)
# TODO add a kill of pg when crashing
signal.signal(signal.SIGINT, signal_handler)
logging.info('Press Ctrl+C to quit')
# print docker logs of odoo
stream = docker_client.logs(odoo.get('Id'), stream=True, follow=True)
while True:
try:
for log in stream:
sys.stdout.write(log)
except ConnectionError:
# If there is no log for some time requests throw some errors
# we ignore them
pass
# Clean up, just in case
# signal_handler(signal.SIGINT, None)
# TODO add handling of signal to restart odoo
def getVolume(docker_client, data_volume_name):
"""Return the volume passed in parameter, creating it if it does not exists
"""
volumes = docker_client.volumes(filters={'name': data_volume_name})
if volumes['Volumes']:
logging.debug('Volume %s already exist', data_volume_name)
return volumes['Volumes'][0]
else:
logging.debug('Creating volume %s', data_volume_name)
return docker_client.create_volume(name=data_volume_name)
if __name__ == "__main__": if __name__ == "__main__":
return_code = main() return_code = main()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment