-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathcheckmodule
More file actions
executable file
·209 lines (185 loc) · 8.88 KB
/
Copy pathcheckmodule
File metadata and controls
executable file
·209 lines (185 loc) · 8.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#!/usr/bin/env bash
################################################################################
# checkmodule — install/update Odoo modules in a database (dev tool)
#
# Creates the database if it does not exist (owner: odoo), stops the Odoo
# service, runs `odoo --init` for the given modules and restarts the service.
# Optionally exports PO files and/or drops the database afterwards.
#
# Usage: checkmodule -d <database> -m <module[,module...]> [options]
#
# Requires: root (or sudo) — the script stops/starts the odoo service and
# accesses PostgreSQL as the postgres superuser to create the database.
################################################################################
LOG_LEVEL="warn" # default log level
WITH_DEMO=true # default: install with demo data
EXPORT_PO=false # default: no PO export
LANG_CODE="sv_SE" # default language
TEST=""
DROP_DB=false
MULTI_USER=""
NO_ADDONS_PATH=false
ODOO_SERVER_CONF=${ODOO_SERVER_CONF:-"/etc/odoo/odoo.conf"}
usage() {
cat <<'EOF' 1>&2
Usage: checkmodule -d <database> -m <module[,module...]> [options]
Required:
-d <database> Database name (created automatically if it does not exist)
-m <module>,... Comma-separated modules to install/update
Options:
-D Install without demo data
-e Export PO file(s) after installation
-L <lang_code> Language for PO export (default: sv_SE)
-l <log_level> debug|debug_rpc|debug_sql|debug_rpc_answer|info|warn|test|error|critical|notset (default: warn)
-t Run tests (--test-enable)
--drop Drop the database after completion (test databases)
--multi-user Run odoo on port 4444 in parallel; do NOT stop the service
--no-addons-path Skip refreshing addons_path in odoo.conf (default: refresh)
Examples:
checkmodule -d test_demo -m sale,stock # create DB (if missing) + install modules
checkmodule -d test_demo -m my_module -t # install with tests
checkmodule -d test_demo -m my_module -e -L sv_SE # install + export sv_SE PO file
checkmodule -d test_demo -m my_module --drop # throwaway test database
EOF
exit 1
}
OPTIONS=$(getopt -o d:m:l:DeL:th -l drop,multi-user,no-addons-path -- "$@")
if [ $? -ne 0 ]; then
usage
fi
eval set -- "$OPTIONS"
while true; do
case "$1" in
-d) ODOODB="$2"; shift 2 ;;
-m) ODOOMODULES="$2"; shift 2 ;;
-l)
LOG_LEVEL="$2"
if [[ ! "$LOG_LEVEL" =~ ^(debug|debug_rpc|debug_sql|debug_rpc_answer|info|warn|test|error|critical|notset)$ ]]; then
echo "Invalid log level: $LOG_LEVEL" >&2
usage
fi
shift 2
;;
-D) WITH_DEMO=false; shift ;;
-e) EXPORT_PO=true; shift ;;
-L) LANG_CODE="$2"; shift 2 ;;
-t) TEST="--test-enable"; shift ;;
-h) usage ;;
--drop) DROP_DB=true; shift ;;
--multi-user) MULTI_USER="-p 4444"; shift ;;
--no-addons-path) NO_ADDONS_PATH=true; shift ;;
--) shift; break ;;
*) echo "Invalid option: $1" >&2; usage ;;
esac
done
if [ -z "$ODOOMODULES" ] || [ -z "$ODOODB" ]; then
echo "ERROR: -d <database> and -m <module> are required." >&2
usage
fi
# Odoo database names allow only [a-zA-Z0-9_]
if ! [[ "$ODOODB" =~ ^[a-zA-Z0-9_]+$ ]]; then
echo "ERROR: invalid database name '$ODOODB' (only a-z, A-Z, 0-9 and _ allowed)." >&2
exit 1
fi
# -e (PO export) stops the service, so it cannot be combined with --multi-user
if [ "$EXPORT_PO" = true ] && [ -n "$MULTI_USER" ]; then
echo "ERROR: -e (PO export) cannot be combined with --multi-user." >&2
exit 1
fi
# ── Ensure the database exists (create if missing) ─────────────────────────
if sudo -u postgres psql -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname='${ODOODB}';" 2>/dev/null | grep -q 1; then
echo "Database '${ODOODB}' already exists."
else
echo "Database '${ODOODB}' does not exist — creating it (owner: odoo)..."
if ! sudo -u postgres createdb -O odoo -E UTF8 -T template0 --lc-collate=C --lc-ctype=C "${ODOODB}"; then
echo "WARN: could not create database with owner 'odoo' — retrying without explicit owner." >&2
sudo -u postgres createdb -E UTF8 -T template0 --lc-collate=C --lc-ctype=C "${ODOODB}" || {
echo "ERROR: failed to create database '${ODOODB}'." >&2
exit 1
}
fi
fi
# ── Ensure AGE/pgvector extensions (per-database setup) ─────────────────────
# Required BEFORE Odoo model init (ai_agent_core OKF/Odoo Mind: ag_catalog
# schema + vector/age extensions must exist when models are initialized).
# Mirrors what Salt postgres.extensions_activate does on other servers.
echo "Ensuring PostgreSQL extensions (vector, age) in '${ODOODB}'..."
sudo -u postgres psql -d "${ODOODB}" -c "CREATE SCHEMA IF NOT EXISTS ag_catalog;" || echo "WARN: could not ensure ag_catalog schema" >&2
sudo -u postgres psql -d "${ODOODB}" -c "CREATE EXTENSION IF NOT EXISTS vector;" || echo "WARN: vector extension unavailable (pgvector-paket saknas?)" >&2
sudo -u postgres psql -d "${ODOODB}" -c "CREATE EXTENSION IF NOT EXISTS age CASCADE;" || echo "WARN: age extension unavailable (age-paket saknas?)" >&2
# ── Refresh addons_path (samma logik som odooaddons, anpassad för Pi) ──────
# Bygger addons_path från de faktiska /usr/share/odoo-* + odooext-*
# katalogerna på disken och skriver raden i odoo.conf. Odoo 18 lägger
# alltid till core-addons (/usr/lib/python3/dist-packages/odoo/addons +
# filestore) själv, så det räcker att konfigen innehåller /usr/share-listan.
refresh_addons_path() {
local new_addons cur
new_addons=$(
{ ls -d /usr/share/odoo-* 2>/dev/null | grep -v 'odoo-addons$';
ls -d /usr/share/odooext-* 2>/dev/null;
[ -d /usr/src/OCB/addons ] && echo /usr/src/OCB/addons; } | paste -sd ","
)
if [ -z "$new_addons" ]; then
echo "WARN: hittade inga /usr/share/odoo-* addons-kataloger — hoppar addons_path-uppdatering." >&2
return 1
fi
cur=$(grep '^addons_path=' "$ODOO_SERVER_CONF" 2>/dev/null | head -1 | cut -d= -f2-)
if [ "$cur" = "$new_addons" ]; then
echo "addons_path redan aktuell (${#new_addons} tecken)."
return 0
fi
echo "Uppdaterar addons_path i $ODOO_SERVER_CONF..."
if grep -q '^addons_path=' "$ODOO_SERVER_CONF" 2>/dev/null; then
sudo perl -i -pe "s/^addons_path=.*/addons_path=${new_addons//\//\\\/}/g" "$ODOO_SERVER_CONF"
else
echo "addons_path=$new_addons" | sudo tee -a "$ODOO_SERVER_CONF" > /dev/null
fi
echo " -> $(grep '^addons_path=' "$ODOO_SERVER_CONF" | cut -c1-100)..."
}
if [ "$NO_ADDONS_PATH" = false ]; then
refresh_addons_path
fi
# ── Install/update modules ──────────────────────────────────────────────────
if [ "$WITH_DEMO" = "false" ]; then
DEMO_OPTION="--without-demo=all"
else
DEMO_OPTION=""
fi
echo "Installing/updating module(s) ${ODOOMODULES} in database '${ODOODB}' (log_level=${LOG_LEVEL}, demo=${WITH_DEMO})"
if [ -z "$MULTI_USER" ]; then
sudo service odoo stop
fi
if [ "$EXPORT_PO" = false ]; then
sudo -E su odoo -c "odoo --config ${ODOO_SERVER_CONF} --database ${ODOODB} --init ${ODOOMODULES} --load-language=${LANG_CODE} ${MULTI_USER} ${TEST} --limit-time-cpu=180 --limit-time-real=300 --stop-after-init --log-level=${LOG_LEVEL} ${DEMO_OPTION}"
INSTALL_RC=$?
else
# Export PO file(s) after installation
echo "Exporting PO file(s) for language: ${LANG_CODE}"
IFS=',' read -ra MODULE_LIST <<< "$ODOOMODULES"
sudo service odoo stop
echo "Step 1/2: installing module(s) ${ODOOMODULES} in '${ODOODB}'..."
sudo -E su odoo -c "odoo --config ${ODOO_SERVER_CONF} --database ${ODOODB} --init ${ODOOMODULES} --load-language=${LANG_CODE} --limit-time-cpu=180 --limit-time-real=300 --stop-after-init ${DEMO_OPTION}"
INSTALL_RC=$?
for module in "${MODULE_LIST[@]}"; do
SHORT_LANG_CODE=${LANG_CODE%%_*}
PO_FILE="${module}-${SHORT_LANG_CODE}.po"
echo "Step 2/2: exporting ${PO_FILE}..."
if sudo -E su odoo -c "odoo --config ${ODOO_SERVER_CONF} --database ${ODOODB} --modules ${module} --i18n-export=/tmp/$$.po --language=${LANG_CODE} --stop-after-init" && \
sudo mv /tmp/$$.po "${PO_FILE}"; then
echo "Saved $(pwd)/${PO_FILE}"
else
echo "WARN: PO export failed for module '${module}'." >&2
fi
done
fi
if [ "$DROP_DB" = true ]; then
echo "Dropping database '${ODOODB}' (--drop)..."
sudo -u postgres dropdb -f "${ODOODB}"
fi
if [ -z "$MULTI_USER" ]; then
sudo service odoo start
fi
if [ "$INSTALL_RC" -ne 0 ]; then
echo "WARN: odoo --init exited with code ${INSTALL_RC}." >&2
fi
exit "$INSTALL_RC"