update
This commit is contained in:
parent
dbd5a8325c
commit
ffc7cef059
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,7 +6,7 @@ __pycache__/
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
config/*.yaml
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
|
22
cli.py
22
cli.py
@ -3,6 +3,7 @@ import argparse
|
||||
import tqdm
|
||||
from services.odoo.service import OdooServiceManager
|
||||
from services.odoo.module import OdooModuleManager
|
||||
import lib.color_log as color_log
|
||||
|
||||
|
||||
def service(args):
|
||||
@ -15,7 +16,10 @@ def service(args):
|
||||
case "restart":
|
||||
service.restart_service(args.instance)
|
||||
case _:
|
||||
print("Invalid action")
|
||||
color_log.Show(
|
||||
"FAILED",
|
||||
f"Invalid action '{args.action}' for service management.",
|
||||
)
|
||||
|
||||
|
||||
def module(args):
|
||||
@ -23,12 +27,17 @@ def module(args):
|
||||
|
||||
# If modules are provided in the command line
|
||||
if args.modules:
|
||||
print(f"Processing modules: {', '.join(args.modules)} for {args.instance}")
|
||||
color_log.Show(
|
||||
"INFO",
|
||||
f"Processing modules: {', '.join(args.modules)} for {args.instance}",
|
||||
)
|
||||
else:
|
||||
# Fallback if no modules are provided (can use default from instance settings)
|
||||
print(f"No modules specified. Using default modules for {args.instance}")
|
||||
color_log.Show(
|
||||
"INFO",
|
||||
f"No modules specified. Using default modules for {args.instance}",
|
||||
)
|
||||
args.modules = module_manager.get_modules(args.instance)
|
||||
|
||||
# Create a progress bar using tqdm
|
||||
for module_name in tqdm.tqdm(
|
||||
args.modules, desc="Processing modules", unit="module"
|
||||
@ -41,7 +50,10 @@ def module(args):
|
||||
case "upgrade":
|
||||
module_manager.upgrade(args.instance, [module_name])
|
||||
case _:
|
||||
print("Invalid action")
|
||||
color_log.Show(
|
||||
"FAILED",
|
||||
f"Invalid action '{args.action}' for module management.",
|
||||
)
|
||||
|
||||
|
||||
def setup_cli():
|
||||
|
54
config/settings.template
Normal file
54
config/settings.template
Normal file
@ -0,0 +1,54 @@
|
||||
odoo_instances:
|
||||
- name: "ftacpa"
|
||||
host: "10.1.1.31"
|
||||
port: 8069
|
||||
database: "ftacpa"
|
||||
username: "nextzen"
|
||||
password: "smartyourlife"
|
||||
type: "systemctl"
|
||||
service_name: "odoo18"
|
||||
git:
|
||||
repo_url: "https://hoangvv:smartyourlife@git.nextzenos.com/NextERP/Odoo18-FTACPA.git"
|
||||
branch: "community/demo/ftacpa"
|
||||
local_path: "/opt/odoo18/addons"
|
||||
ssh:
|
||||
user: root
|
||||
password: Smartyourlife123@*
|
||||
key_path: "/root/.ssh/privatessh.key"
|
||||
odoo_instances:
|
||||
- name: "ftacpa"
|
||||
host: "10.1.1.31"
|
||||
port: 8069
|
||||
database: "server"
|
||||
username: "nextzen"
|
||||
password: "smartyourlife"
|
||||
type: "systemctl"
|
||||
service_name: "odoo18"
|
||||
git:
|
||||
repo_url: "https://hoangvv:smartyourlife@git.nextzenos.com/NextERP/Odoo18-FTACPA.git"
|
||||
branch: "community/demo/ftacpa"
|
||||
local_path: "/opt/ftacpa/addons"
|
||||
ssh:
|
||||
user: root
|
||||
password: Smartyourlife123@*
|
||||
key_path: "/root/.ssh/privatessh.key"
|
||||
# - name: "server1_test"
|
||||
# host: "server1.example.com"
|
||||
# port: 8069
|
||||
# database: "test_db1"
|
||||
# username: "admin"
|
||||
# password: "test_password"
|
||||
# module_names:
|
||||
# - "your_module"
|
||||
# type: "docker"
|
||||
# - name: "server2_prod"
|
||||
# host: "server2.example.com"
|
||||
# port: 8070
|
||||
# database: "prod_db2"
|
||||
# username: "admin"
|
||||
# password: "admin_password"
|
||||
# module_names:
|
||||
# - "your_module"
|
||||
# - "custom_module"
|
||||
# - "third_module"
|
||||
# type: "systemctl"
|
@ -9,16 +9,16 @@ def colorize(text, code):
|
||||
def Show(status, message):
|
||||
"""Displays a message with a status indicator."""
|
||||
colors = {
|
||||
0: (
|
||||
'OK': (
|
||||
colorize("[", "90") + colorize(" OK ", "38;5;154") + colorize("]", "90")
|
||||
), # Green, Grey
|
||||
1: (
|
||||
'FAILED': (
|
||||
colorize("[", "90") + colorize(" FAILED ", "91") + colorize("]", "90")
|
||||
), # Red, Grey
|
||||
2: (
|
||||
'INFO': (
|
||||
colorize("[", "90") + colorize(" INFO ", "38;5;154") + colorize("]", "90")
|
||||
), # Green, Grey
|
||||
3: (
|
||||
'WARNING': (
|
||||
colorize("[", "90") + colorize(" WARNING ", "33") + colorize("]", "90")
|
||||
), # Yellow, Grey
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ from odoorpc import ODOO
|
||||
import os
|
||||
import sys
|
||||
from services.config import Config
|
||||
import lib.color_log as color_log
|
||||
|
||||
|
||||
class OdooConnection:
|
||||
@ -48,11 +49,15 @@ class OdooConnection:
|
||||
instance["database"], instance["username"], instance["password"]
|
||||
)
|
||||
self.connections[instance["name"]] = odoo
|
||||
print(
|
||||
f"Connected to {instance['host']}:{instance['port']} - {instance['database']}"
|
||||
color_log.Show(
|
||||
"OK",
|
||||
f"Connected to {instance['name']} at {instance['host']}:{instance['port']}",
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Failed to connect to {instance['name']}: {e}")
|
||||
color_log.Show(
|
||||
"FAILED",
|
||||
f"Failed to connect to {instance['name']} at {instance['host']}:{instance['port']}: {e}",
|
||||
)
|
||||
raise
|
||||
|
||||
def get_connection(self, instance_name):
|
||||
@ -69,7 +74,7 @@ class OdooConnection:
|
||||
if name in self.connections:
|
||||
# odoorpc doesn't have an explicit disconnect, so we just remove the reference
|
||||
del self.connections[name]
|
||||
print(f"Disconnected from instance: {name}")
|
||||
color_log.Show("OK", f"Disconnected from {name}")
|
||||
|
||||
def get_instances(self):
|
||||
"""Return the list of configured instances."""
|
||||
@ -80,11 +85,13 @@ class OdooConnection:
|
||||
odoo = self.get_connection(instance_name)
|
||||
if not odoo:
|
||||
raise ValueError(f"No connection available for instance '{instance_name}'")
|
||||
|
||||
try:
|
||||
model_obj = odoo.env[model]
|
||||
result = getattr(model_obj, method)(*args, **kwargs)
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"Error executing {method} on {model} for {instance_name}: {e}")
|
||||
color_log.Show(
|
||||
"FAILED",
|
||||
f"Error executing {method} on {model} for {instance_name}: {e}",
|
||||
)
|
||||
raise
|
||||
|
@ -1,6 +1,7 @@
|
||||
from services.git.handler import GitHandler
|
||||
from services.odoo.connection import OdooConnection
|
||||
import subprocess
|
||||
import lib.color_log as color_log
|
||||
|
||||
|
||||
class OdooModuleManager:
|
||||
@ -19,14 +20,13 @@ class OdooModuleManager:
|
||||
for instance in self.config.get_instances():
|
||||
if instance_name and instance["name"] != instance_name:
|
||||
continue
|
||||
|
||||
print(f"Processing instance: {instance['name']}")
|
||||
color_log.Show("INFO", f"Processing instance: {instance['name']}")
|
||||
for module_name in module_names:
|
||||
try:
|
||||
print(
|
||||
f"{action.capitalize()}ing module: {module_name} in {instance['name']}"
|
||||
color_log.Show(
|
||||
"INFO",
|
||||
f"{action.capitalize()}ing module: {module_name} in {instance['name']}",
|
||||
)
|
||||
|
||||
module_ids = self.config.execute(
|
||||
instance["name"],
|
||||
"ir.module.module",
|
||||
@ -34,9 +34,10 @@ class OdooModuleManager:
|
||||
[("name", "=", module_name)],
|
||||
)
|
||||
|
||||
if not module_ids:
|
||||
print(
|
||||
f"Module {module_name} not found in {instance['name']}, skipping."
|
||||
if not module_ids and action in ["upgrade", "uninstall"]:
|
||||
color_log.Show(
|
||||
"WARNING",
|
||||
f"Module {module_name} not found in {instance['name']}, skipping.",
|
||||
)
|
||||
continue
|
||||
|
||||
@ -47,23 +48,41 @@ class OdooModuleManager:
|
||||
button_action,
|
||||
module_ids, # Pass list directly instead of wrapping in another list
|
||||
)
|
||||
|
||||
print(
|
||||
f"Module {module_name} {action}ed successfully in {instance['name']}"
|
||||
color_log.Show(
|
||||
"OK",
|
||||
f"Module {module_name} {action}ed successfully in {instance['name']}",
|
||||
)
|
||||
except Exception as e:
|
||||
print(
|
||||
f"Error while {action}ing {module_name} in {instance['name']}: {e}"
|
||||
color_log.Show(
|
||||
"FAILED",
|
||||
f"Error while {action}ing {module_name} in {instance['name']}: {e}",
|
||||
)
|
||||
|
||||
def install(self, instance_name: str = None,module_names: list = None) -> None:
|
||||
def get_modules(self, instance_name: str = None) -> list:
|
||||
"""Get a list of installed modules for the specified instance(s)."""
|
||||
self.config.connect(instance_name)
|
||||
modules = []
|
||||
for instance in self.config.get_instances():
|
||||
if instance_name and instance["name"] != instance_name:
|
||||
continue
|
||||
color_log.Show("INFO", f"Fetching modules for instance: {instance['name']}")
|
||||
module_ids = self.config.execute(
|
||||
instance["name"],
|
||||
"ir.module.module",
|
||||
"search_read",
|
||||
[],
|
||||
["name"],
|
||||
)
|
||||
modules.extend([mod["name"] for mod in module_ids])
|
||||
return modules
|
||||
def install(self, instance_name: str = None, module_names: list = None) -> None:
|
||||
"""Install multiple modules for the specified instance(s)."""
|
||||
self._manage_module("install", instance_name,module_names)
|
||||
self._manage_module("install", instance_name, module_names)
|
||||
|
||||
def uninstall(self, instance_name: str = None,module_names: list = None) -> None:
|
||||
def uninstall(self, instance_name: str = None, module_names: list = None) -> None:
|
||||
"""Uninstall multiple modules for the specified instance(s)."""
|
||||
self._manage_module("uninstall", instance_name,module_names)
|
||||
self._manage_module("uninstall", instance_name, module_names)
|
||||
|
||||
def upgrade(self, instance_name: str = None,module_names: list = None) -> None:
|
||||
def upgrade(self, instance_name: str = None, module_names: list = None) -> None:
|
||||
"""Upgrade multiple modules for the specified instance(s)."""
|
||||
self._manage_module("upgrade", instance_name,module_names)
|
||||
self._manage_module("upgrade", instance_name, module_names)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import subprocess
|
||||
from services.odoo.connection import OdooConnection
|
||||
import lib.color_log as color_log
|
||||
|
||||
|
||||
class OdooServiceManager:
|
||||
@ -9,11 +10,15 @@ class OdooServiceManager:
|
||||
def _execute_command(self, cmd, instance_name):
|
||||
"""Execute a shell command and handle errors."""
|
||||
try:
|
||||
print(f"Executing: {cmd}")
|
||||
color_log.Show("INFO", f"Executing command: {cmd}")
|
||||
subprocess.run(cmd, shell=True, check=True, capture_output=True, text=True)
|
||||
print(f"Service operation successful for {instance_name}")
|
||||
color_log.Show("OK", f"Command executed successfully for {instance_name}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error performing service operation for {instance_name}: {e}")
|
||||
color_log.Show(
|
||||
"FAILED",
|
||||
f"Error performing service operation for {instance_name}: {e}",
|
||||
)
|
||||
|
||||
raise
|
||||
|
||||
def _get_command(self, instance, action):
|
||||
@ -35,7 +40,10 @@ class OdooServiceManager:
|
||||
container_name = instance.get("container_name", f"odoo_{instance['name']}")
|
||||
cmd = f"docker {action} {container_name}"
|
||||
else:
|
||||
print(f"Unsupported service type '{service_type}' for {instance['name']}")
|
||||
color_log.Show(
|
||||
"WARNING",
|
||||
f"Unsupported service type '{service_type}' for {instance['name']}",
|
||||
)
|
||||
return None
|
||||
|
||||
if not local_host:
|
||||
@ -52,14 +60,16 @@ class OdooServiceManager:
|
||||
:param action: "stop" or "restart"
|
||||
:param instance_name: Specific instance name, or None for all instances.
|
||||
"""
|
||||
if action not in ["stop", "restart","start"]:
|
||||
if action not in ["stop", "restart", "start"]:
|
||||
raise ValueError("Action must be 'stop' or 'restart'.")
|
||||
|
||||
for instance in self.config.get_instances():
|
||||
if instance_name and instance["name"] != instance_name:
|
||||
continue
|
||||
|
||||
print(f"{action.capitalize()}ing service for instance: {instance['name']}")
|
||||
color_log.Show(
|
||||
"INFO",
|
||||
f"{action.capitalize()}ing service for instance: {instance['name']}",
|
||||
)
|
||||
cmd = self._get_command(instance, action)
|
||||
if cmd:
|
||||
self._execute_command(cmd, instance["name"])
|
||||
|
Loading…
Reference in New Issue
Block a user