5 changed files with 402 additions and 0 deletions
-
214recipes/odoo/crud.sh
-
124recipes/odoo/install.sh
-
33templates/apps/odoo/odoo-addon-install
-
17templates/apps/odoo/odoo.conf.j2
-
14templates/apps/odoo/odoo.service.j2
@ -0,0 +1,214 @@ |
|||
#!/bin/bash |
|||
|
|||
function check_database_exists() { |
|||
db-psql list | grep -q "$longname" |
|||
} |
|||
|
|||
function check_port_used() { |
|||
# shellcheck disable=SC2034 |
|||
usedport=$(lxc exec "$container" -- bash -c "grep xmlrpc_port /etc/odoo/$shortname.conf | cut -d' ' -f3") |
|||
[[ "$usedport" == "$port" ]] |
|||
} |
|||
|
|||
function check_service_running() { |
|||
lxc exec "$container" -- bash -c "systemctl is-active --quiet ${longname}.service" |
|||
} |
|||
|
|||
function _read() { |
|||
disable_trace |
|||
check_database_exists |
|||
check_container "$container" |
|||
check_port_used |
|||
check_service_running |
|||
enable_trace |
|||
return 0 |
|||
} |
|||
|
|||
function _create() { |
|||
|
|||
echo "creating templates ... " |
|||
mkdir -p "$MIAOU_CONFIGDIR/apps/odoo" |
|||
|
|||
longport=$((port + 1000)) |
|||
APP_PORT=$port LONG_PORT=$longport APP_NAME=$shortname tera -e -t "$MIAOU_BASEDIR/templates/apps/odoo/odoo.conf.j2" -o "$MIAOU_CONFIGDIR/apps/odoo/$shortname.conf" "$MIAOU_CONFIGDIR/miaou.expanded.yaml" >/dev/null |
|||
APP_NAME=$shortname tera -t "$MIAOU_BASEDIR/templates/apps/odoo/odoo.service.j2" --env-only -o "$MIAOU_CONFIGDIR/apps/odoo/$longname.service" >/dev/null |
|||
echo "creating templates ... OK" |
|||
|
|||
echo "copying files to container <$container> ... " |
|||
lxc file push --uid 0 --gid 0 "$MIAOU_CONFIGDIR/apps/odoo/$shortname.conf" "$container/etc/odoo/$shortname.conf" |
|||
lxc file push --uid 0 --gid 0 "$MIAOU_CONFIGDIR/apps/odoo/$longname.service" "$container/etc/systemd/system/$longname.service" |
|||
echo "copying files to container <$container> ... OK" |
|||
|
|||
echo "create data folder for $shortname" |
|||
cat <<EOF | lxc_exec "$container" |
|||
set -Eeuo pipefail |
|||
|
|||
echo allow addons writable for user odoo |
|||
mkdir -p /home/odoo/data-$shortname/addons/18.0 |
|||
chmod u+w /home/odoo/data-$shortname/addons/18.0 |
|||
chown -R odoo:odoo /home/odoo/data-$shortname |
|||
EOF |
|||
|
|||
if ! (db-psql list | grep -q "$longname"); then |
|||
echo "create empty database <$longname> ... " |
|||
db-psql create "$longname" |
|||
echo "create empty database <$longname> ... OK" |
|||
|
|||
admin_username=$(echo -e "$data" | yq '.admin.username') |
|||
[[ $admin_username = 'null' ]] && echoerr "odoo recipe requires \`data:admin:username\` into miaou.yaml service definition of <$fqdn>" && exit 1 |
|||
|
|||
admin_password=$(echo -e "$data" | yq '.admin.password') |
|||
[[ $admin_password = 'null' ]] && echoerr "odoo recipe requires \`data:admin:password\` into miaou.yaml service definition of <$fqdn>" && exit 1 |
|||
|
|||
cat <<EOF | lxc_exec "$container" |
|||
set -Eeuo pipefail |
|||
|
|||
echo reloading systemd |
|||
systemctl daemon-reload |
|||
systemctl stop $longname |
|||
|
|||
echo initialize database... |
|||
su odoo -c "python3.10 /home/odoo/odoo/odoo-bin -c /etc/odoo/$shortname.conf -i base --without-demo=all --stop-after-init" |
|||
echo initialize database OK |
|||
|
|||
echo install default modules ... |
|||
su odoo -c "python3.10 /home/odoo/odoo/odoo-bin -c /etc/odoo/$shortname.conf -i account,contacts,l10n_fr,account,sale,point_of_sale -d $longname --worker=0 --stop-after-init" |
|||
echo default modules OK |
|||
|
|||
echo activate french language |
|||
su odoo -c "python3.10 /home/odoo/odoo/odoo-bin -c /etc/odoo/$shortname.conf --load-language fr_FR -d $longname --worker=0 --stop-after-init" |
|||
|
|||
echo change administrator password, default credential applied! |
|||
echo "UPDATE res_users SET login='$admin_username', password='$admin_password' WHERE id=2" | PGPASSWORD=$longname psql -U $longname -h ct1.lxd |
|||
|
|||
EOF |
|||
else |
|||
echo "database already exists!" |
|||
fi |
|||
|
|||
echo "initialize odoo $shortname $longname ..." |
|||
cat <<EOF | lxc_exec "$container" |
|||
set -Eeuo pipefail |
|||
|
|||
echo reloading systemd |
|||
systemctl daemon-reload |
|||
|
|||
if ! systemctl is-active --quiet $longname; then |
|||
echo start service $longname |
|||
systemctl enable $longname |
|||
systemctl start $longname |
|||
systemctl is-active --quiet $longname |
|||
else |
|||
echo service $longname already started! |
|||
fi |
|||
|
|||
EOF |
|||
echo "initialize odoo $shortname $longname ... OK" |
|||
} |
|||
|
|||
function _update() { |
|||
echo "update" |
|||
} |
|||
|
|||
function _delete() { |
|||
echo "delete" |
|||
} |
|||
|
|||
function usage() { |
|||
echo "Usage: $COMMAND_NAME -c|r|u|d --port $port --fqdn $fqdn --container $container --name $name --data $data" |
|||
exit 2 |
|||
} |
|||
|
|||
### MAIN |
|||
|
|||
# init_strict |
|||
|
|||
COMMAND_NAME=$(basename "$0") |
|||
|
|||
# read the options |
|||
|
|||
TEMP=$(getopt -n "$COMMAND_NAME" -o crud --long port:,container:,name:,fqdn:,domain:,subdomain:,data: -- "$@") |
|||
# shellcheck disable=SC2181 |
|||
[[ "$?" -eq 0 ]] || usage |
|||
eval set -- "$TEMP" |
|||
|
|||
action="unset" |
|||
port="unset" |
|||
fqdn="unset" |
|||
container="unset" |
|||
shortname="unset" |
|||
longname="unset" |
|||
data="unset" |
|||
|
|||
# extract options and their arguments into variables. |
|||
while true; do |
|||
case "$1" in |
|||
--port) |
|||
port=$2 |
|||
shift 2 |
|||
;; |
|||
--fqdn) |
|||
fqdn=$2 |
|||
shift 2 |
|||
;; |
|||
--container) |
|||
container=$2 |
|||
shift 2 |
|||
;; |
|||
--name) |
|||
shortname=$2 |
|||
longname="odoo-$shortname" |
|||
shift 2 |
|||
;; |
|||
--data) |
|||
data=$2 |
|||
shift 2 |
|||
;; |
|||
--domain) |
|||
shift 2 |
|||
;; |
|||
--subdomain) |
|||
shift 2 |
|||
;; |
|||
-c) |
|||
[[ "$action" == "unset" ]] || usage |
|||
action="_create" |
|||
shift 1 |
|||
;; |
|||
-r) |
|||
[[ "$action" == "unset" ]] || usage |
|||
action="_read" |
|||
shift 1 |
|||
;; |
|||
-u) |
|||
[[ "$action" == "unset" ]] || usage |
|||
action="_update" |
|||
shift 1 |
|||
;; |
|||
-d) |
|||
[[ "$action" == "unset" ]] || usage |
|||
action="_delete" |
|||
shift 1 |
|||
;; |
|||
--) |
|||
shift |
|||
break |
|||
;; |
|||
*) |
|||
echoerr "Internal error: unrecognized option: <$1>" |
|||
exit 1 |
|||
;; |
|||
esac |
|||
done |
|||
|
|||
[[ |
|||
"$action" != unset && |
|||
"$port" != unset && |
|||
"$fqdn" != unset && |
|||
"$container" != unset && |
|||
"$shortname" != unset && |
|||
"$data" != unset ]] || usage |
|||
|
|||
. "$MIAOU_BASEDIR/lib/init.sh" |
|||
|
|||
$action |
@ -0,0 +1,124 @@ |
|||
#!/bin/bash |
|||
|
|||
readonly EXPANDED_CONF="$MIAOU_CONFIGDIR/miaou.expanded.yaml" |
|||
readonly ODOO_DIR="/home/odoo/odoo" |
|||
|
|||
readonly WKHTML_VERSION="0.12.6.1-3" |
|||
readonly WKHTML_RELEASE="$WKHTML_VERSION.bookworm_amd64" |
|||
|
|||
function check_user_odoo() { |
|||
(lxc exec "$CONTAINER" -- id odoo &>/dev/null) || return 12 |
|||
return 0 |
|||
} |
|||
|
|||
function check_target_bgcolor() { |
|||
(lxc exec "$CONTAINER" -- grep -Pq "^\\\$o-community-color: $BACKGROUND_COLOR" "$ODOO_DIR/addons/web/static/src/legacy/scss/primary_variables.scss") || return 13 |
|||
return 0 |
|||
} |
|||
|
|||
function check_file_odoo-addon-install() { |
|||
(lxc exec "$CONTAINER" -- test -f /home/odoo/odoo/odoo-addon-install) || return 23 |
|||
return 0 |
|||
} |
|||
|
|||
function check() { |
|||
PREFIX="recipe:odoo:check" |
|||
check_user_odoo || return 21 |
|||
check_target_bgcolor || return 22 |
|||
check_file_odoo-addon-install || return 23 |
|||
} |
|||
|
|||
function install() { |
|||
PREFIX="recipe:odoo:install" |
|||
: $PREFIX |
|||
launch_container "$CONTAINER" |
|||
echo "initializing Odoo ... " |
|||
|
|||
lxc exec "$CONTAINER" -- bash <<EOF |
|||
set -Eeuo pipefail |
|||
echo "installing odoo..." |
|||
apt update && apt dist-upgrade -y |
|||
|
|||
echo "required packages" |
|||
apt install -y postgresql-client build-essential zlib1g-dev libssl-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev libpq-dev libffi-dev |
|||
|
|||
if [[ ! -d /usr/local/share/python3.10 ]]; then |
|||
echo "install python-3.10.17" |
|||
cd /tmp |
|||
wget https://www.python.org/ftp/python/3.10.17/Python-3.10.17.tgz |
|||
tar -xf Python-3.10.17.tgz |
|||
mv Python-3.10.17 /usr/local/share/python3.10 |
|||
cd /usr/local/share/python3.10 |
|||
./configure --enable-optimizations --enable-shared |
|||
make -j \$(nproc) |
|||
make altinstall |
|||
ldconfig /usr/local/share/python3.10 |
|||
else |
|||
echo "python-3.10.17 already installed!" |
|||
fi |
|||
|
|||
if dpkg -l | grep -s wkhtmltox | grep -qs $WKHTML_VERSION; then |
|||
echo package=wkhtmltox version=$WKHTML_RELEASE already found! |
|||
else |
|||
echo "wkhtmltox version=$WKHTML_RELEASE has to be installed!" |
|||
wget https://github.com/wkhtmltopdf/packaging/releases/download/$WKHTML_VERSION/wkhtmltox_$WKHTML_RELEASE.deb |
|||
dpkg -i wkhtmltox_$WKHTML_RELEASE.deb || (apt -fy install && rm wkhtmltox_$WKHTML_RELEASE.deb) |
|||
fi |
|||
|
|||
if ! grep -q odoo /etc/passwd; then |
|||
echo "add user <odoo>" |
|||
useradd -ms /bin/bash odoo |
|||
else |
|||
echo "user <odoo> already set!" |
|||
fi |
|||
|
|||
echo "install odoo in odoo userspace" |
|||
cat <<EOT | su - odoo |
|||
set -Eeuo pipefail |
|||
|
|||
if [[ ! -d odoo ]]; then |
|||
echo "git odoo from remote" |
|||
git clone https://github.com/odoo/odoo.git --depth 1 --branch 18.0 odoo |
|||
export MAKEFLAGS="-j\$(nproc)" |
|||
pip3.10 install --upgrade pip |
|||
pip3.10 install wheel pypdf2 slugify |
|||
pip3.10 install -r odoo/requirements.txt |
|||
else |
|||
echo "git odoo already downloaded!" |
|||
fi |
|||
echo "community-color change to $BACKGROUND_COLOR" |
|||
/opt/miaou-bash/tools/append_or_replace "^.*o-community-color:.*" "\\\\\\\$o-community-color: $BACKGROUND_COLOR !default;" /home/odoo/odoo/addons/web/static/src/legacy/scss/primary_variables.scss |
|||
|
|||
EOT |
|||
mkdir -p /etc/odoo |
|||
EOF |
|||
lxc file push "$MIAOU_BASEDIR/templates/apps/odoo/odoo-addon-install" "$CONTAINER/home/odoo/odoo/odoo-addon-install" |
|||
lxc exec "$CONTAINER" -- bash <<EOF |
|||
chown odoo:odoo /home/odoo/odoo/odoo-addon-install |
|||
chmod 740 /home/odoo/odoo/odoo-addon-install |
|||
echo "new script <odoo-addon-install> added!" |
|||
EOF |
|||
} |
|||
|
|||
function compute_bgcolor_target() { |
|||
target=$(yq '.target' "$EXPANDED_CONF") |
|||
case "$target" in |
|||
dev) builtin echo "#17a2b8" ;; |
|||
beta) builtin echo "#79A70A" ;; |
|||
prod) builtin echo "#7C7BAD" ;; |
|||
*) echoerr "unknown target <$target>" && exit 10 ;; |
|||
esac |
|||
} |
|||
|
|||
### MAIN |
|||
|
|||
. "$MIAOU_BASEDIR/lib/init.sh" |
|||
arg1_required "$@" |
|||
readonly CONTAINER="$1" |
|||
BACKGROUND_COLOR=$(compute_bgcolor_target) |
|||
readonly BACKGROUND_COLOR |
|||
|
|||
check || ( |
|||
install |
|||
check |
|||
) |
@ -0,0 +1,33 @@ |
|||
#!/bin/bash |
|||
|
|||
CLIENT=$1 |
|||
ADDON=$2 |
|||
|
|||
function usage() { |
|||
echo 'usage: <CLIENT> <ADDON>' |
|||
exit 100 |
|||
} |
|||
|
|||
# VERIFICATION |
|||
|
|||
[[ -z "$CLIENT" || -z "$ADDON" ]] && usage |
|||
[[ ! -d "/home/odoo/data-${CLIENT}" ]] && echo "unknown CLIENT <${CLIENT}>, should exist in folder /home/odoo/data-..." && exit 2 |
|||
|
|||
URL="https://pypi.org/project/odoo-addon-${ADDON}/" |
|||
curl --output /dev/null --silent --head --fail "${URL}" |
|||
[[ $? -ne 0 ]] && echo "unknown ADDON <${ADDON}>, should be downloadable from: ${URL}" && exit 3 |
|||
|
|||
[[ -d "/home/odoo/data-${CLIENT}/addons/18.0/${ADDON}" ]] && echo "ADDON <${ADDON}> already exists, consider removing manually!" && exit 4 |
|||
|
|||
# ACTION |
|||
|
|||
package=$(curl -Ls "$URL" | rg '<a href="(https://files.pythonhosted.org/.*)">' -r '$1') |
|||
wget $package -O /tmp/package.zip |
|||
rm /tmp/ADDON -rf && mkdir /tmp/ADDON |
|||
unzip /tmp/package.zip 'odoo/addons/*' -d /tmp/ADDON/ |
|||
real_name=$(unzip -l /tmp/package.zip | head -n4 | tail -n1 | cut -d'/' -f3) |
|||
chown -R odoo:odoo /tmp/ADDON/ |
|||
mv /tmp/ADDON/odoo/addons/* "/home/odoo/data-$CLIENT/addons/18.0/" |
|||
|
|||
# ADD |
|||
su odoo -c "python3.10 /home/odoo/odoo/odoo-bin -c /etc/odoo/$CLIENT.conf -i $real_name -d odoo-$CLIENT --worker=0 --stop-after-init" |
@ -0,0 +1,17 @@ |
|||
[options] |
|||
data_dir = /home/odoo/data-{{ APP_NAME }} |
|||
|
|||
xmlrpc_port = {{ APP_PORT }} |
|||
longpolling_port = {{ LONG_PORT }} |
|||
|
|||
db_host = ct1.lxd |
|||
db_name = odoo-{{ APP_NAME }} |
|||
db_user = odoo-{{ APP_NAME }} |
|||
db_password = odoo-{{ APP_NAME }} |
|||
list_db = {{ target != 'prod'}} |
|||
|
|||
workers = 2 |
|||
db_maxconn = 10 |
|||
db_filter = .* |
|||
syslog = True |
|||
proxy_mode = True |
@ -0,0 +1,14 @@ |
|||
[Unit] |
|||
Description=Odoo {{ APP_NAME }} |
|||
After=network.target |
|||
|
|||
[Service] |
|||
Type=simple |
|||
SyslogIdentifier=odoo-{{ APP_NAME }} |
|||
PermissionsStartOnly=true |
|||
User=odoo |
|||
Group=odoo |
|||
ExecStart=python3.10 /home/odoo/odoo/odoo-bin -c /etc/odoo/{{ APP_NAME }}.conf |
|||
|
|||
[Install] |
|||
WantedBy=multi-user.target |
Write
Preview
Loading…
Cancel
Save
Reference in new issue