update
This commit is contained in:
parent
422b142d90
commit
b29630e1b6
7
main.py
7
main.py
@ -2,19 +2,18 @@
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
from services.odoo.manager import OdooModuleManager
|
||||
from services.odoo.service import OdooServiceManager
|
||||
|
||||
|
||||
def main():
|
||||
print(os.getcwd())
|
||||
manager = OdooModuleManager(config_path="utility/config/settings.yaml")
|
||||
service = OdooServiceManager(config_path="utility/config/settings.yaml")
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Restart Odoo Service",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
parser.add_argument("instance", help="Instance name")
|
||||
args = parser.parse_args()
|
||||
manager.restart_service(args.instance)
|
||||
service.restart_service(args.instance)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
|
101
scripts/clean_up_addons.sh
Normal file
101
scripts/clean_up_addons.sh
Normal file
@ -0,0 +1,101 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if at least one root folder is provided as an argument
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <root_folder> [<root_folder>...]"
|
||||
echo "Please provide at least one root folder path."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Define the protected items list file
|
||||
PROTECTED_LIST="protected.txt"
|
||||
if [ ! -f "$PROTECTED_LIST" ]; then
|
||||
echo "Error: '$PROTECTED_LIST' not found."
|
||||
echo "Please create 'protected.txt' one directory up with a list of protected files/folders (one per line)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Safeguard: Check if any file/folder matching patterns in protected.txt exists in a root folder
|
||||
check_protected_items() {
|
||||
local root_dir="$1"
|
||||
while IFS= read -r pattern; do
|
||||
# Skip empty lines
|
||||
[ -z "$pattern" ] && continue
|
||||
|
||||
# Handle wildcards by using find for pattern matching
|
||||
if [[ "$pattern" == *"*"* ]]; then
|
||||
# Convert pattern to a find-compatible search
|
||||
if [[ "$pattern" == /* ]]; then
|
||||
search_path="${root_dir}${pattern}"
|
||||
else
|
||||
search_path="${root_dir}/${pattern}"
|
||||
fi
|
||||
|
||||
# Use find to check if any files match the pattern
|
||||
if find "$root_dir" -path "$search_path" 2>/dev/null | grep -q .; then
|
||||
echo "Error: Protected pattern '$pattern' matches files in '$root_dir'. Aborting execution."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Exact match for non-wildcard entries
|
||||
if [ -e "$root_dir/$pattern" ]; then
|
||||
echo "Error: Protected item '$pattern' found in '$root_dir'. Aborting execution."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done < "$PROTECTED_LIST"
|
||||
}
|
||||
|
||||
# Function to check and delete subfolders
|
||||
delete_non_manifest_folders() {
|
||||
local dir="$1"
|
||||
|
||||
# Loop through all immediate subdirectories in the given directory
|
||||
for subfolder in "$dir"/*/ ; do
|
||||
# Check if it's a directory
|
||||
if [ -d "$subfolder" ]; then
|
||||
# Check if __manifest__.py exists in this subfolder
|
||||
if [ ! -f "$subfolder/__manifest__.py" ]; then
|
||||
echo "Deleting '$subfolder' (no __manifest__.py found)"
|
||||
rm -rf "$subfolder"
|
||||
else
|
||||
echo "Keeping '$subfolder' (__manifest__.py found)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Process each root folder provided as an argument
|
||||
for ROOT_FOLDER in "$@"; do
|
||||
# Check if the root folder exists and is a directory
|
||||
if [ ! -d "$ROOT_FOLDER" ]; then
|
||||
echo "Error: '$ROOT_FOLDER' is not a valid directory. Skipping."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Perform the safeguard check for this root folder
|
||||
echo "Checking for protected items in '$ROOT_FOLDER' from '$PROTECTED_LIST'..."
|
||||
check_protected_items "$ROOT_FOLDER"
|
||||
|
||||
# Change to the root folder to handle relative paths cleanly
|
||||
cd "$ROOT_FOLDER" || {
|
||||
echo "Error: Could not change to directory '$ROOT_FOLDER'. Skipping."
|
||||
continue
|
||||
}
|
||||
|
||||
# Call the function with the current root folder
|
||||
echo "Processing '$ROOT_FOLDER'..."
|
||||
delete_non_manifest_folders "."
|
||||
|
||||
# Return to the original directory to process the next root folder
|
||||
cd - > /dev/null || {
|
||||
echo "Error: Could not return from '$ROOT_FOLDER'. Exiting."
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "Cleanup complete for '$ROOT_FOLDER'!"
|
||||
done
|
||||
|
||||
echo "All root folders processed!"
|
||||
|
||||
exit 0
|
10
scripts/dir2file.sh
Normal file
10
scripts/dir2file.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define output file name
|
||||
input_dir="$1"
|
||||
output_file="$2"
|
||||
# Find all directories in root and write to file
|
||||
# Using find to list only directories (-type d) at depth 1 (-maxdepth 1)
|
||||
find $input_dir -maxdepth 1 -type d -not -path "$input_dir" -exec basename {} \; | sort >> "$output_file"
|
||||
|
||||
echo "Folder list has been written to $output_file"
|
93
scripts/gen_config_docker.py
Normal file
93
scripts/gen_config_docker.py
Normal file
@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import configparser
|
||||
import shutil
|
||||
import os
|
||||
from dotenv import set_key
|
||||
from pathlib import Path
|
||||
import socket
|
||||
import secrets
|
||||
import string
|
||||
import color_log
|
||||
def generate_password(length=16):
|
||||
"""Generates a random password of specified length."""
|
||||
alphabet = string.ascii_letters + string.digits
|
||||
return ''.join(secrets.choice(alphabet) for _ in range(length))
|
||||
|
||||
def find_available_port(start_port=80):
|
||||
"""Finds an available port starting from the given port."""
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
while True:
|
||||
try:
|
||||
sock.bind(('0.0.0.0', start_port))
|
||||
color_log.Show(3,f" {start_port} is Open")
|
||||
return start_port
|
||||
except OSError as e:
|
||||
if e.errno == 98: # Address already in use
|
||||
print(f"{start_port} already in use , Try other port ...")
|
||||
start_port += 1
|
||||
else:
|
||||
raise
|
||||
|
||||
def main():
|
||||
"""
|
||||
Generates a random password and finds an available port.
|
||||
Updates the Odoo configuration file and .env file with these values.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description="Generate Odoo configuration")
|
||||
parser.add_argument('--db_port', type=int, help='')
|
||||
parser.add_argument('--db_user', type=str, help='')
|
||||
parser.add_argument('--deploy_path', type=str, help='')
|
||||
parser.add_argument('--image', type=str, help='')
|
||||
parser.add_argument('--tag', type=str, help='')
|
||||
parser.add_argument('--addons', type=str, help='')
|
||||
parser.add_argument('--config', type=str, help='')
|
||||
parser.add_argument('--container', type=str, help='')
|
||||
parser.add_argument('--backup', type=str, help='')
|
||||
args = parser.parse_args()
|
||||
db_port = args.db_port
|
||||
db_pass = "smartyourlife"
|
||||
db_user = args.db_user
|
||||
base_dir= args.deploy_path
|
||||
image=args.image
|
||||
tag=args.tag
|
||||
container=args.container
|
||||
addons=args.addons
|
||||
config_path=args.config
|
||||
app_port = 10017
|
||||
backup = args.backup
|
||||
# Copy template files
|
||||
os.makedirs(f"{base_dir}/etc", exist_ok=True)
|
||||
color_log.Show(3,f"Copy {base_dir}/odoo.conf.template to {base_dir}/etc/odoo.conf")
|
||||
shutil.copyfile(f'{base_dir}/odoo.conf.template', f'{base_dir}/etc/odoo.conf')
|
||||
shutil.copyfile(f'{base_dir}/env.template', f'{base_dir}/.env')
|
||||
|
||||
# Update Odoo configuration file
|
||||
config = configparser.ConfigParser()
|
||||
config.read(f'{base_dir}/etc/odoo.conf')
|
||||
config['options']['db_host'] = "db"
|
||||
config['options']['db_user'] = db_user
|
||||
config['options']['db_password'] = db_pass
|
||||
config['options']['db_port'] = str(db_port)
|
||||
config['options']['addons_path'] = "/mnt/extra-addons"
|
||||
config['options']['data_dir'] = "/var/lib/odoo"
|
||||
config['options']['proxy_mode'] = "True"
|
||||
with open(f'{base_dir}/etc/odoo.conf', 'w') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
# Update .env file
|
||||
env_file_path = Path("deployment/.env")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="COMPOSE_PROJECT_NAME", value_to_set=f"odoo-{tag}",quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="PG_PORT", value_to_set=find_available_port(int(os.getenv('DB_PORT','5432'))+1),quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="PG_USER", value_to_set=db_user,quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="PG_PASS", value_to_set=db_pass,quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="ODOO_CONFIG", value_to_set=config_path,quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="ODOO_ADDONS", value_to_set=addons,quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="ODOO_PORT", value_to_set=find_available_port(app_port),quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="ODOO_IMAGE", value_to_set=image.lower(),quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="ODOO_TAG", value_to_set=tag,quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="ODOO_CONTAINER", value_to_set=container.lower(),quote_mode="never")
|
||||
set_key(dotenv_path=env_file_path, key_to_set="ODOO_BACKUP", value_to_set=backup,quote_mode="never")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
245
scripts/init_config.sh
Normal file
245
scripts/init_config.sh
Normal file
@ -0,0 +1,245 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
export PATH=/usr/sbin:$PATH
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
set -euo pipefail
|
||||
DEPLOY_PATH=$(pwd)/deployment
|
||||
SETUP_PATH=$(pwd)/setup
|
||||
PIP=$(pwd)/venv/bin/pip
|
||||
PYTHON=$(pwd)/venv/bin/python
|
||||
ODOO_ADDONS=${DEPLOY_PATH}/addons
|
||||
ODOO_CONFIG=${DEPLOY_PATH}/etc
|
||||
ODOO_BACKUP=${DEPLOY_PATH}/backup
|
||||
# System
|
||||
DEPENDS_PACKAGE=('wget' 'curl' 'git' 'unzip' 'make' 'wkhtmltopdf' 'postgresql-client')
|
||||
DEPENDS_COMMAND=('wget' 'curl' 'git' 'unzip' 'make' 'wkhtmltopdf' 'psql')
|
||||
((EUID)) && sudo_cmd="sudo" || sudo_cmd=""
|
||||
readonly MINIMUM_DOCER_VERSION="20"
|
||||
UNAME_U="$(uname -s)"
|
||||
readonly UNAME_U
|
||||
readonly COLOUR_RESET='\e[0m'
|
||||
readonly aCOLOUR=(
|
||||
'\e[38;5;154m' # green | Lines, bullets and separators
|
||||
'\e[1m' # Bold white | Main descriptions
|
||||
'\e[90m' # Grey | Credits
|
||||
'\e[91m' # Red | Update notifications Alert
|
||||
'\e[33m' # Yellow | Emphasis
|
||||
)
|
||||
trap 'onCtrlC' INT
|
||||
onCtrlC() {
|
||||
echo -e "${COLOUR_RESET}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Show() {
|
||||
# OK
|
||||
if (($1 == 0)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} OK $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# FAILED
|
||||
elif (($1 == 1)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[3]}FAILED$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
exit 1
|
||||
# INFO
|
||||
elif (($1 == 2)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} INFO $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# NOTICE
|
||||
elif (($1 == 3)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[4]}NOTICE$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
fi
|
||||
}
|
||||
|
||||
Warn() {
|
||||
echo -e "${aCOLOUR[3]}$1$COLOUR_RESET"
|
||||
}
|
||||
|
||||
GreyStart() {
|
||||
echo -e "${aCOLOUR[2]}\c"
|
||||
}
|
||||
|
||||
ColorReset() {
|
||||
echo -e "$COLOUR_RESET\c"
|
||||
}
|
||||
|
||||
|
||||
Update_Package_Resource() {
|
||||
GreyStart
|
||||
if [ -x "$(command -v apk)" ]; then
|
||||
${sudo_cmd} apk update
|
||||
elif [ -x "$(command -v apt)" ]; then
|
||||
${sudo_cmd} apt update
|
||||
elif [ -x "$(command -v dnf)" ]; then
|
||||
${sudo_cmd} dnf check-update
|
||||
elif [ -x "$(command -v zypper)" ]; then
|
||||
${sudo_cmd} zypper update
|
||||
elif [ -x "$(command -v yum)" ]; then
|
||||
${sudo_cmd} yum update
|
||||
fi
|
||||
ColorReset
|
||||
}
|
||||
# 3 Check OS
|
||||
Check_OS() {
|
||||
if [[ $UNAME_U == *Linux* ]]; then
|
||||
Show 0 "Your System is : $UNAME_U"
|
||||
else
|
||||
Show 1 "This script is only for Linux."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
Install_Depends() {
|
||||
for ((i = 0; i < ${#DEPENDS_COMMAND[@]}; i++)); do
|
||||
cmd=${DEPENDS_COMMAND[i]}
|
||||
if [[ ! -x $(${sudo_cmd} which "$cmd") ]]; then
|
||||
packagesNeeded=${DEPENDS_PACKAGE[i]}
|
||||
Show 2 "Install the necessary dependencies: \e[33m$packagesNeeded \e[0m"
|
||||
GreyStart
|
||||
if [ -x "$(command -v apk)" ]; then
|
||||
${sudo_cmd} apk add --no-cache "$packagesNeeded"
|
||||
elif [ -x "$(command -v apt-get)" ]; then
|
||||
${sudo_cmd} apt-get -y -q install "$packagesNeeded" --no-upgrade
|
||||
elif [ -x "$(command -v dnf)" ]; then
|
||||
${sudo_cmd} dnf install "$packagesNeeded"
|
||||
elif [ -x "$(command -v zypper)" ]; then
|
||||
${sudo_cmd} zypper install "$packagesNeeded"
|
||||
elif [ -x "$(command -v yum)" ]; then
|
||||
${sudo_cmd} yum install "$packagesNeeded"
|
||||
elif [ -x "$(command -v pacman)" ]; then
|
||||
${sudo_cmd} pacman -S "$packagesNeeded"
|
||||
elif [ -x "$(command -v paru)" ]; then
|
||||
${sudo_cmd} paru -S "$packagesNeeded"
|
||||
else
|
||||
Show 1 "Package manager not found. You must manually install: \e[33m$packagesNeeded \e[0m"
|
||||
fi
|
||||
ColorReset
|
||||
else
|
||||
Show 2 "\e[33m ${DEPENDS_COMMAND[i]}\e[0m Installed"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
Check_Dependency_Installation() {
|
||||
for ((i = 0; i < ${#DEPENDS_COMMAND[@]}; i++)); do
|
||||
cmd=${DEPENDS_COMMAND[i]}
|
||||
if [[ ! -x $(${sudo_cmd} which "$cmd") ]]; then
|
||||
packagesNeeded=${DEPENDS_PACKAGE[i]}
|
||||
Show 1 "Dependency \e[33m$packagesNeeded \e[0m installation failed, please try again manually!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
Check_Docker_Install() {
|
||||
if [[ -x "$(command -v docker)" ]]; then
|
||||
Docker_Version=$(${sudo_cmd} docker version --format '{{.Server.Version}}')
|
||||
if [[ $? -ne 0 ]]; then
|
||||
Install_Docker
|
||||
elif [[ ${Docker_Version:0:2} -lt "${MINIMUM_DOCER_VERSION}" ]]; then
|
||||
Show 1 "Recommended minimum Docker version is \e[33m${MINIMUM_DOCER_VERSION}.xx.xx\e[0m,\Current Docker verison is \e[33m${Docker_Version}\e[0m,\nPlease uninstall current Docker and rerun the CasaOS installation script."
|
||||
exit 1
|
||||
else
|
||||
Show 0 "Current Docker verison is ${Docker_Version}."
|
||||
fi
|
||||
else
|
||||
Install_Docker
|
||||
fi
|
||||
}
|
||||
Install_Docker() {
|
||||
Show 2 "Install the necessary dependencies: \e[33mDocker \e[0m"
|
||||
if [[ ! -d "${PREFIX}/etc/apt/sources.list.d" ]]; then
|
||||
${sudo_cmd} mkdir -p "${PREFIX}/etc/apt/sources.list.d"
|
||||
fi
|
||||
GreyStart
|
||||
if [[ "${REGION}" = "CN" ]]; then
|
||||
${sudo_cmd} curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
|
||||
else
|
||||
${sudo_cmd} curl -fsSL https://get.docker.com | bash
|
||||
fi
|
||||
ColorReset
|
||||
if [[ $? -ne 0 ]]; then
|
||||
Show 1 "Installation failed, please try again."
|
||||
exit 1
|
||||
else
|
||||
Check_Docker_Install_Final
|
||||
fi
|
||||
}
|
||||
Check_Docker_Install_Final() {
|
||||
if [[ -x "$(command -v docker)" ]]; then
|
||||
Docker_Version=$(${sudo_cmd} docker version --format '{{.Server.Version}}')
|
||||
if [[ $? -ne 0 ]]; then
|
||||
Install_Docker
|
||||
elif [[ ${Docker_Version:0:2} -lt "${MINIMUM_DOCER_VERSION}" ]]; then
|
||||
Show 1 "Recommended minimum Docker version is \e[33m${MINIMUM_DOCER_VERSION}.xx.xx\e[0m,\Current Docker verison is \e[33m${Docker_Version}\e[0m,\nPlease uninstall current Docker and rerun the CasaOS installation script."
|
||||
exit 1
|
||||
else
|
||||
Show 0 "Current Docker verison is ${Docker_Version}."
|
||||
Check_Docker_Running
|
||||
fi
|
||||
else
|
||||
Show 1 "Installation failed, please run 'curl -fsSL https://get.docker.com | bash' and rerun the CasaOS installation script."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
Generate_Config_Docker(){
|
||||
ODOO_IMAGE=${1:-}
|
||||
ODOO_TAG=${2:-}
|
||||
ODOO_CONTAINER=${3:-}
|
||||
if [[ ! -f "${DEPLOY_PATH}/.env" ]]; then
|
||||
cp "${DEPLOY_PATH}/env.template" "${DEPLOY_PATH}/.env"
|
||||
fi
|
||||
USER="${REPO_NAME:-"default_repo"}"
|
||||
# Convert to lowercase
|
||||
USER="${USER,,}"
|
||||
${PYTHON} "$SETUP_PATH/gen_config_docker.py" --db_port 5432 --db_user $USER --deploy_path "$DEPLOY_PATH" \
|
||||
--image "${ODOO_IMAGE}" --container "${ODOO_CONTAINER}" --tag "${ODOO_TAG:=latest}" \
|
||||
--addons "${ODOO_ADDONS}" --config "${ODOO_CONFIG}" --backup "${ODOO_BACKUP}"
|
||||
Show 0 " Generate Config Complete"
|
||||
}
|
||||
Generate_Config_Native(){
|
||||
DB_USER=${2:-}
|
||||
DB_PASSWORD=${3:-}
|
||||
DB_SERVER=${4:-}
|
||||
DB_PORT=${5:-}
|
||||
ADDONS=${1:-}
|
||||
REPO_NAME=$(basename "$(git rev-parse --show-toplevel)" | sed -E 's/[.-]/_/g')
|
||||
USER="${REPO_NAME:-"default_repo"}"
|
||||
# Convert to lowercase
|
||||
USER="${USER,,}"
|
||||
PASSWORD="$(openssl rand -hex 24)"
|
||||
# Check if the user already exists
|
||||
USER_EXISTS=$(psql "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_SERVER}:${DB_PORT}/postgres" -t -A -c "SELECT COUNT(*) FROM pg_roles WHERE rolname='$USER';")
|
||||
|
||||
if [ $USER_EXISTS -eq 0 ]; then
|
||||
# User does not exist, create the user
|
||||
Show 2 "Create the new PostgreSQL username: $USER with password: $PASSWORD"
|
||||
psql "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_SERVER}:${DB_PORT}/postgres" -c "CREATE USER $USER WITH PASSWORD '$PASSWORD';"
|
||||
Show 2 "Grant $USER superuser (admin) privileges"
|
||||
psql "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_SERVER}:${DB_PORT}/postgres" -c "ALTER USER $USER WITH SUPERUSER;"
|
||||
else
|
||||
# User exists, update the password (do not try to create)
|
||||
Show 2 "User $USER already exists, updating password to $PASSWORD"
|
||||
psql "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_SERVER}:${DB_PORT}/postgres" -c "ALTER USER $USER WITH PASSWORD '$PASSWORD';"
|
||||
fi
|
||||
${PYTHON} "$SETUP_PATH/gen_config.py" --db_user $USER --db_pass $PASSWORD --deploy_path "$(pwd)" \
|
||||
--addons_path $ADDONS --db_port $DB_PORT --db_server $DB_SERVER
|
||||
Show 0 " Generate Config Complete"
|
||||
}
|
||||
main(){
|
||||
TYPE=${1:-}
|
||||
Check_OS
|
||||
# Update_Package_Resource
|
||||
# Install_Depends
|
||||
# Check_Dependency_Installation
|
||||
# Check_Docker_Install
|
||||
case "$TYPE" in
|
||||
--native)
|
||||
Generate_Config_Native $2 $3 $4 $5 $6
|
||||
;;
|
||||
--docker)
|
||||
Generate_Config_Docker $2 $3 $4
|
||||
;;
|
||||
*)
|
||||
# else
|
||||
Show 1 "Invalid argument (--docker|--native)"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
33
scripts/migrate-lang.sh
Normal file
33
scripts/migrate-lang.sh
Normal file
@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Set source and destination repositories
|
||||
SRC_REPO="/root/dev/NextERP/dev/Viindoo/odoo-18.0"
|
||||
DEST_REPO="/root/dev/NextERP/dev/odoo18/Odoo18"
|
||||
LANG="vi"
|
||||
# Ensure both paths exist
|
||||
if [ ! -d "$SRC_REPO" ]; then
|
||||
echo "Error: Source repository does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$DEST_REPO" ]; then
|
||||
echo "Error: Destination repository does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find and copy vi.po files while preserving directory structure
|
||||
cd "$SRC_REPO" || exit
|
||||
find . -type f -name "${LANG}.po" | while read -r file; do
|
||||
# Get the directory path of the file
|
||||
dir_path=$(dirname "$file")
|
||||
|
||||
# Ensure the destination directory exists
|
||||
mkdir -p "$DEST_REPO/$dir_path"
|
||||
|
||||
# Copy the file
|
||||
cp "$file" "$DEST_REPO/$dir_path/"
|
||||
|
||||
echo "Copied: $file -> $DEST_REPO/$dir_path/"
|
||||
done
|
||||
|
||||
echo "All ${LANG}.po files copied successfully!"
|
82
scripts/modules_scan.sh
Normal file
82
scripts/modules_scan.sh
Normal file
@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if required arguments are provided
|
||||
if [ $# -lt 3 ] || [ $# -gt 4 ]; then
|
||||
echo "Usage: $0 <input_file> <root_folder> <output_yaml_file> [list_branch]"
|
||||
echo "Example: $0 exclude_list.txt /path/to/git/repo /path/to/output.yaml 'branch1 branch2'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INPUT_FILE="$1"
|
||||
ROOT_FOLDER="$2"
|
||||
OUTPUT_FILE="$3"
|
||||
LIST_BRANCH="$4"
|
||||
|
||||
# Check if input file exists
|
||||
if [ ! -f "$INPUT_FILE" ]; then
|
||||
echo "Error: Input file '$INPUT_FILE' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if root folder exists
|
||||
if [ ! -d "$ROOT_FOLDER" ]; then
|
||||
echo "Error: Root folder '$ROOT_FOLDER' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if output YAML file exists, if not create it
|
||||
if [ ! -f "$OUTPUT_FILE" ]; then
|
||||
echo "Output file does not exist. Creating $OUTPUT_FILE"
|
||||
touch "$OUTPUT_FILE"
|
||||
fi
|
||||
|
||||
# Change to root folder
|
||||
cd "$ROOT_FOLDER" || exit 1
|
||||
|
||||
# Initialize output file
|
||||
echo "branches:" > "$OUTPUT_FILE"
|
||||
|
||||
# Get all git branches
|
||||
git fetch --all
|
||||
if [ -z "$LIST_BRANCH" ]; then
|
||||
branches=$(git branch -r | grep -v HEAD | sed 's/origin\///' | sed 's/^[[:space:]]*//')
|
||||
else
|
||||
branches=$LIST_BRANCH
|
||||
fi
|
||||
|
||||
# Process each branch
|
||||
for branch in $branches; do
|
||||
echo "Processing branch: $branch"
|
||||
|
||||
# Checkout branch
|
||||
git checkout "$branch" 2>/dev/null || continue
|
||||
|
||||
# Get all folders in current branch
|
||||
folders=$(find . -maxdepth 1 -type d -not -path '.' -not -path './.*' | sed 's|./||')
|
||||
|
||||
# Array to store modules not in input file
|
||||
modules=()
|
||||
|
||||
# Check each folder against input file
|
||||
while IFS= read -r folder; do
|
||||
# Skip if folder is empty
|
||||
[ -z "$folder" ] && continue
|
||||
|
||||
# Check if folder is in input file
|
||||
if ! grep -Fxq "$folder" "$INPUT_FILE"; then
|
||||
modules+=("$folder")
|
||||
fi
|
||||
done <<< "$folders"
|
||||
|
||||
# Write to yaml if there are modules
|
||||
if [ ${#modules[@]} -gt 0 ]; then
|
||||
echo " $branch:" >> "$OUTPUT_FILE"
|
||||
echo " modules:" >> "$OUTPUT_FILE"
|
||||
for module in "${modules[@]}"; do
|
||||
echo " - $module" >> "$OUTPUT_FILE"
|
||||
done
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
echo "Output written to $OUTPUT_FILE"
|
@ -1,7 +1,7 @@
|
||||
from odoorpc import ODOO
|
||||
import os
|
||||
import sys
|
||||
from utility.services.config import Config
|
||||
from services.config import Config
|
||||
|
||||
|
||||
class OdooConnection:
|
||||
|
0
services/odoo/database.py
Normal file
0
services/odoo/database.py
Normal file
@ -1,116 +0,0 @@
|
||||
from utility.services.git.handler import GitHandler
|
||||
from utility.services.odoo.connection import OdooConnection
|
||||
import subprocess
|
||||
|
||||
|
||||
class OdooModuleManager:
|
||||
def __init__(self, config_path="config/settings.yaml"):
|
||||
self.config = OdooConnection(config_path)
|
||||
# Use OdooConnection instead of Config directly
|
||||
self.git = GitHandler(
|
||||
repo_url=self.config.config.get("git", "repo_url"),
|
||||
local_path=self.config.config.get("git", "local_path"),
|
||||
branch=self.config.config.get("git", "branch", "main"),
|
||||
)
|
||||
|
||||
def update_and_upgrade(self, instance_name=None):
|
||||
"""Update and upgrade multiple modules for the specified instance(s)."""
|
||||
self.config.connect(instance_name) # Connect to the target instance(s)
|
||||
for instance in self.config.get_instances():
|
||||
if instance_name and instance["name"] != instance_name:
|
||||
continue
|
||||
print(f"Processing instance: {instance['name']}")
|
||||
module_names = instance.get("module_names", [])
|
||||
|
||||
if not module_names:
|
||||
print(f"No modules specified for {instance['name']}, skipping upgrade.")
|
||||
continue
|
||||
|
||||
for module_name in module_names:
|
||||
print(f"Upgrading module: {module_name} in {instance['name']}")
|
||||
try:
|
||||
# Use OdooConnection.execute to upgrade the module
|
||||
module_ids = self.config.execute(
|
||||
instance["name"],
|
||||
"ir.module.module",
|
||||
"search",
|
||||
[("name", "=", module_name), ("state", "=", "installed")],
|
||||
)
|
||||
if module_ids:
|
||||
self.config.execute(
|
||||
instance["name"],
|
||||
"ir.module.module",
|
||||
"button_upgrade",
|
||||
[module_ids],
|
||||
)
|
||||
print(
|
||||
f"Module {module_name} upgraded successfully in {instance['name']}"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"Module {module_name} not found or not installed in {instance['name']}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Failed to upgrade {module_name} in {instance['name']}: {e}")
|
||||
# Continue with other modules
|
||||
return True
|
||||
|
||||
def restart_service(self, instance_name=None):
|
||||
"""Restart the Odoo service based on the instance type using SSH with private key."""
|
||||
for instance in self.config.get_instances():
|
||||
if instance_name and instance["name"] != instance_name:
|
||||
continue
|
||||
print(f"Restarting service for instance: {instance['name']}")
|
||||
|
||||
service_type = instance.get("type", "systemctl")
|
||||
host = instance["host"]
|
||||
service_name = instance.get("service_name", f"odoo_{instance['name']}")
|
||||
|
||||
# Access ssh as a dictionary
|
||||
ssh_settings = instance.get("ssh", {})
|
||||
ssh_user = ssh_settings.get("user", "root")
|
||||
ssh_key_path = ssh_settings.get("key_path")
|
||||
# ssh_password = ssh_settings.get("password") # Not used with key
|
||||
|
||||
if service_type == "systemctl":
|
||||
if host == "localhost" or host == "127.0.0.1":
|
||||
cmd = f"sudo systemctl restart {service_name}"
|
||||
else:
|
||||
if not ssh_key_path:
|
||||
cmd = f"ssh -t {ssh_user}@{host} 'sudo systemctl restart {service_name}'"
|
||||
else:
|
||||
cmd = f"ssh -i {ssh_key_path} {ssh_user}@{host} 'sudo systemctl restart {service_name}'"
|
||||
elif service_type == "docker":
|
||||
container_name = instance.get(
|
||||
"container_name", f"odoo_{instance['name']}"
|
||||
)
|
||||
if host == "localhost" or host == "127.0.0.1":
|
||||
cmd = f"docker restart {container_name}"
|
||||
else:
|
||||
if not ssh_key_path:
|
||||
raise ValueError(
|
||||
f"SSH key path not specified for {instance['name']}"
|
||||
)
|
||||
cmd = f"ssh -i {ssh_key_path} {ssh_user}@{host} 'docker restart {container_name}'"
|
||||
else:
|
||||
print(
|
||||
f"Unsupported service type '{service_type}' for {instance['name']}"
|
||||
)
|
||||
continue
|
||||
|
||||
try:
|
||||
print(f"Executing: {cmd}")
|
||||
subprocess.run(
|
||||
cmd, shell=True, check=True, capture_output=True, text=True
|
||||
)
|
||||
print(f"Service restarted successfully for {instance['name']}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error restarting service for {instance['name']}: {e}")
|
||||
raise
|
||||
|
||||
def update_and_restart(self, instance_name=None):
|
||||
"""Combine update, upgrade, and restart."""
|
||||
updated = self.update_and_upgrade(instance_name)
|
||||
if updated:
|
||||
self.restart_service(instance_name)
|
||||
return updated
|
56
services/odoo/module.py
Normal file
56
services/odoo/module.py
Normal file
@ -0,0 +1,56 @@
|
||||
from services.git.handler import GitHandler
|
||||
from services.odoo.connection import OdooConnection
|
||||
import subprocess
|
||||
|
||||
|
||||
class OdooModuleManager:
|
||||
def __init__(self, config_path="config/settings.yaml"):
|
||||
self.config = OdooConnection(config_path)
|
||||
# Use OdooConnection instead of Config directly
|
||||
self.git = GitHandler(
|
||||
repo_url=self.config.config.get("git", "repo_url"),
|
||||
local_path=self.config.config.get("git", "local_path"),
|
||||
branch=self.config.config.get("git", "branch", "main"),
|
||||
)
|
||||
|
||||
def update_and_upgrade(self, instance_name=None):
|
||||
"""Update and upgrade multiple modules for the specified instance(s)."""
|
||||
self.config.connect(instance_name) # Connect to the target instance(s)
|
||||
for instance in self.config.get_instances():
|
||||
if instance_name and instance["name"] != instance_name:
|
||||
continue
|
||||
print(f"Processing instance: {instance['name']}")
|
||||
module_names = instance.get("module_names", [])
|
||||
|
||||
if not module_names:
|
||||
print(f"No modules specified for {instance['name']}, skipping upgrade.")
|
||||
continue
|
||||
|
||||
for module_name in module_names:
|
||||
print(f"Upgrading module: {module_name} in {instance['name']}")
|
||||
try:
|
||||
# Use OdooConnection.execute to upgrade the module
|
||||
module_ids = self.config.execute(
|
||||
instance["name"],
|
||||
"ir.module.module",
|
||||
"search",
|
||||
[("name", "=", module_name), ("state", "=", "installed")],
|
||||
)
|
||||
if module_ids:
|
||||
self.config.execute(
|
||||
instance["name"],
|
||||
"ir.module.module",
|
||||
"button_upgrade",
|
||||
[module_ids],
|
||||
)
|
||||
print(
|
||||
f"Module {module_name} upgraded successfully in {instance['name']}"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"Module {module_name} not found or not installed in {instance['name']}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Failed to upgrade {module_name} in {instance['name']}: {e}")
|
||||
# Continue with other modules
|
||||
return True
|
73
services/odoo/service.py
Normal file
73
services/odoo/service.py
Normal file
@ -0,0 +1,73 @@
|
||||
import subprocess
|
||||
from services.odoo.connection import OdooConnection
|
||||
|
||||
|
||||
class OdooServiceManager:
|
||||
def __init__(self, config_path="config/settings.yaml"):
|
||||
self.config = OdooConnection(config_path)
|
||||
|
||||
def _execute_command(self, cmd, instance_name):
|
||||
"""Execute a shell command and handle errors."""
|
||||
try:
|
||||
print(f"Executing: {cmd}")
|
||||
subprocess.run(cmd, shell=True, check=True, capture_output=True, text=True)
|
||||
print(f"Service operation successful for {instance_name}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error performing service operation for {instance_name}: {e}")
|
||||
raise
|
||||
|
||||
def _get_command(self, instance, action):
|
||||
"""
|
||||
Generate the appropriate command based on instance type and action (stop/restart).
|
||||
"""
|
||||
service_type = instance.get("type", "systemctl")
|
||||
host = instance["host"]
|
||||
service_name = instance.get("service_name", f"odoo_{instance['name']}")
|
||||
ssh_settings = instance.get("ssh", {})
|
||||
ssh_user = ssh_settings.get("user", "root")
|
||||
ssh_key_path = ssh_settings.get("key_path")
|
||||
|
||||
local_host = host in ["localhost", "127.0.0.1"]
|
||||
|
||||
if service_type == "systemctl":
|
||||
cmd = f"sudo systemctl {action} {service_name}"
|
||||
elif service_type == "docker":
|
||||
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']}")
|
||||
return None
|
||||
|
||||
if not local_host:
|
||||
if not ssh_key_path:
|
||||
cmd = f"ssh -t {ssh_user}@{host} 'sudo {cmd}'"
|
||||
else:
|
||||
cmd = f"ssh -i {ssh_key_path} {ssh_user}@{host} 'sudo {cmd}'"
|
||||
|
||||
return cmd
|
||||
|
||||
def manage_service(self, action, instance_name=None):
|
||||
"""
|
||||
Manage the Odoo service (stop or restart) for given instances.
|
||||
:param action: "stop" or "restart"
|
||||
:param instance_name: Specific instance name, or None for all instances.
|
||||
"""
|
||||
if action not in ["stop", "restart"]:
|
||||
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']}")
|
||||
cmd = self._get_command(instance, action)
|
||||
if cmd:
|
||||
self._execute_command(cmd, instance["name"])
|
||||
|
||||
def stop_service(self, instance_name=None):
|
||||
"""Stop the Odoo service based on the instance type"""
|
||||
self.manage_service("stop", instance_name)
|
||||
|
||||
def restart_service(self, instance_name=None):
|
||||
"""Restart the Odoo service based on the instance type"""
|
||||
self.manage_service("restart", instance_name)
|
Loading…
Reference in New Issue
Block a user