From 11a59249b33f13f1316169b2e8769081f20eec3d Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 11 Apr 2022 12:59:03 +0200 Subject: [PATCH] [ADD] cli 'run' command + tests; [WIP] add generate_odoo_command --- odoo_openupgrade_wizard/cli.py | 2 + odoo_openupgrade_wizard/cli_docker_build.py | 2 +- odoo_openupgrade_wizard/cli_get_code.py | 4 +- odoo_openupgrade_wizard/cli_init.py | 2 +- odoo_openupgrade_wizard/cli_options.py | 20 ++++ odoo_openupgrade_wizard/cli_run.py | 36 +++++++ .../configuration_version_dependant.py | 15 --- odoo_openupgrade_wizard/tools_odoo.py | 95 +++++++++++++++++++ tests/cli_B_02_docker_build_test.py | 1 - tests/cli_B_03_run_test.py | 28 ++++++ 10 files changed, 184 insertions(+), 21 deletions(-) create mode 100644 odoo_openupgrade_wizard/cli_run.py create mode 100644 odoo_openupgrade_wizard/tools_odoo.py create mode 100644 tests/cli_B_03_run_test.py diff --git a/odoo_openupgrade_wizard/cli.py b/odoo_openupgrade_wizard/cli.py index 82cdeae..8aaac0f 100644 --- a/odoo_openupgrade_wizard/cli.py +++ b/odoo_openupgrade_wizard/cli.py @@ -9,6 +9,7 @@ import odoo_openupgrade_wizard from odoo_openupgrade_wizard.cli_docker_build import docker_build from odoo_openupgrade_wizard.cli_get_code import get_code from odoo_openupgrade_wizard.cli_init import init +from odoo_openupgrade_wizard.cli_run import run from odoo_openupgrade_wizard.tools_system import ensure_folder_exists @@ -92,3 +93,4 @@ def main(ctx, env_folder, filestore_folder): main.add_command(init) main.add_command(get_code) main.add_command(docker_build) +main.add_command(run) diff --git a/odoo_openupgrade_wizard/cli_docker_build.py b/odoo_openupgrade_wizard/cli_docker_build.py index 7639220..1a3370a 100644 --- a/odoo_openupgrade_wizard/cli_docker_build.py +++ b/odoo_openupgrade_wizard/cli_docker_build.py @@ -6,7 +6,7 @@ from odoo_openupgrade_wizard.cli_options import ( get_odoo_versions_from_options, releases_options, ) -from odoo_openupgrade_wizard.configuration_version_dependant import ( +from odoo_openupgrade_wizard.tools_odoo import ( get_docker_image_tag, get_odoo_env_path, ) diff --git a/odoo_openupgrade_wizard/cli_get_code.py b/odoo_openupgrade_wizard/cli_get_code.py index 1adb303..2d34885 100644 --- a/odoo_openupgrade_wizard/cli_get_code.py +++ b/odoo_openupgrade_wizard/cli_get_code.py @@ -4,9 +4,7 @@ from odoo_openupgrade_wizard.cli_options import ( get_odoo_versions_from_options, releases_options, ) -from odoo_openupgrade_wizard.configuration_version_dependant import ( - get_odoo_env_path, -) +from odoo_openupgrade_wizard.tools_odoo import get_odoo_env_path from odoo_openupgrade_wizard.tools_system import git_aggregate diff --git a/odoo_openupgrade_wizard/cli_init.py b/odoo_openupgrade_wizard/cli_init.py index 09d5f2c..9191ec3 100644 --- a/odoo_openupgrade_wizard/cli_init.py +++ b/odoo_openupgrade_wizard/cli_init.py @@ -4,10 +4,10 @@ import click from odoo_openupgrade_wizard import templates from odoo_openupgrade_wizard.configuration_version_dependant import ( - get_odoo_env_path, get_odoo_versions, get_release_options, ) +from odoo_openupgrade_wizard.tools_odoo import get_odoo_env_path from odoo_openupgrade_wizard.tools_system import ( ensure_file_exists_from_template, ensure_folder_exists, diff --git a/odoo_openupgrade_wizard/cli_options.py b/odoo_openupgrade_wizard/cli_options.py index 59bbf85..a42df95 100644 --- a/odoo_openupgrade_wizard/cli_options.py +++ b/odoo_openupgrade_wizard/cli_options.py @@ -22,3 +22,23 @@ def get_odoo_versions_from_options(ctx, releases_arg): if odoo_version["release"] in releases: odoo_versions.append(odoo_version) return odoo_versions + + +def step_options(function): + function = click.option( + "--step", + required=True, + prompt=True, + type=str, + help="Migration step for which you want to perform the operation.", + )(function) + return function + + +def get_migration_step_from_options(ctx, step_arg): + step = float(step_arg) + for migration_step in ctx.obj["config"]["migration_steps"]: + if migration_step["name"] == step: + return migration_step + # TODO, improve exception + raise Exception diff --git a/odoo_openupgrade_wizard/cli_run.py b/odoo_openupgrade_wizard/cli_run.py new file mode 100644 index 0000000..5f59322 --- /dev/null +++ b/odoo_openupgrade_wizard/cli_run.py @@ -0,0 +1,36 @@ +from time import sleep + +import click +from loguru import logger + +from odoo_openupgrade_wizard.cli_options import ( + get_migration_step_from_options, + step_options, +) +from odoo_openupgrade_wizard.tools_odoo import kill_odoo, run_odoo + + +@click.command() +@step_options +@click.option( + "--duration", + type=float, + default=False, + help="Duration of the execution of the script. Mainly used" + " for test purpose, for commands that are using input()" + " function to stop.", +) +@click.pass_context +def run(ctx, step, duration): + + migration_step = get_migration_step_from_options(ctx, step) + try: + run_odoo(ctx, migration_step) + if duration: + sleep(duration) + else: + input("Press 'Enter' to kill the odoo container and exit ...") + except (KeyboardInterrupt, SystemExit): + logger.info("Received Keyboard Interrupt or System Exiting...") + finally: + kill_odoo(ctx, migration_step) diff --git a/odoo_openupgrade_wizard/configuration_version_dependant.py b/odoo_openupgrade_wizard/configuration_version_dependant.py index b3298d4..c6688ae 100644 --- a/odoo_openupgrade_wizard/configuration_version_dependant.py +++ b/odoo_openupgrade_wizard/configuration_version_dependant.py @@ -1,5 +1,3 @@ -from pathlib import Path - # See : https://github.com/OCA/openupgradelib/issues/248 # https://github.com/OCA/openupgradelib/issues/288 _LEGACY_OPENUPGRADELIB = ( @@ -84,16 +82,3 @@ def get_odoo_versions(initial_release: float, final_release: float) -> list: ): result.append(version_template) return result - - -def get_odoo_env_path(ctx, odoo_version: dict) -> Path: - folder_name = "env_%s" % str(odoo_version["release"]).rjust(4, "0") - return ctx.obj["src_folder_path"] / folder_name - - -def get_docker_image_tag(ctx, odoo_version: dict): - """Return a docker image tag, based on project name and odoo release""" - return "odoo-openupgrade-wizard-image-%s-%s" % ( - ctx.obj["config"]["project_name"], - str(odoo_version["release"]).rjust(4, "0"), - ) diff --git a/odoo_openupgrade_wizard/tools_odoo.py b/odoo_openupgrade_wizard/tools_odoo.py new file mode 100644 index 0000000..97c5720 --- /dev/null +++ b/odoo_openupgrade_wizard/tools_odoo.py @@ -0,0 +1,95 @@ +from pathlib import Path + +import docker +from loguru import logger + + +def get_odoo_env_path(ctx, odoo_version: dict) -> Path: + folder_name = "env_%s" % str(odoo_version["release"]).rjust(4, "0") + return ctx.obj["src_folder_path"] / folder_name + + +def get_docker_image_tag(ctx, odoo_version: dict) -> str: + """Return a docker image tag, based on project name and odoo release""" + return "odoo-openupgrade-wizard-image-%s-%s" % ( + ctx.obj["config"]["project_name"], + str(odoo_version["release"]).rjust(4, "0"), + ) + + +def get_docker_container_name(ctx, migration_step: dict) -> str: + """Return a docker container name, based on project name, + odoo release and migration step""" + return "odoo-openupgrade-wizard-container-%s-%s-step-%s" % ( + ctx.obj["config"]["project_name"], + str(migration_step["release"]).rjust(4, "0"), + str(migration_step["name"]).rjust(2, "0"), + ) + + +def get_odoo_version_from_migration_step(ctx, migration_step: dict) -> dict: + for odoo_version in ctx.obj["config"]["odoo_versions"]: + if odoo_version["release"] == migration_step["release"]: + return odoo_version + # TODO, improve exception + raise Exception + + +def generate_odoo_command( + ctx, migration_step: dict, update_all: bool = False +) -> str: + # TODO, make it dynamic + addons_path = ( + "/container_env/src/odoo/addons," "/container_env/src/odoo/odoo/addons" + ) + update_all_cmd = update_all and "--update_all" or "" + return ( + f"/container_env/src/odoo/odoo-bin" + f" --db_host db" + f" --db_port 5432" + f" --db_user odoo" + f" --db_password odoo" + f" --addons-path {addons_path}" + f" {update_all_cmd}" + ) + + +def run_odoo(ctx, migration_step: dict): + client = docker.from_env() + odoo_version = get_odoo_version_from_migration_step(ctx, migration_step) + folder_path = get_odoo_env_path(ctx, odoo_version) + + command = generate_odoo_command(ctx, migration_step) + + image_name = get_docker_image_tag(ctx, odoo_version) + container_name = get_docker_container_name(ctx, migration_step) + logger.info( + "Launching Odoo Docker container named %s based on image '%s'." + % (container_name, image_name) + ) + container = client.containers.run( + image_name, + name=container_name, + command=command, + ports={"8069": 8069, "5432": 5432}, + volumes=["%s:/container_env/" % (folder_path)], + links={"db": "db"}, + detach=True, + auto_remove=True, + ) + logger.info("Container Launched. Command executed : %s" % command) + return container + + +def kill_odoo(ctx, migration_step: dict): + client = docker.from_env() + containers = client.containers.list( + all=True, + filters={"name": get_docker_container_name(ctx, migration_step)}, + ) + for container in containers: + logger.info( + "Stop container %s, based on image '%s'." + % (container.name, ",".join(container.image.tags)) + ) + container.stop() diff --git a/tests/cli_B_02_docker_build_test.py b/tests/cli_B_02_docker_build_test.py index 9a27382..5caa074 100644 --- a/tests/cli_B_02_docker_build_test.py +++ b/tests/cli_B_02_docker_build_test.py @@ -20,7 +20,6 @@ def test_cli_docker_build(): ) assert result.exit_code == 0 - # TODO, add test to see if image exists docker_client = docker.from_env() assert docker_client.images.get( diff --git a/tests/cli_B_03_run_test.py b/tests/cli_B_03_run_test.py new file mode 100644 index 0000000..4f86daf --- /dev/null +++ b/tests/cli_B_03_run_test.py @@ -0,0 +1,28 @@ +from pathlib import Path + +import docker +from click.testing import CliRunner + +from odoo_openupgrade_wizard.cli import main + + +def test_cli_run(): + output_folder_path = Path("./tests/output_B") + + result = CliRunner().invoke( + main, + [ + "--env-folder=%s" % output_folder_path, + "run", + "--step=1", + "--duration=2", + ], + catch_exceptions=False, + ) + assert result.exit_code == 0 + + # Ensure that all the containers are removed + docker_client = docker.from_env() + assert not docker_client.containers.list( + all=True, filters={"name": "odoo-openupgrade-wizard"} + )