odoo-openupgrade-wizard/odoo_openupgrade_wizard/tools/tools_odoo_instance.py
2024-03-23 21:59:12 +01:00

124 lines
4.3 KiB
Python

import socket
import time
import odoorpc
from loguru import logger
# Wait for the launch of odoo instance 60 seconds
_ODOO_RPC_MAX_TRY = 60
_ODOO_RPC_URL = "0.0.0.0"
class OdooInstance:
env = False
version = False
def __init__(self, ctx, database, alternative_xml_rpc_port=False):
port = (
alternative_xml_rpc_port
and alternative_xml_rpc_port
or ctx.obj["config"]["odoo_host_xmlrpc_port"]
)
logger.info(
f"Connect to database {database} via odoorpc (Port {port})..."
)
for x in range(1, _ODOO_RPC_MAX_TRY + 1):
# Connection
try:
rpc_connexion = odoorpc.ODOO(
_ODOO_RPC_URL,
"jsonrpc",
port=port,
timeout=ctx.obj["config"]["odoo_rpc_timeout"],
)
# connexion is OK
break
except (socket.gaierror, socket.error) as e:
if x < _ODOO_RPC_MAX_TRY:
logger.debug(
f"{x}/{_ODOO_RPC_MAX_TRY}"
" Unable to connect to the server."
" Retrying in 1 second ..."
)
time.sleep(1)
else:
logger.critical(
f"{x}/{_ODOO_RPC_MAX_TRY}"
" Unable to connect to the server."
)
raise e
# Login
try:
rpc_connexion.login(database, "admin", "admin")
except Exception as e:
logger.error(
f"Unable to connect to http://localhost:{port}"
" with login 'admin' and password 'admin."
)
raise e
self.env = rpc_connexion.env
self.version = rpc_connexion.version
def browse_by_search(
self, model_name, domain=False, order=False, limit=False
):
domain = domain or []
model = self.env[model_name]
return model.browse(model.search(domain, order=order, limit=limit))
def browse_by_create(self, model_name, vals):
model = self.env[model_name]
return model.browse(model.create(vals))
def install_modules(self, module_names):
if type(module_names) is str:
module_names = [module_names]
installed_modules = []
i = 0
for module_name in module_names:
i += 1
log_prefix = f"{i}/{len(module_names)} - Module '{module_name}': "
modules = self.browse_by_search(
"ir.module.module", [("name", "=", module_name)]
)
if not len(modules):
logger.error(f"{log_prefix}': Not found.")
continue
module = modules[0]
if module.state == "installed":
logger.info(f"{log_prefix}': still installed. Skipped.")
elif module.state == "uninstalled":
try_qty = 0
installed = False
while installed is False:
try_qty += 1
try_qty_text = f" (try #{try_qty})" if try_qty != 1 else ""
logger.info(f"{log_prefix}': Installing ...{try_qty_text}")
try:
module.button_immediate_install()
installed = True
installed_modules.append(module_name)
time.sleep(5)
except Exception as e:
if try_qty <= 5:
sleeping_time = 2 * try_qty * 60
logger.warning(
f"Error. Retrying in {sleeping_time} seconds."
f"\n{e}"
)
time.sleep(sleeping_time)
else:
logger.critical(
f"Error after {try_qty} try. Exiting." f"\n{e}"
)
raise e
else:
logger.error(
f"{log_prefix}': In the {module.state} state."
" (Unable to install)"
)
return installed_modules