From 3647f5ae6dbd040310364ea649a4edee57edab7c Mon Sep 17 00:00:00 2001 From: Janik von Rotz Date: Thu, 25 Apr 2024 16:37:15 +0200 Subject: [PATCH] reafctor: custom Docker image --- .gitmodules | 4 + .python-version | 2 +- Dockerfile | 118 ++++++++++++- README.md | 20 +-- addons/server_tools | 2 +- build/entrypoint.sh | 28 +++- build/odoo.conf.template | 2 +- build/wait-for-psql.py | 32 ++++ docker-compose.yml | 5 +- enterprise | 2 +- oca/web-api | 1 + odoo | 2 +- task | 349 ++++++++++++++++++++++----------------- task.md | 2 + 14 files changed, 381 insertions(+), 188 deletions(-) create mode 100755 build/wait-for-psql.py create mode 160000 oca/web-api diff --git a/.gitmodules b/.gitmodules index 9cc6692c..ebb8777c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -250,3 +250,7 @@ path = oca/hr-attendance url = git@github.com:OCA/hr-attendance.git branch = 16.0 +[submodule "oca/web-api"] + path = oca/web-api + url = git@github.com:OCA/web-api.git + branch = 16.0 diff --git a/.python-version b/.python-version index 2c073331..902b2c90 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.11 +3.11 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index ca73820e..e9914ee7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,117 @@ -ARG ODOO_IMAGE +FROM debian:bookworm-slim +MAINTAINER Mint System GmbH -FROM $ODOO_IMAGE +SHELL ["/bin/bash", "-xo", "pipefail", "-c"] -USER root +# Generate locale C.UTF-8 for postgres and general locale data +ENV LANG C.UTF-8 -RUN apt-get update && \ -apt-get install -y --no-install-recommends \ -gettext +# Retrieve the target architecture to install the correct wkhtmltopdf package +ARG TARGETARCH -USER odoo +# Install some deps, lessc and less-plugin-clean-css, and wkhtmltopdf +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + dirmngr \ + fonts-noto-cjk \ + gnupg \ + libssl-dev \ + node-less \ + npm \ + python3-dev \ + libpq-dev \ + gcc \ + python3-venv \ + python3-magic \ + python3-num2words \ + python3-odf \ + python3-pdfminer \ + python3-pip \ + python3-phonenumbers \ + python3-pyldap \ + python3-qrcode \ + python3-renderpm \ + python3-setuptools \ + python3-slugify \ + python3-vobject \ + python3-watchdog \ + python3-xlrd \ + python3-xlwt \ + xz-utils \ + gettext && \ + if [ -z "${TARGETARCH}" ]; then \ + TARGETARCH="$(dpkg --print-architecture)"; \ + fi; \ + WKHTMLTOPDF_ARCH=${TARGETARCH} && \ + case ${TARGETARCH} in \ + "amd64") WKHTMLTOPDF_ARCH=amd64 && WKHTMLTOPDF_SHA=e9f95436298c77cc9406bd4bbd242f4771d0a4b2 ;; \ + "arm64") WKHTMLTOPDF_SHA=58c84db46b11ba0e14abb77a32324b1c257f1f22 ;; \ + "ppc64le" | "ppc64el") WKHTMLTOPDF_ARCH=ppc64el && WKHTMLTOPDF_SHA=7ed8f6dcedf5345a3dd4eeb58dc89704d862f9cd ;; \ + esac \ + && curl -o wkhtmltox.deb -sSL https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_${WKHTMLTOPDF_ARCH}.deb \ + && echo ${WKHTMLTOPDF_SHA} wkhtmltox.deb | sha1sum -c - \ + && apt-get install -y --no-install-recommends ./wkhtmltox.deb \ + && rm -rf /var/lib/apt/lists/* wkhtmltox.deb +# Install latest postgresql-client +RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ bookworm-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ + && GNUPGHOME="$(mktemp -d)" \ + && export GNUPGHOME \ + && repokey='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' \ + && gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${repokey}" \ + && gpg --batch --armor --export "${repokey}" > /etc/apt/trusted.gpg.d/pgdg.gpg.asc \ + && gpgconf --kill all \ + && rm -rf "$GNUPGHOME" \ + && apt-get update \ + && apt-get install --no-install-recommends -y postgresql-client \ + && rm -f /etc/apt/sources.list.d/pgdg.list \ + && rm -rf /var/lib/apt/lists/* + +# Install rtlcss (on Debian buster) +RUN npm install -g rtlcss + +# Prepare virtual env +RUN python3 -m venv /opt/odoo-venv +ENV PATH=/opt/odoo-venv/bin:$PATH + +# Install Odoo +COPY ./odoo /opt/odoo +RUN pip install --no-cache-dir /opt/odoo \ + && pip install lxml==4.9.2 \ + && pip list +ENV ADDONS_PATH=/opt/odoo/addons + +# Copy entrypoint script and Odoo configuration file COPY ./build/odoo.conf.template /etc/odoo/ - COPY ./build/entrypoint.sh / -RUN pip3 install prometheus-client +# Create a user named odoo +RUN adduser --disabled-password --gecos "" odoo + +# Set the working directory +WORKDIR /opt/odoo + +# Set permissions and mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons +RUN chown odoo /etc/odoo \ + && mkdir -p /mnt/extra-addons \ + && chown -R odoo /mnt/extra-addons \ + && mkdir -p /var/lib/odoo/sessions \ + && chown -R odoo /var/lib/odoo \ + && chmod +w /var/lib/odoo/sessions +VOLUME ["/var/lib/odoo", "/mnt/extra-addons"] + +# Expose Odoo services +EXPOSE 8069 8071 8072 + +# Set the default config file +ENV ODOO_RC /etc/odoo/odoo.conf + +COPY ./build/wait-for-psql.py /usr/local/bin/wait-for-psql.py + +# Set default user when running the container +USER odoo + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["odoo"] diff --git a/README.md b/README.md index 3f9a04cd..29362ba1 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,15 @@ This is the [Mint System](https://www.mint-system.ch/) Odoo development environm This projects provides a highly opinionated way to develop Odoo and Odoo modules. It supports the following scenarios: -* **Docker Compose**: Spin up a Odoo, Postgres and pgAdmin Docker container and experiment locally -* **Import and Export Database**: Use Odoo scripts to copy and restore a remote customer database to the local development environment. Investigate issues and deploy the database at wish -* **Community Edition**: Checkout the Odoo Community Edition and start editing the source code +* **Docker Compose**: Spin up a Odoo, Postgres and pgAdmin Docker container and experiment locally. +* **Import and Export Database**: Use Odoo scripts to copy and restore a remote customer database to the local environment. Investigate issues and deploy the database at ease. +* **Community Edition**: Checkout the Odoo Community Edition and start editing the source code. * **Enterprise Modules**: Checkout the Odoo enterprise modules and deploy them into the Odoo Docker container or the Odoo source. -* **Develop Modules**: Scaffold a new module, develop new Odoo features locally and [much more](./task.md) -* **Customizing Snippets**: Create [snippets](./snippets.md) and push them to an Odoo database -* **Odoo Scripts**: Develope scripts to patch Odoo code -* **Odoo Image**: Build and publish an Odoo Docker image -* **Kuberenetes**: Deploy Odoo and Postgres to Kubernetes cluster +* **Develop Modules**: Scaffold a new module, develop new Odoo features locally and [much more](./task.md). +* **Customizing Snippets**: Create [snippets](./snippets.md) and push them to an Odoo database. +* **Odoo Scripts**: Develope scripts to patch Odoo code. +* **Odoo Image**: Build and publish an custom Odoo Docker image. +* **Kuberenetes**: Deploy Odoo and Postgres to Kubernetes cluster. ## Requirements @@ -182,7 +182,7 @@ task drop-db To build the Docker image setup these `.env` vars: ```bash -ODOO_REVISION=16.5 +ODOO_REVISION=16.0 DOCKER_REGISTRY=mint-system/ ``` @@ -194,7 +194,7 @@ task build Publish the Odoo image. -``` +```bash task publish ``` diff --git a/addons/server_tools b/addons/server_tools index 21005934..d28dd812 160000 --- a/addons/server_tools +++ b/addons/server_tools @@ -1 +1 @@ -Subproject commit 210059344a85e6758460657f0051c34c95c3757b +Subproject commit d28dd812f9faee4e072e6891fda09fb69dc5be89 diff --git a/build/entrypoint.sh b/build/entrypoint.sh index fa2c2cb7..8e0e0639 100755 --- a/build/entrypoint.sh +++ b/build/entrypoint.sh @@ -2,17 +2,18 @@ set -e +echo " ___ _ ____ _ _ _ " +echo " / _ \ __| | ___ ___ | __ ) _ _(_) | __| |" +echo "| | | |/ _' |/ _ \ / _ \ | _ \| | | | | |/ _' |" +echo "| |_| | (_| | (_) | (_) | | |_) | |_| | | | (_| |" +echo " \___/ \__,_|\___/ \___/ |____/ \__,_|_|_|\__,_|" +echo +echo "Maintainer: Mint System GmbH " + if [ -v PASSWORD_FILE ]; then PASSWORD="$(< $PASSWORD_FILE)" fi -# set the postgres database host, port, user and password according to the environment -# and pass them as arguments to the odoo process if not present in the config file -: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} -: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} -: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} -: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}} - ME=$(basename "$0") entrypoint_log() { @@ -36,6 +37,19 @@ auto_envsubst() { auto_envsubst +echo "List python packages:" + +pip list + +echo "Running Odoo as user: $USER" + +# Set the postgres database host, port, user and password according to the environment +# and pass them as arguments to the odoo process if not present in the config file +: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} +: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} +: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} +: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}} + DB_ARGS=() function check_config() { param="$1" diff --git a/build/odoo.conf.template b/build/odoo.conf.template index 63cde32f..0234f9ce 100644 --- a/build/odoo.conf.template +++ b/build/odoo.conf.template @@ -1,5 +1,5 @@ [options] -addons_path = $ODOO_ADDONS_PATH +addons_path = $ADDONS_PATH,$ODOO_ADDONS_PATH data_dir = /var/lib/odoo ; admin_passwd = admin ; csv_internal_sep = , diff --git a/build/wait-for-psql.py b/build/wait-for-psql.py new file mode 100755 index 00000000..a55f4409 --- /dev/null +++ b/build/wait-for-psql.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +import argparse +import psycopg2 +import sys +import time + + +if __name__ == '__main__': + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('--db_host', required=True) + arg_parser.add_argument('--db_port', required=True) + arg_parser.add_argument('--db_user', required=True) + arg_parser.add_argument('--db_password', required=True) + arg_parser.add_argument('--timeout', type=int, default=5) + + args = arg_parser.parse_args() + + start_time = time.time() + while (time.time() - start_time) < args.timeout: + try: + conn = psycopg2.connect(user=args.db_user, host=args.db_host, port=args.db_port, password=args.db_password, dbname='postgres') + error = '' + break + except psycopg2.OperationalError as e: + error = e + else: + conn.close() + time.sleep(1) + + if error: + print("Database connection failure: %s" % error, file=sys.stderr) + sys.exit(1) diff --git a/docker-compose.yml b/docker-compose.yml index 72fbeddc..31df6b96 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,9 +13,10 @@ services: HOST: db USER: odoo PASSWORD: odoo + PORT: ${POSTGRES_PORT} ODOO_ADDONS_PATH: "${DOCKER_ADDONS_PATH}" ports: - - "127.0.0.1:8069:8069" + - "127.0.0.1:${ODOO_PORT}:${ODOO_PORT}" volumes: - odoo-data:/var/lib/odoo - ./addons:/mnt/addons @@ -39,7 +40,7 @@ services: container_name: db image: postgres:12-alpine ports: - - "127.0.0.1:5432:5432" + - "127.0.0.1:${POSTGRES_PORT}:${POSTGRES_PORT}" environment: POSTGRES_USER: odoo POSTGRES_PASSWORD: odoo diff --git a/enterprise b/enterprise index 3d236feb..47cc8bbe 160000 --- a/enterprise +++ b/enterprise @@ -1 +1 @@ -Subproject commit 3d236febeae41f337de2782ac487aa2b5778f603 +Subproject commit 47cc8bbed4f326d2eff14f072f62259a82a12d08 diff --git a/oca/web-api b/oca/web-api new file mode 160000 index 00000000..2330f243 --- /dev/null +++ b/oca/web-api @@ -0,0 +1 @@ +Subproject commit 2330f2432afe7090394d63b685cbe188c7ea3133 diff --git a/odoo b/odoo index e45456a2..391a4276 160000 --- a/odoo +++ b/odoo @@ -1 +1 @@ -Subproject commit e45456a266a199d6f465bc48b681a1eb6d991eda +Subproject commit 391a427620b6aec690481fe7c7d0b0326b95ee8c diff --git a/task b/task index 4e3ddbeb..8037a87c 100755 --- a/task +++ b/task @@ -19,9 +19,12 @@ fi PATH="$PATH:./odoo" GIT_BRANCH=$(git symbolic-ref --short -q HEAD) ODOO_REVISION=${ODOO_REVISION:="$GIT_BRANCH"} -ODOO_LANGUAGE=de_CH +ODOO_LANGUAGE=${ODOO_LANGUAGE:="de_CH"} ODOO_DEVELOPMENT_CONFIG_DIR="$HOME/.config/odoo-build" -DOCKER_TAG="odoo:$ODOO_REVISION" +DOCKER_TAG=${DOCKER_TAG:="odoo:${ODOO_REVISION}"} +ODOO_PORT=${ODOO_PORT:="8069"} +POSTGRES_PORT=${POSTGRES_PORT:="5432"} + if [ -z "${DOCKER_REGISTRY}" ]; then DOCKER_REGISTRY="" fi @@ -37,6 +40,20 @@ else BROWSER_OPEN="xdg-open" fi +function info() { + set-addons-path + echo "OS Release: $OS_RELEASE" + echo "Target Arch: $TARGETARCH" + echo "Git Branch: $GIT_BRANCH" + echo "Odoo Revision: $ODOO_REVISION" + echo "Odoo Port: $ODOO_PORT" + echo "Postgres Port: $POSTGRES_PORT" + echo "Odoo Language: $ODOO_LANGUAGE" + echo "Docker Registry: $DOCKER_REGISTRY" + echo "Docker Tag: $DOCKER_TAG" + echo "Addons Path: $ADDONS_PATH" +} + function set-addons-path() { # Read addons path list @@ -149,6 +166,12 @@ function build() { docker build . --build-arg TARGETARCH="$TARGETARCH" --build-arg ODOO_IMAGE="${DOCKER_REGISTRY}${DOCKER_TAG}" -t "${DOCKER_REGISTRY}${DOCKER_TAG}" } +function publish() { + echo "Push Docker iamge ${DOCKER_REGISTRY}${DOCKER_TAG}" + docker push "${DOCKER_REGISTRY}${DOCKER_TAG}" +} + + function install-odoo-scripts() { curl -L https://raw.githubusercontent.com/mint-system/ansible-build/master/roles/odoo_scripts/files/install | bash } @@ -214,8 +237,8 @@ function start() { set-addons-path # Exports for Docker Compose - export POSTGRES_USER=odoo - export POSTGRES_PASSWORD=odoo + export POSTGRES_PORT + export ODOO_PORT export DOCKER_TAG export DOCKER_ADDONS_PATH @@ -270,6 +293,12 @@ function deploy() { } function down() { + # Exports for Docker Compose + export POSTGRES_PORT + export ODOO_PORT + export DOCKER_TAG + export DOCKER_ADDONS_PATH + if test -z "$1"; then docker-compose down -v fi @@ -1011,11 +1040,11 @@ case "$1" in activate-venv) activate-venv ;; - disable-auto-install) - disable-auto-install + build) + build ;; - save-config) - save-config "$2" + change-uuid) + change-uuid "$2" ;; checkout) checkout "$2" "$3" @@ -1026,140 +1055,38 @@ case "$1" in checkout-revision) checkout-revision "$2" ;; - list) - docker-compose config --services; echo "native" - ;; - ps) - docker ps --format 'table {{.Names}}\t{{.Image}}\t{{(.Label "description")}}\t{{.Status}}' - ;; - start) - start "$2" "$3" - ;; - deploy) - deploy "$2" - ;; - restart) - restart "$2" - ;; - stop) - stop "$2" - ;; - kill) - down "$2" - ;; - logs) - docker logs odoo -f - ;; - build) - build - ;; - init-venv) - init-venv - ;; - install-odoo-scripts) - install-odoo-scripts - ;; - install-native) - install-native - ;; - init-db) - init-db "$2" - ;; - start-shell) - start-shell "$2" - ;; - start-psql) - start-psql "$2" - ;; - update-module) - update-module "$2" "$3" - ;; - test-module) - test-module "$2" "$3" - ;; - test-coverage-module) - test-coverage-module "$2" "$3" - ;; - create-module) - create-module "$2" - ;; - drop-db) - drop-db "$2" - ;; - send-support-mail) - send-support-mail - ;; clear-assets) clear-assets "$2" ;; - generate-admin-passwd) - generate-admin-passwd "$2" - ;; - odoo-cloc) - odoo-cloc "$2" - ;; - restore-database) - restore-database "$2" "$3" - ;; - convert-database) - convert-database "$2" - ;; - install-module) - install-module "$2" "$3" - ;; - remove-module) - remove-module "$2" "$3" - ;; - git-submodule-remove) - git-submodule-remove "$2" - ;; - git-submodule-add) - git-submodule-add "$2" "$3" - ;; - git-submodule-update) - git-submodule-update - ;; - release-module) - release-module "$2" - ;; - lint-module) - lint-module "$2" - ;; - update-readme) - update-readme "$2" - ;; - zip-module) - zip-module "$2" - ;; clear-filestore) clear-filestore "$2" ;; - init-odoo-env) - init-odoo-env "$2" + convert-database) + convert-database "$2" ;; - list-env) - ls -f "$ODOO_DEVELOPMENT_CONFIG_DIR" + create-module) + create-module "$2" ;; - list-addons) - list-addons + deploy) + deploy "$2" ;; - edit-env) - edit-env "$2" + disable-auto-install) + disable-auto-install ;; disable-mailserver) disable-mailserver "$2" ;; - change-uuid) - change-uuid "$2" + down) + down "$2" ;; - set-admin) - set-admin "$2" + drop-db) + drop-db "$2" ;; - git-submodule-switch) - git-submodule-switch "$2" + edit-env) + edit-env "$2" ;; - git-submodule-list) - git-submodule-list + generate-admin-passwd) + generate-admin-passwd "$2" ;; get-module-version) get-module-version "$2" @@ -1170,44 +1097,156 @@ case "$1" in git-mig-branch) git-mig-branch "$2" ;; - update-snippet) - update-snippet "$2" "$3" + git-submodule-add) + git-submodule-add "$2" "$3" ;; - test-jsonrpc) - test-jsonrpc "$2" - ;; - install-snippet) - install-snippet "$2" "$3" - ;; - lint-snippets) - lint-snippets - ;; - update-app-list) - update-app-list "$2" - ;; - init-nextcloud-env) - init-nextcloud-env "$2" - ;; - upload-module) - upload-module "$2" "$3" - ;; - translate-module) - translate-module "$2" "$3" "$4" - ;; - patch-database) - patch-database "$2" "$3" + git-submodule-list) + git-submodule-list ;; git-submodule-pull) git-submodule-pull ;; - update-docs) - update-docs + git-submodule-remove) + git-submodule-remove "$2" + ;; + git-submodule-switch) + git-submodule-switch "$2" + ;; + git-submodule-update) + git-submodule-update + ;; + help) + help task + exit 1 + ;; + info) + info + ;; + init-db) + init-db "$2" + ;; + init-nextcloud-env) + init-nextcloud-env "$2" + ;; + init-odoo-env) + init-odoo-env "$2" + ;; + init-venv) + init-venv + ;; + install-module) + install-module "$2" "$3" + ;; + install-native) + install-native + ;; + install-odoo-scripts) + install-odoo-scripts + ;; + install-snippet) + install-snippet "$2" "$3" + ;; + install-snippets) + install-snippets + ;; + install) + install + ;; + lint-module) + lint-module "$2" + ;; + lint-snippets) + lint-snippets + ;; + list-addons) + list-addons + ;; + list-env) + ls -f "$ODOO_DEVELOPMENT_CONFIG_DIR" + ;; + list) + docker-compose config --services; echo "native" + ;; + logs) + docker logs odoo -f + ;; + patch-database) + patch-database "$2" "$3" + ;; + publish) + publish + ;; + ps) + docker ps --format 'table {{.Names}}\t{{.Image}}\t{{(.Label "description")}}\t{{.Status}}' + ;; + release-module) + release-module "$2" + ;; + remove-module) + remove-module "$2" "$3" + ;; + reset-views) + reset-views "$2" "$3" + ;; + restart) + restart "$2" + ;; + restore-database) + restore-database "$2" "$3" + ;; + save-config) + save-config "$2" + ;; + send-support-mail) + send-support-mail + ;; + set-admin) + set-admin "$2" ;; source) activate-venv ;; - reset-views) - reset-views "$2" "$3" + start-psql) + start-psql "$2" + ;; + start-shell) + start-shell "$2" + ;; + start) + start "$2" "$3" + ;; + stop) + stop "$2" + ;; + test-coverage-module) + test-coverage-module "$2" "$3" + ;; + test-jsonrpc) + test-jsonrpc "$2" + ;; + test-module) + test-module "$2" "$3" + ;; + translate-module) + translate-module "$2" "$3" "$4" + ;; + update-app-list) + update-app-list "$2" + ;; + update-docs) + update-docs + ;; + update-module) + update-module "$2" "$3" + ;; + update-readme) + update-readme "$2" + ;; + update-snippet) + update-snippet "$2" "$3" + ;; + upload-module) + upload-module "$2" "$3" ;; *) help task diff --git a/task.md b/task.md index 8495a5b6..32dc6503 100644 --- a/task.md +++ b/task.md @@ -27,6 +27,7 @@ | git-submodule-remove | [path] | Remove git submodule. | | git-submodule-switch | [branch] | Switch branch for all submodules. | | git-submodule-update | | Update submodules from .gitmodules file. | +| info | | Show values of project env vars. | | init-db | [db] | Initialize the Odoo database. Default is branch name. | | init-nextcloud-env | [env] | Create env file for Nextcloud instance. | | init-odoo-env | [env] | Create env file for Odoo Instance. | @@ -44,6 +45,7 @@ | logs | | Tail Odoo Docker container logs. | | odoo-cloc | [db] | Count custom line of codes. Default is branch name. | | patch-database | [db][path] | Apply sql file to database. Default database is branch name. | +| publish | | Publish Odoo Docker image. | | ps | | List docker processes. | | release-module | [path] | Create GitHub release for a module. | | remove-module | [db][name] | Remove target Odoo module. |