|
|
@@ -1,10 +1,10 @@
|
|
|
#!/bin/bash
|
|
|
################################################################################
|
|
|
-# Простая установка/обновление/удаление Odoo 19 на Debian 13
|
|
|
+# Простая установка/обновление/удаление Odoo 19 на Debian 13 (Trixie)
|
|
|
# - автоматический выбор свежего архива odoo_19.0+e.*.tar.gz
|
|
|
# - распаковка clean-enterprise-19.0.zip (если есть)
|
|
|
# - PostgreSQL 16 из официального репозитория (кластер создаётся автоматически)
|
|
|
-# - wkhtmltopdf с проверкой и установкой шрифтов для кириллицы
|
|
|
+# - wkhtmltopdf с libssl1.1 (совместимость с Trixie)
|
|
|
# - venv, systemd, конфиг в /etc/odoo/
|
|
|
#-------------------------------------------------------------------------------
|
|
|
# Сделайте скрипт исполняемым: chmod +x odoo19_install_debian13.sh
|
|
|
@@ -39,6 +39,9 @@ if [[ -n "$CUSTOM_ARCHIVE" ]]; then
|
|
|
echo "Найден архив кастомных модулей: $CUSTOM_ARCHIVE"
|
|
|
fi
|
|
|
|
|
|
+WKHTMLTOX_URL="https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb"
|
|
|
+LIBSSL_URL="http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb"
|
|
|
+
|
|
|
# ------------------------- ФУНКЦИИ -------------------------
|
|
|
log_info() { echo -e "\n[INFO] $*"; }
|
|
|
log_error() { echo -e "\n[ERROR] $*" >&2; }
|
|
|
@@ -51,44 +54,28 @@ check_root() {
|
|
|
}
|
|
|
|
|
|
generate_password() {
|
|
|
- tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 16 | head -n 1
|
|
|
+ tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 20 | head -n 1
|
|
|
}
|
|
|
|
|
|
install_wkhtmltopdf() {
|
|
|
- log_info "Установка wkhtmltopdf и шрифтов для корректной генерации PDF"
|
|
|
-
|
|
|
- # 1. Шрифты критически важны для кириллицы в отчётах Odoo
|
|
|
- apt-get install -y xfonts-base xfonts-75dpi fontconfig
|
|
|
-
|
|
|
- # Проверяем, не установлен ли уже wkhtmltopdf (на случай повторного запуска)
|
|
|
- if command -v wkhtmltopdf &>/dev/null; then
|
|
|
- log_info "wkhtmltopdf уже установлен: $(wkhtmltopdf --version)"
|
|
|
- return 0
|
|
|
- fi
|
|
|
-
|
|
|
- # 2. Скачиваем совместимый пакет от Debian 12 (Bookworm)
|
|
|
- local WKHTML_URL="https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb"
|
|
|
- log_info "Загрузка wkhtmltopdf..."
|
|
|
- wget -q -O /tmp/wkhtmltox.deb "$WKHTML_URL"
|
|
|
-
|
|
|
- # 3. Устанавливаем. apt автоматически разрешит зависимости для Debian 13
|
|
|
- if apt-get install -y /tmp/wkhtmltox.deb; then
|
|
|
- log_info "wkhtmltopdf успешно установлен: $(wkhtmltopdf --version)"
|
|
|
- rm -f /tmp/wkhtmltox.deb
|
|
|
-
|
|
|
- # Создаем симлинки на всякий случай, если Odoo ищет их в /usr/bin
|
|
|
- ln -sf /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf 2>/dev/null || true
|
|
|
- ln -sf /usr/local/bin/wkhtmltoimage /usr/bin/wkhtmltoimage 2>/dev/null || true
|
|
|
- else
|
|
|
- log_error "Не удалось установить wkhtmltopdf. Проверьте вывод apt выше."
|
|
|
- exit 1
|
|
|
- fi
|
|
|
+ log_info "Установка wkhtmltopdf"
|
|
|
+ wget -q "$LIBSSL_URL" -O /tmp/libssl1.1.deb
|
|
|
+ dpkg -i /tmp/libssl1.1.deb || apt-get install -f -y >/dev/null 2>&1
|
|
|
+ rm -f /tmp/libssl1.1.deb
|
|
|
+
|
|
|
+ wget -q "$WKHTMLTOX_URL" -O /tmp/wkhtmltox.deb
|
|
|
+ dpkg -i /tmp/wkhtmltox.deb || apt-get install -f -y >/dev/null 2>&1
|
|
|
+ rm -f /tmp/wkhtmltox.deb
|
|
|
+
|
|
|
+ ln -sf /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf
|
|
|
+ ln -sf /usr/local/bin/wkhtmltoimage /usr/bin/wkhtmltoimage
|
|
|
+ log_info "wkhtmltopdf установлен"
|
|
|
}
|
|
|
|
|
|
create_odoo_user_and_dirs() {
|
|
|
log_info "Создание пользователя $OE_USER и каталогов"
|
|
|
- # Пользователь odoo НЕ добавляется в sudo в целях безопасности
|
|
|
adduser --system --quiet --shell=/bin/bash --home=$OE_HOME --gecos 'ODOO' --group $OE_USER
|
|
|
+ adduser $OE_USER sudo
|
|
|
mkdir -p /var/log/$OE_USER
|
|
|
mkdir -p $OE_HOME_EXT
|
|
|
mkdir -p $OE_HOME/custom-addons
|
|
|
@@ -97,8 +84,8 @@ create_odoo_user_and_dirs() {
|
|
|
|
|
|
extract_odoo() {
|
|
|
log_info "Распаковка $ODOO_ARCHIVE в $OE_HOME_EXT"
|
|
|
- rm -rf "$OE_HOME_EXT"/*
|
|
|
- tar -C "$OE_HOME_EXT" -xzf "$ODOO_ARCHIVE" --strip-components=1
|
|
|
+ rm -rf $OE_HOME_EXT/*
|
|
|
+ tar -C $OE_HOME_EXT -xzf "$ODOO_ARCHIVE" --strip-components=1
|
|
|
if [[ ! -d "$OE_HOME_EXT/odoo" || ! -f "$OE_HOME_EXT/odoo/__main__.py" ]]; then
|
|
|
log_error "Структура архива неверна: нет odoo/__main__.py"
|
|
|
exit 1
|
|
|
@@ -108,11 +95,7 @@ extract_odoo() {
|
|
|
extract_custom() {
|
|
|
if [[ -n "$CUSTOM_ARCHIVE" && -f "$CUSTOM_ARCHIVE" ]]; then
|
|
|
log_info "Распаковка $CUSTOM_ARCHIVE в $OE_HOME/custom-addons"
|
|
|
- if ! unzip -qo "$CUSTOM_ARCHIVE" -d "$OE_HOME/custom-addons"; then
|
|
|
- log_error "Ошибка при распаковке $CUSTOM_ARCHIVE. Проверьте целостность архива."
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
+ unzip -qo "$CUSTOM_ARCHIVE" -d $OE_HOME/custom-addons
|
|
|
if [[ -d "$OE_HOME/custom-addons/clean-enterprise-19.0" ]]; then
|
|
|
if [[ -d "$OE_HOME/custom-addons/clean-enterprise-19.0/clean_enterprise" ]]; then
|
|
|
mv "$OE_HOME/custom-addons/clean-enterprise-19.0/clean_enterprise" "$OE_HOME/custom-addons/"
|
|
|
@@ -120,14 +103,14 @@ extract_custom() {
|
|
|
rm -rf "$OE_HOME/custom-addons/clean-enterprise-19.0"
|
|
|
fi
|
|
|
else
|
|
|
- log_info "Файл кастомных модулей не найден, пропускаем."
|
|
|
+ log_info "Файл $CUSTOM_ARCHIVE не найден, пропускаем."
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
setup_venv() {
|
|
|
log_info "Создание venv в $OE_VENV"
|
|
|
if [[ -d "$OE_VENV" ]]; then
|
|
|
- rm -rf "$OE_VENV"
|
|
|
+ rm -rf $OE_VENV
|
|
|
fi
|
|
|
su - $OE_USER -c "python3 -m venv $OE_VENV"
|
|
|
|
|
|
@@ -146,9 +129,9 @@ create_config() {
|
|
|
log_info "Создание конфига $OE_CONFIG_FILE"
|
|
|
if [[ "$GENERATE_RANDOM_PASSWORD" == "True" ]]; then
|
|
|
OE_SUPERADMIN=$(generate_password)
|
|
|
- log_info "Пароль администратора (master password): $OE_SUPERADMIN"
|
|
|
+ log_info "Пароль администратора: $OE_SUPERADMIN"
|
|
|
fi
|
|
|
- cat > "$OE_CONFIG_FILE" <<EOF
|
|
|
+ cat > $OE_CONFIG_FILE <<EOF
|
|
|
[options]
|
|
|
admin_passwd = ${OE_SUPERADMIN}
|
|
|
http_port = ${OE_PORT}
|
|
|
@@ -156,13 +139,13 @@ logfile = /var/log/${OE_USER}/${OE_SERVER}.log
|
|
|
addons_path = ${OE_HOME_EXT}/odoo/addons,${OE_HOME}/custom-addons
|
|
|
limit_time_real = 1200
|
|
|
EOF
|
|
|
- chown $OE_USER:$OE_USER "$OE_CONFIG_FILE"
|
|
|
- chmod 640 "$OE_CONFIG_FILE"
|
|
|
+ chown $OE_USER:$OE_USER $OE_CONFIG_FILE
|
|
|
+ chmod 640 $OE_CONFIG_FILE
|
|
|
}
|
|
|
|
|
|
create_service() {
|
|
|
log_info "Создание systemd сервиса"
|
|
|
- cat > "/etc/systemd/system/${OE_SERVER}.service" <<EOF
|
|
|
+ cat > /etc/systemd/system/${OE_SERVER}.service <<EOF
|
|
|
[Unit]
|
|
|
Description=Odoo $OE_VERSION Server
|
|
|
Requires=postgresql.service
|
|
|
@@ -183,42 +166,30 @@ WantedBy=multi-user.target
|
|
|
EOF
|
|
|
|
|
|
systemctl daemon-reload
|
|
|
- systemctl enable --now "${OE_SERVER}"
|
|
|
+ systemctl enable --now ${OE_SERVER}
|
|
|
sleep 3
|
|
|
}
|
|
|
|
|
|
update_databases() {
|
|
|
- log_info "Обновление модулей в базах данных Odoo"
|
|
|
- # Исправлено: убран дубликат 'template0', добавлена фильтрация по владельцу
|
|
|
- OE_DBS=$(sudo -Hiu postgres psql -tAc "SELECT datname FROM pg_database WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname='$OE_USER') AND datname NOT IN ('postgres', 'template0', 'template1');")
|
|
|
-
|
|
|
+ log_info "Обновление модулей во всех базах данных"
|
|
|
+ OE_DBS=$(sudo -Hiu postgres psql -tAc "SELECT datname FROM pg_database WHERE datname NOT IN ('postgres', 'template0', 'template1', 'template0');")
|
|
|
if [[ -n "$OE_DBS" ]]; then
|
|
|
for db in $OE_DBS; do
|
|
|
- db=$(echo "$db" | xargs)
|
|
|
- [[ -z "$db" ]] && continue
|
|
|
log_info "Обновление базы: $db"
|
|
|
su - $OE_USER -s /bin/bash -c "source $OE_VENV/bin/activate && python3 -m odoo -c $OE_CONFIG_FILE --update all --stop-after-init -d $db"
|
|
|
done
|
|
|
else
|
|
|
- log_info "Нет баз данных Odoo для обновления."
|
|
|
+ log_info "Нет баз данных для обновления."
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
# ------------------------- РЕЖИМЫ -------------------------
|
|
|
do_install() {
|
|
|
- log_info "=== УСТАНОВКА Odoo $OE_VERSION ==="
|
|
|
+ log_info "=== УСТАНОВКА Odoo $OE_VERSION на Debian 13 (Trixie) ==="
|
|
|
|
|
|
# 1. Базовые пакеты
|
|
|
apt-get update
|
|
|
-
|
|
|
- log_info "Внимание: будет выполнено обновление всех пакетов системы (apt-get upgrade)."
|
|
|
- read -p "Продолжить обновление системы? (Y/n): " confirm_upgrade
|
|
|
- if [[ ! "$confirm_upgrade" =~ ^[Nn]$ ]]; then
|
|
|
- apt-get upgrade -y
|
|
|
- else
|
|
|
- log_info "Обновление системы пропущено."
|
|
|
- fi
|
|
|
-
|
|
|
+ apt-get upgrade -y
|
|
|
apt-get install -y git python3 python3-pip build-essential wget \
|
|
|
python3-dev python3-venv python3-wheel python3-cffi \
|
|
|
libssl-dev libffi-dev libxml2-dev libxslt1-dev \
|
|
|
@@ -226,13 +197,14 @@ do_install() {
|
|
|
libjpeg-dev zlib1g-dev libpng-dev \
|
|
|
nodejs npm gdebi-core curl unzip
|
|
|
|
|
|
- # 2. PostgreSQL 16
|
|
|
+ # 2. PostgreSQL 16 (рекомендуемая версия для Odoo 19 на Debian 13)
|
|
|
log_info "Установка PostgreSQL 16"
|
|
|
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /usr/share/keyrings/postgresql-archive-keyring.gpg
|
|
|
echo "deb [signed-by=/usr/share/keyrings/postgresql-archive-keyring.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
|
|
apt-get update
|
|
|
apt-get install -y postgresql-16 postgresql-client-16 postgresql-server-dev-16
|
|
|
|
|
|
+ # Если кластер не запустился автоматически — запускаем или создаём
|
|
|
if ! pg_isready -q; then
|
|
|
log_info "PostgreSQL не отвечает, пробуем запустить кластер"
|
|
|
pg_ctlcluster 16 main start || {
|
|
|
@@ -241,7 +213,7 @@ do_install() {
|
|
|
}
|
|
|
fi
|
|
|
|
|
|
- # Оставляем права суперпользователя (-s) для управления базами
|
|
|
+ # Создаём пользователя odoo в PostgreSQL
|
|
|
su - postgres -c "createuser -s $OE_USER" 2>/dev/null || true
|
|
|
|
|
|
# 3. wkhtmltopdf
|
|
|
@@ -258,8 +230,8 @@ do_install() {
|
|
|
extract_custom
|
|
|
|
|
|
# 7. Права
|
|
|
- chown -R $OE_USER:$OE_USER "$OE_HOME"
|
|
|
- chown -R $OE_USER:$OE_USER "/var/log/$OE_USER"
|
|
|
+ chown -R $OE_USER:$OE_USER $OE_HOME
|
|
|
+ chown -R $OE_USER:$OE_USER /var/log/$OE_USER
|
|
|
|
|
|
# 8. Виртуальное окружение
|
|
|
setup_venv
|
|
|
@@ -270,7 +242,6 @@ do_install() {
|
|
|
|
|
|
echo "-----------------------------------------------------------"
|
|
|
echo "УСТАНОВКА ЗАВЕРШЕНА"
|
|
|
- echo "-----------------------------------------------------------"
|
|
|
echo "Веб-интерфейс: http://$(hostname -I | awk '{print $1}'):$OE_PORT"
|
|
|
echo "Мастер-пароль: $OE_SUPERADMIN"
|
|
|
echo "Конфиг: $OE_CONFIG_FILE"
|
|
|
@@ -281,7 +252,7 @@ do_install() {
|
|
|
|
|
|
do_update() {
|
|
|
log_info "=== ОБНОВЛЕНИЕ Odoo $OE_VERSION ==="
|
|
|
- systemctl stop "${OE_SERVER}" || true
|
|
|
+ systemctl stop ${OE_SERVER} || true
|
|
|
|
|
|
ODOO_ARCHIVE=$(ls -t "$SCRIPT_DIR"/odoo_19.0+e.*.tar.gz 2>/dev/null | head -n1)
|
|
|
if [[ -z "$ODOO_ARCHIVE" ]]; then
|
|
|
@@ -292,7 +263,7 @@ do_update() {
|
|
|
|
|
|
extract_odoo
|
|
|
extract_custom
|
|
|
- chown -R $OE_USER:$OE_USER "$OE_HOME"
|
|
|
+ chown -R $OE_USER:$OE_USER $OE_HOME
|
|
|
|
|
|
su - $OE_USER -s /bin/bash <<EOF
|
|
|
source $OE_VENV/bin/activate
|
|
|
@@ -303,7 +274,7 @@ deactivate
|
|
|
EOF
|
|
|
|
|
|
update_databases
|
|
|
- systemctl start "${OE_SERVER}"
|
|
|
+ systemctl start ${OE_SERVER}
|
|
|
log_info "Обновление завершено"
|
|
|
}
|
|
|
|
|
|
@@ -315,40 +286,35 @@ do_uninstall() {
|
|
|
exit 0
|
|
|
fi
|
|
|
|
|
|
- systemctl stop "${OE_SERVER}" 2>/dev/null || true
|
|
|
- systemctl disable "${OE_SERVER}" 2>/dev/null || true
|
|
|
- rm -f "/etc/systemd/system/${OE_SERVER}.service"
|
|
|
+ systemctl stop ${OE_SERVER} 2>/dev/null || true
|
|
|
+ systemctl disable ${OE_SERVER} 2>/dev/null || true
|
|
|
+ rm -f /etc/systemd/system/${OE_SERVER}.service
|
|
|
systemctl daemon-reload
|
|
|
- rm -f "$OE_CONFIG_FILE"
|
|
|
- rmdir "$OE_CONFIG_DIR" 2>/dev/null || true
|
|
|
- rm -rf "$OE_HOME"
|
|
|
- rm -rf "/var/log/$OE_USER"
|
|
|
- userdel -r "$OE_USER" 2>/dev/null || true
|
|
|
+ rm -f $OE_CONFIG_FILE
|
|
|
+ rmdir $OE_CONFIG_DIR 2>/dev/null || true
|
|
|
+ rm -rf $OE_HOME
|
|
|
+ rm -rf /var/log/$OE_USER
|
|
|
+ userdel -r $OE_USER 2>/dev/null || true
|
|
|
|
|
|
read -p "Удалить пользователя PostgreSQL 'odoo' и его базы? (y/N): " del_pg
|
|
|
if [[ "$del_pg" =~ ^[Yy]$ ]]; then
|
|
|
if id "postgres" &>/dev/null; then
|
|
|
dbs=$(sudo -Hiu postgres psql -tAc "SELECT datname FROM pg_database WHERE datdba = (SELECT oid FROM pg_roles WHERE rolname='$OE_USER')")
|
|
|
for db in $dbs; do
|
|
|
- db=$(echo "$db" | xargs)
|
|
|
- [[ -z "$db" ]] && continue
|
|
|
sudo -u postgres dropdb "$db" 2>/dev/null || true
|
|
|
done
|
|
|
- sudo -u postgres dropuser --if-exists "$OE_USER" 2>/dev/null || true
|
|
|
- log_info "Пользователь PostgreSQL и его базы удалены"
|
|
|
+ sudo -u postgres dropuser --if-exists $OE_USER 2>/dev/null || true
|
|
|
+ log_info "Пользователь PostgreSQL удалён"
|
|
|
fi
|
|
|
fi
|
|
|
|
|
|
- read -p "Удалить PostgreSQL полностью? (ВНИМАНИЕ: это удалит ВСЕ базы на сервере) (y/N): " del_pg_all
|
|
|
+ read -p "Удалить PostgreSQL полностью? (y/N): " del_pg_all
|
|
|
if [[ "$del_pg_all" =~ ^[Yy]$ ]]; then
|
|
|
- read -p "Вы абсолютно уверены? Это действие необратимо! (y/N): " confirm_all
|
|
|
- if [[ "$confirm_all" =~ ^[Yy]$ ]]; then
|
|
|
- apt-get purge -y postgresql-16 postgresql-client-16 postgresql-server-dev-16
|
|
|
- rm -rf /var/lib/postgresql /var/log/postgresql
|
|
|
- log_info "Пакеты PostgreSQL и данные удалены. Системный пользователь 'postgres' сохранен для стабильности ОС."
|
|
|
- else
|
|
|
- log_info "Отмена полного удаления PostgreSQL."
|
|
|
- fi
|
|
|
+ apt-get purge -y postgresql-16 postgresql-client-16 postgresql-server-dev-16
|
|
|
+ rm -rf /var/lib/postgresql /var/log/postgresql
|
|
|
+ userdel -r postgres 2>/dev/null || true
|
|
|
+ groupdel postgres 2>/dev/null || true
|
|
|
+ log_info "PostgreSQL удалён"
|
|
|
fi
|
|
|
|
|
|
log_info "Удаление завершено"
|
|
|
@@ -368,4 +334,4 @@ case "$1" in
|
|
|
*) echo "Неверный параметр: $1"; exit 1 ;;
|
|
|
esac
|
|
|
|
|
|
-exit 0
|
|
|
+exit 0
|