diff --git a/NEWS.rst b/NEWS.rst index 0b3e52d2278fce200c74b928f3fc893271eb922a_TkVXUy5yc3Q=..4554c7b603b7d8d33246c296b19a2146d1c91da7_TkVXUy5yc3Q= 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,12 @@ History ======= +16.7.0 +------ + +Add command to run a redner for a project, from docker_dev_start or directly with docker_redner. + + 16.6.0 ------ diff --git a/odoo_scripts/config.py b/odoo_scripts/config.py index 0b3e52d2278fce200c74b928f3fc893271eb922a_b2Rvb19zY3JpcHRzL2NvbmZpZy5weQ==..4554c7b603b7d8d33246c296b19a2146d1c91da7_b2Rvb19zY3JpcHRzL2NvbmZpZy5weQ== 100644 --- a/odoo_scripts/config.py +++ b/odoo_scripts/config.py @@ -234,9 +234,12 @@ _logger.warning("Unexpected odoo_type: %s", self.odoo_type) read_expanded("postgresql_version", "9.6") self.start_py3o = section.get("start_py3o", "no") in ("yes", "true") - self.start_rednerd = section.get("start_rednerd", "no") in ("yes", "true") - self.rednerd_version = section.get("rednerd_version", "latest") - self.rednerd_repository = section.get("rednerd_repository", None) + self.start_rednerd = section.get("start_rednerd", "no") in ( + "yes", + "true", + ) + read_expanded("rednerd_version", "latest") + read_expanded("rednerd_repository", None) class Singleton(type): @@ -271,19 +274,3 @@ return_code = main(sys.argv[1:]) if return_code: exit(return_code) - self.postgresql_version = config_parser.get( - section, "postgresql_version", fallback="9.6" - ) - self.start_py3o = config_parser.get( - section, "start_py3o", fallback="no" - ) in ("yes", "true") - - self.start_rednerd = config_parser.get( - section, "start_rednerd", fallback="no" - ) in ("yes", "true") - self.rednerd_version = config_parser.get( - section, "rednerd_version", fallback="latest" - ) - self.rednerd_repository = config_parser.get( - section, "rednerd_repository", fallback=None - ) diff --git a/odoo_scripts/docker_client.py b/odoo_scripts/docker_client.py index 0b3e52d2278fce200c74b928f3fc893271eb922a_b2Rvb19zY3JpcHRzL2RvY2tlcl9jbGllbnQucHk=..4554c7b603b7d8d33246c296b19a2146d1c91da7_b2Rvb19zY3JpcHRzL2RvY2tlcl9jbGllbnQucHk= 100644 --- a/odoo_scripts/docker_client.py +++ b/odoo_scripts/docker_client.py @@ -74,7 +74,6 @@ :param user: User to execute command as. :param interactive: True if the container needs to be interactive """ - import ipdb;ipdb.set_trace() if interactive: dockerpty.exec_command(cls.client.api, container.id, command) # it would be nice to return the exec command return code, but diff --git a/odoo_scripts/docker_postgresql.py b/odoo_scripts/docker_postgresql.py index 0b3e52d2278fce200c74b928f3fc893271eb922a_b2Rvb19zY3JpcHRzL2RvY2tlcl9wb3N0Z3Jlc3FsLnB5..4554c7b603b7d8d33246c296b19a2146d1c91da7_b2Rvb19zY3JpcHRzL2RvY2tlcl9wb3N0Z3Jlc3FsLnB5 100644 --- a/odoo_scripts/docker_postgresql.py +++ b/odoo_scripts/docker_postgresql.py @@ -25,4 +25,5 @@ POSTGRES_PASSWORD = "this-could-be-anything" PSQL = "psql" +"""Command to use to run psql in the docker container.""" SH = "SH" @@ -28,4 +29,5 @@ SH = "SH" +"""Command to use to run sh in the docker container.""" def docker_run_postgresql( diff --git a/odoo_scripts/docker_rednerd.py b/odoo_scripts/docker_rednerd.py index 0b3e52d2278fce200c74b928f3fc893271eb922a_b2Rvb19zY3JpcHRzL2RvY2tlcl9yZWRuZXJkLnB5..4554c7b603b7d8d33246c296b19a2146d1c91da7_b2Rvb19zY3JpcHRzL2RvY2tlcl9yZWRuZXJkLnB5 100644 --- a/odoo_scripts/docker_rednerd.py +++ b/odoo_scripts/docker_rednerd.py @@ -1,1 +1,2 @@ +#!/usr/bin/env python3 # vim: set shiftwidth=4 softtabstop=4: @@ -1,6 +2,5 @@ # vim: set shiftwidth=4 softtabstop=4: -""" -Rednerd API (0.1.0) +"""Run a rednerd docker with volume based on project name. Documentation: http://127.0.0.1:12345/docs """ @@ -9,6 +9,7 @@ import logging import os import sys +import tempfile import time import docker @@ -21,7 +22,7 @@ __version__ = "1.0.0" __date__ = "2021-01-14" -__updated__ = "2021-01-14" +__updated__ = "2021-02-26" MIGRATE = "migrate" ADMIN_PASSWORD = "admin-password" @@ -43,7 +44,7 @@ docker_client, project_name, repository, - attach=True, - stop_at_exist=True, + attach: bool = True, + stop_at_exit: bool = True, redner_config=dict(), redner_port=None, @@ -48,3 +49,4 @@ redner_config=dict(), redner_port=None, + redner_socket=None, version="latest", @@ -50,2 +52,3 @@ version="latest", + command: str = None, ): @@ -51,7 +54,11 @@ ): + """ + :param redner_port: Port to use, uses socket if no port is provided + :param redner_socket: Indicate socket to use (path outside the container) + """ super(DockerRednerd, self).__init__() self.name = "rednerd_{}".format(project_name) self.repository = repository self.version = version self.attach = attach self.base_image = "{}:{}".format(self.repository, self.version) @@ -52,9 +59,9 @@ super(DockerRednerd, self).__init__() self.name = "rednerd_{}".format(project_name) self.repository = repository self.version = version self.attach = attach self.base_image = "{}:{}".format(self.repository, self.version) - self.stop_at_exist = stop_at_exist + self.stop_at_exit = stop_at_exit self.docker_cli = docker_client self.redner_config = redner_config @@ -59,9 +66,18 @@ self.docker_cli = docker_client self.redner_config = redner_config - self.redner_port = redner_port or None + if redner_port is not None: + self.redner_port = redner_port + else: + # create a socket + if redner_socket is None: + self.redner_socket = tempfile.TemporaryDirectory( + prefix="odoo_scripts_rednerd_socket-" + ).name + if redner_socket is not None: + self.redner_socket = redner_socket # Retrieve the container if it already exist try: self.container = self.docker_cli.containers.get(self.name) except docker.errors.NotFound: self.container = None @@ -62,11 +78,12 @@ # Retrieve the container if it already exist try: self.container = self.docker_cli.containers.get(self.name) except docker.errors.NotFound: self.container = None + self.command = command def start(self): """Start rednerd container""" self.pull_image() if self.container is not None: @@ -68,9 +85,10 @@ def start(self): """Start rednerd container""" self.pull_image() if self.container is not None: - _logger.debug("%s Container already exist", self.name) + _logger.debug("Container %s already exist", self.name) + # TODO why stop rednerd? maybe because port is different. # stop and remove self.stop_and_remove() # call run() with detach=True @@ -74,6 +92,6 @@ # stop and remove self.stop_and_remove() # call run() with detach=True - self.container = self.docker_cli.containers.create( + create_param = dict( image=self.base_image, name=self.name, @@ -78,4 +96,4 @@ image=self.base_image, name=self.name, - ports={"80/tcp": self.redner_port}, + ports=dict(), environment=self.redner_config, @@ -81,2 +99,4 @@ environment=self.redner_config, + volumes=dict(), + command=[self.command, "--token-secret", self.name], ) @@ -82,3 +102,17 @@ ) - _logger.info("Starting %s container", self.name) + if hasattr(self, "redner_port"): + create_param["ports"]["80/tcp"] = self.redner_port + _logger.info("Using port %d", self.redner_port) + if hasattr(self, "redner_socket"): + socket_path = "/run/rednerd.socket" + create_param["volumes"][self.redner_socket, "rednerd.socket"] = { + "bind": socket_path, + "mode": "rw", + } + create_param["command"].extend(["--socket-path", socket_path]) + # TODO missing directory cleanup + _logger.info("Using socket %s", self.redner_socket) + self.container = self.docker_cli.containers.create(**create_param) + _logger.info("Starting container %s", self.name) + _logger.debug(create_param) self.container.start() @@ -84,7 +118,5 @@ self.container.start() - if self.attach: - self.logs() # give rednerd the time to start up # wait with self.container.wait() # self.container.wait() @@ -87,7 +119,7 @@ # give rednerd the time to start up # wait with self.container.wait() # self.container.wait() - if self.stop_at_exist: + if self.stop_at_exit: atexit.register(self.stop_and_remove) @@ -92,5 +124,8 @@ atexit.register(self.stop_and_remove) + if self.attach: + self.logs() + time.sleep(5) return True @@ -105,8 +140,9 @@ def logs(self): """Display container logs""" - for l in self.container.logs(stream=True): - _logger.info(l) + for log in self.container.logs(stream=True): + # log has an unwanted extra \n at the end + _logger.info(log.decode("UTF-8")[:-1]) def stop(self): """ @@ -174,7 +210,7 @@ program_license = """%s Created by Oury Balde on %s. - Copyright 2020 XCG Consulting. All rights reserved. + Copyright 2021 XCG Consulting. All rights reserved. Licensed under the MIT License @@ -210,4 +246,5 @@ default=REDNER_ADMIN_PASSWORD, ) parser.add_argument( + "-p", "--port", @@ -213,8 +250,14 @@ "--port", - help="Redner port to use [default: %(default)s]", - default=8080, + help="Redner port to use, use a socket if empty [default: %(default)s]", + default=None, + type=int, + ) + parser.add_argument( + "--socket", + help="Specify Redner socket to use [default: %(default)s]", + default=None, ) parser.add_argument( "-c", "--command", help="Command to run. If specified the command will not be interactive" @@ -216,7 +259,7 @@ ) parser.add_argument( "-c", "--command", help="Command to run. If specified the command will not be interactive" - ", otherwise it will be interactive.", + ", otherwise it will be interactive. [default: %(default)s]", metavar="command", @@ -222,5 +265,5 @@ metavar="command", - default=None, + default="serve", ) return parser @@ -256,9 +299,9 @@ redner_config=env, redner_port=port, version=rednerd_version, - stop_at_exist=False, + command=command, ) # TODO: # create a user "need an admin password" # synchronize templates @@ -260,8 +303,9 @@ ) # TODO: # create a user "need an admin password" # synchronize templates + # TODO display ir.config_parameter to set docker_rednerd.start() @@ -265,5 +309,7 @@ docker_rednerd.start() + return 0 + if __name__ == "__main__": @@ -268,6 +314,9 @@ if __name__ == "__main__": - main(sys.argv[1:]) - # return_code = main(sys.argv[1:]) - # if return_code: - # exit(return_code) + return_code = main(sys.argv[1:]) + if return_code: + exit(return_code) + +# TODO: +# - bind /CONTAINER_ALREADY_STARTED_PLACEHOLDER somehow +# - bind pg database somehow