161 lines
5.3 KiB
Python
161 lines
5.3 KiB
Python
import os
|
|
import sys
|
|
import argparse
|
|
import subprocess
|
|
import configparser
|
|
import psycopg2
|
|
|
|
def get_custom_addons_modules(addons_path):
|
|
"""
|
|
Scans the given addons path and returns a list of directory names
|
|
that contain a __manifest__.py file.
|
|
"""
|
|
modules = []
|
|
if not os.path.exists(addons_path):
|
|
print(f"Error: Addons path '{addons_path}' does not exist.")
|
|
return []
|
|
|
|
for item in os.listdir(addons_path):
|
|
item_path = os.path.join(addons_path, item)
|
|
if os.path.isdir(item_path):
|
|
manifest_path = os.path.join(item_path, '__manifest__.py')
|
|
if os.path.exists(manifest_path):
|
|
modules.append(item)
|
|
return modules
|
|
|
|
def get_db_params(config_path):
|
|
"""
|
|
Parses the Odoo config file to extract database connection parameters.
|
|
"""
|
|
config = configparser.ConfigParser()
|
|
try:
|
|
config.read(config_path)
|
|
except Exception as e:
|
|
print(f"Error reading config file: {e}")
|
|
return {}
|
|
|
|
db_params = {}
|
|
if 'options' in config:
|
|
params = config['options']
|
|
db_params['host'] = params.get('db_host', 'localhost')
|
|
db_params['port'] = params.get('db_port', '5432')
|
|
db_params['user'] = params.get('db_user', 'odoo')
|
|
db_params['password'] = params.get('db_password', '')
|
|
|
|
return db_params
|
|
|
|
def get_installed_modules(modules_list, db_name, db_params):
|
|
"""
|
|
Connects to the database and filters the given list of modules specifically
|
|
for those that are installed (state='installed').
|
|
"""
|
|
installed_modules = []
|
|
|
|
conn_params = {
|
|
'dbname': db_name,
|
|
'user': db_params.get('user', 'odoo'),
|
|
'password': db_params.get('password', ''),
|
|
'host': db_params.get('host', 'localhost'),
|
|
'port': db_params.get('port', '5432')
|
|
}
|
|
|
|
# Filter out empty or None values to use defaults or avoid errors
|
|
conn_params = {k: v for k, v in conn_params.items() if v}
|
|
|
|
try:
|
|
conn = psycopg2.connect(**conn_params)
|
|
cur = conn.cursor()
|
|
|
|
# Check if modules are installed
|
|
if not modules_list:
|
|
return []
|
|
|
|
query = "SELECT name FROM ir_module_module WHERE state = 'installed' AND name IN %s"
|
|
cur.execute(query, (tuple(modules_list),))
|
|
rows = cur.fetchall()
|
|
|
|
installed_modules = [row[0] for row in rows]
|
|
|
|
cur.close()
|
|
conn.close()
|
|
except psycopg2.Error as e:
|
|
print(f"Database error: {e}")
|
|
print("Ensure psycopg2 matches the server configuration.")
|
|
return []
|
|
except Exception as e:
|
|
print(f"Error checking installed modules: {e}")
|
|
return []
|
|
|
|
return installed_modules
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Upgrade installed modules in customaddons for a specific database.")
|
|
parser.add_argument('-d', '--database', required=True, help="Database name to upgrade modules on.")
|
|
parser.add_argument('-c', '--config', required=True, help="Path to Odoo configuration file.")
|
|
parser.add_argument('--odoo-bin', default='./odoo/odoo-bin', help="Path to odoo-bin executable (default: ./odoo/odoo-bin)")
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Determine customaddons path relative to this script
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
custom_addons_path = os.path.join(script_dir, 'customaddons')
|
|
|
|
print(f"Scanning for modules in {custom_addons_path}...")
|
|
modules = get_custom_addons_modules(custom_addons_path)
|
|
|
|
if not modules:
|
|
print("No modules found in customaddons.")
|
|
sys.exit(0)
|
|
|
|
print(f"Found {len(modules)} local modules.")
|
|
|
|
# Get DB params from config
|
|
db_params = get_db_params(args.config)
|
|
|
|
print(f"Checking installed status in database '{args.database}'...")
|
|
installed_modules = get_installed_modules(modules, args.database, db_params)
|
|
|
|
if not installed_modules:
|
|
print("None of the local modules are installed in the specified database.")
|
|
sys.exit(0)
|
|
|
|
print(f"Found {len(installed_modules)} installed modules to upgrade.")
|
|
|
|
# Construct the Odoo command
|
|
modules_str = ','.join(installed_modules)
|
|
|
|
# Check if odoo-bin exists
|
|
if not os.path.exists(args.odoo_bin) and not os.path.exists(os.path.abspath(args.odoo_bin)):
|
|
print(f"Error: odoo-bin not found at {args.odoo_bin}")
|
|
sys.exit(1)
|
|
|
|
cmd = [
|
|
sys.executable,
|
|
args.odoo_bin,
|
|
'-c', args.config,
|
|
'-d', args.database,
|
|
'-u', modules_str,
|
|
'--stop-after-init'
|
|
]
|
|
|
|
print("--------------------------------------------------")
|
|
print(f"Starting upgrade for database '{args.database}'...")
|
|
print(f"Modules to upgrade: {modules_str}")
|
|
print(f"Command: {' '.join(cmd)}")
|
|
print("--------------------------------------------------")
|
|
|
|
try:
|
|
subprocess.run(cmd, check=True)
|
|
print("--------------------------------------------------")
|
|
print("Upgrade completed successfully.")
|
|
except subprocess.CalledProcessError as e:
|
|
print("--------------------------------------------------")
|
|
print(f"Error: Upgrade failed with exit code {e.returncode}")
|
|
sys.exit(e.returncode)
|
|
except Exception as e:
|
|
print(f"An unexpected error occurred: {e}")
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|