Initial 18.0

This commit is contained in:
Jared Kipe
2024-10-06 06:37:30 -06:00
parent 6040b8490e
commit 4e60f0b990
13 changed files with 662 additions and 0 deletions

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
.git

101
.gitignore vendored Normal file
View File

@@ -0,0 +1,101 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/

83
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,83 @@
image: docker:stable
services:
- docker:dind
stages:
- build
- release
- trigger
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
CONTAINER_IMAGE: registry.gitlab.com/hibou-io/hibou-odoo/suite
DOCKERHUB_IMAGE: hibou/hibou-odoo-suite
GITLAB_BASE_URL: https://gitlab.com
ENTERPRISE_PROJECT_ID: 40326521
before_script:
- RELEASE=$(echo $CI_COMMIT_REF_NAME | sed "s{.*\/\(.*\)\/.*{\1{g")
- RELEASE_DATE="$(date '+%Y-%m-%d')"
- IMAGE_TAG=$(echo $CI_COMMIT_REF_SLUG | sed "s/^\([[:digit:]][[:digit:]]\)-\([[:digit:]]\)/\1\.\2/g")
- IMAGE_TAG_DATE="${IMAGE_TAG}-${RELEASE_DATE}"
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
merge_request:
variables:
GIT_STRATEGY: none
stage: build
only:
- /(^add\/)|(^new\/)|(^mig\/)|(^imp\/)|(^fix\/)/i
script:
- docker pull registry.gitlab.com/hibou-io/hibou-odoo/flow
- docker tag registry.gitlab.com/hibou-io/hibou-odoo/flow flow
- ENVS=`env | grep "CI_\|GITLAB_" | sed -n '/^[^\t]/s/=.*//p' | sed '/^$/d' | sed 's/^/-e /g' | tr '\n' ' '`
- docker run $ENVS flow gitlab-automerge --target-branch "${RELEASE}-test" --automerge
- docker run $ENVS flow gitlab-automerge --remove-source
build:
variables:
GIT_SUBMODULE_STRATEGY: recursive
stage: build
script:
- sed -i "s/RELEASE/$RELEASE/g" Dockerfile-GitLab
- docker build --pull -t $CONTAINER_IMAGE:$IMAGE_TAG -f Dockerfile-GitLab .
- docker push $CONTAINER_IMAGE:$IMAGE_TAG
release:
stage: release
variables:
GIT_STRATEGY: none
script:
- apk add python3
- docker pull registry.gitlab.com/hibou-io/hibou-odoo/flow
- docker tag registry.gitlab.com/hibou-io/hibou-odoo/flow flow
- docker run -v "${PWD}/.local:/dest" flow self-install /dest
- cd .local/flow
- ./entrypoint.sh docker-release $CONTAINER_IMAGE:$IMAGE_TAG $CONTAINER_IMAGE:$IMAGE_TAG_DATE
- docker login -u "${DOCKERHUB_USERNAME}" -p "${DOCKERHUB_PASSWORD}"
- docker tag $CONTAINER_IMAGE:$IMAGE_TAG $DOCKERHUB_IMAGE:$IMAGE_TAG
- docker push $DOCKERHUB_IMAGE:$IMAGE_TAG
- ./entrypoint.sh docker-release $DOCKERHUB_IMAGE:$IMAGE_TAG $DOCKERHUB_IMAGE:$IMAGE_TAG_DATE
only:
- /^\d+\.\d+$/
publish:
stage: build
script:
- docker pull registry.gitlab.com/hibou-io/hibou-odoo/flow
- docker tag registry.gitlab.com/hibou-io/hibou-odoo/flow flow
- ENVS=`env | grep "CI_\|GITLAB_" | sed -n '/^[^\t]/s/=.*//p' | sed '/^$/d' | sed 's/^/-e /g' | tr '\n' ' '`
- docker run -v $PWD:/src $ENVS flow odoo-publish -n "Hibou Odoo Suite" -v $RELEASE
only:
- /^\d\d\.\d+$/
trigger:
variables:
GIT_STRATEGY: none
stage: trigger
script:
- docker run byrnedo/alpine-curl curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=$RELEASE $GITLAB_BASE_URL/api/v4/projects/$ENTERPRISE_PROJECT_ID/trigger/pipeline
only:
- /^\d\d\.\d+/

120
.pylintrc Normal file
View File

@@ -0,0 +1,120 @@
[MASTER]
load-plugins=pylint_odoo
score=n
[ODOOLINT]
manifest_required_authors=Hibou Corp.
manifest_required_keys=license
manifest_deprecated_keys=description,active
license_allowed=OPL-1,AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
valid_odoo_versions=15.0
[MESSAGES CONTROL]
disable=all
# This .pylintrc contains optional AND mandatory checks and is meant to be
# loaded in an IDE to have it check everything, in the hope this will make
# optional checks more visible to contributors who otherwise never look at a
# green travis to see optional checks that failed.
# .pylintrc-mandatory containing only mandatory checks is used the pre-commit
# config as a blocking check.
enable=anomalous-backslash-in-string,
api-one-deprecated,
api-one-multi-together,
assignment-from-none,
attribute-deprecated,
class-camelcase,
dangerous-default-value,
dangerous-view-replace-wo-priority,
development-status-allowed,
duplicate-id-csv,
duplicate-key,
duplicate-xml-fields,
duplicate-xml-record-id,
eval-referenced,
eval-used,
incoherent-interpreter-exec-perm,
license-allowed,
manifest-author-string,
manifest-deprecated-key,
manifest-required-author,
manifest-required-key,
manifest-version-format,
method-compute,
method-inverse,
method-required-super,
method-search,
openerp-exception-warning,
pointless-statement,
pointless-string-statement,
print-used,
redundant-keyword-arg,
redundant-modulename-xml,
reimported,
relative-import,
return-in-init,
rst-syntax-error,
sql-injection,
too-few-format-args,
translation-field,
translation-required,
unreachable,
use-vim-comment,
wrong-tabs-instead-of-spaces,
xml-syntax-error,
attribute-string-redundant,
character-not-valid-in-resource-link,
consider-merging-classes-inherited,
context-overridden,
create-user-wo-reset-password,
dangerous-filter-wo-user,
dangerous-qweb-replace-wo-priority,
deprecated-data-xml-node,
deprecated-openerp-xml-node,
duplicate-po-message-definition,
except-pass,
file-not-used,
invalid-commit,
manifest-maintainers-list,
missing-newline-extrafiles,
missing-readme,
missing-return,
odoo-addons-relative-import,
old-api7-method-defined,
po-msgstr-variables,
po-syntax-error,
renamed-field-parameter,
resource-not-exist,
str-format-used,
test-folder-imported,
translation-contains-variable,
translation-positional-used,
unnecessary-utf8-coding-comment,
website-manifest-key-not-valid-uri,
xml-attribute-translatable,
xml-deprecated-qweb-directive,
xml-deprecated-tree-attribute,
# messages that do not cause the lint step to fail
consider-merging-classes-inherited,
create-user-wo-reset-password,
dangerous-filter-wo-user,
deprecated-module,
file-not-used,
invalid-commit,
missing-manifest-dependency,
missing-newline-extrafiles,
missing-readme,
no-utf8-coding-comment,
odoo-addons-relative-import,
old-api7-method-defined,
redefined-builtin,
too-complex,
unnecessary-utf8-coding-comment
[REPORTS]
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
output-format=colorized
reports=no

113
.theia/launch.json Normal file
View File

@@ -0,0 +1,113 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "Odoo: shell",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-run.py",
"args": ["shell", "--no-xmlrpc"],
"console": "integratedTerminal"
},
{
"name": "Odoo: TEST 'sale'",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-run.py",
"args": ["-i", "sale",
"-u", "sale",
"--test-enable", "--no-xmlrpc", "--stop-after-init"],
"console": "integratedTerminal"
},
{
"name": "Odoo: INIT 'hr_commission'",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-run.py",
"args": ["-i", "hr_commission",
"-u", "hr_commission",
"--stop-after-init"],
"console": "integratedTerminal"
},
{
"name": "Odoo: TEST 'hr_commission'",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-run.py",
"args": ["-i", "hr_commission",
"-u", "hr_commission",
"--test-enable", "--no-xmlrpc", "--stop-after-init"],
"console": "integratedTerminal"
},
{
"name": "Odoo: INIT 'hr_payroll_hibou'",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-run.py",
"args": ["-i", "hr_payroll_hibou",
"-u", "hr_payroll_hibou",
"--stop-after-init"],
"console": "integratedTerminal"
},
{
"name": "Odoo: TEST 'hr_payroll_hibou'",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-run.py",
"args": ["-i", "hr_payroll_hibou",
"-u", "hr_payroll_hibou",
"--test-enable", "--no-xmlrpc", "--stop-after-init"],
"console": "integratedTerminal"
},
{
"name": "Odoo: server",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-run.py",
"args": [],
"console": "integratedTerminal"
},
{
"name": "Odoo: Locust Load Testing",
"type": "python",
"request": "launch",
"program": "/flow/odoo/Locust/entrypoint.py",
"args": [
// -f /path/to/locustfiles.py
// -d more-specific-db
"--user", "admin",
"--pass", "admin",
"--host", "localhost",
"--port", "8069",
"--proto", "jsonrpc"
],
"console": "integratedTerminal"
},
{
"name": "Odoo: reload foreground server",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-reload.py",
"args": [],
"console": "integratedTerminal"
},
{
"name": "Odoo: reload foreground server, Kill Others",
"type": "python",
"request": "launch",
"program": "/opt/odoo/hibou-suite/odoo-reload.py",
"args": ["KILL_OTHER"],
"console": "integratedTerminal"
}
]
}

19
.theia/settings.json Normal file
View File

@@ -0,0 +1,19 @@
{
"workbench.colorTheme": "Hibou Dark",
"files.exclude": {
"**/.var": true,
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/*.pyc": {"when": "$(basename).py"},
"**/__pycache__": true
},
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true
},
"editor.enablePreview": false
}

15
COPYRIGHT Normal file
View File

@@ -0,0 +1,15 @@
Most of the files are
Copyright (c) 2016-2024 Hibou Corp.
Many files also contain contributions from third
parties. In this case the original copyright of
the contributions can be traced through the
history of the source version control system.
When that is not the case, the files contain a prominent
notice stating the original copyright and applicable
license, or come with their own dedicated COPYRIGHT
and/or LICENSE file.

10
Dockerfile Normal file
View File

@@ -0,0 +1,10 @@
FROM hibou/hibou-odoo:18.0
USER odoo
COPY --from=hibou/flow /flow /flow
COPY --chown=104 entrypoint.sh /entrypoint.sh
COPY --chown=104 . /opt/odoo/hibou-suite
RUN rm /etc/odoo/odoo.conf \
&& cp /opt/odoo/hibou-suite/debian/odoo.conf /etc/odoo/odoo.conf \
;

10
Dockerfile-GitLab Normal file
View File

@@ -0,0 +1,10 @@
FROM registry.gitlab.com/hibou-io/hibou-odoo/odoo:RELEASE
USER odoo
COPY --from=registry.gitlab.com/hibou-io/hibou-odoo/flow /flow /flow
COPY --chown=104 entrypoint.sh /entrypoint.sh
COPY --chown=104 . /opt/odoo/hibou-suite
RUN rm /etc/odoo/odoo.conf \
&& cp /opt/odoo/hibou-suite/debian/odoo.conf /etc/odoo/odoo.conf \
;

39
debian/odoo.conf vendored Normal file
View File

@@ -0,0 +1,39 @@
[options]
addons_path = /opt/odoo/hibou-suite,/opt/odoo/odoo/addons
; You can include more external modules by including them in the path, e.g.
; addons_path = /opt/odoo/hibou-suite,/opt/odoo/hibou-suite/external/hibou-oca/server-brand,/opt/odoo/odoo/addons
data_dir = /var/lib/odoo
; admin_passwd = admin
; csv_internal_sep = ,
; db_maxconn = 64
; db_name = False
; db_template = template1
; dbfilter = .*
; debug_mode = False
; email_from = False
; limit_memory_hard = 2684354560
; limit_memory_soft = 2147483648
; limit_request = 8192
; limit_time_cpu = 60
; limit_time_real = 120
; list_db = True
; log_db = False
; log_handler = [':INFO']
; log_level = info
; logfile = None
; longpolling_port = 8072
; max_cron_threads = 2
; osv_memory_age_limit = 1.0
; osv_memory_count_limit = False
; smtp_password = False
; smtp_port = 25
; smtp_server = localhost
; smtp_ssl = False
; smtp_user = False
; workers = 0
; xmlrpc = True
; xmlrpc_interface =
; xmlrpc_port = 8069
; xmlrpcs = True
; xmlrpcs_interface =
; xmlrpcs_port = 8071

104
entrypoint.sh Executable file
View File

@@ -0,0 +1,104 @@
#!/bin/bash
set -e
# DEV_MODE=exclusive
# Will start the Theia IDE in the foreground, you can then start Odoo from a terminal.
# DEV_MODE=1
# Will start the Theia IDE in the background, regular Odoo commands will still work.
# Note that in Theia you can re-start Odoo e.g.
# `kill -s SIGHUP 1` to reload/restart Odoo
# `kill -s SIGQUIT 1` to cause Odoo to dump stacktrace in standard out
# Note that with Odoo running in the foreground, killing Odoo will kill the container.
# DEV_MODE=
# Unset to not use Theia at all.
#
# DEV_MODE_PATH=/opt/odoo/addons
# To change the path to start Theia in, useful to get git working.
if [ "$DEV_MODE_PATH" != "" ] && [ -z "$(ls -A $DEV_MODE_PATH/.theia)" ]
then
cp -R /opt/odoo/hibou-suite/.theia $DEV_MODE_PATH || true
fi
if [ "$DEV_MODE_PATH" != "" ] && [ -z "$(ls -A $DEV_MODE_PATH/.pylintrc)" ]
then
cp -R /opt/odoo/hibou-suite/.pylintrc $DEV_MODE_PATH || true
fi
if [ "$DEV_MODE_PATH" == "" ]
then
export DEV_MODE_PATH=/opt/odoo/hibou-suite
fi
if [[ -x "/opt/athene/entrypoint.sh" ]]
then
/opt/athene/entrypoint.sh
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'}}}
DB_ARGS=()
function check_config() {
param="$1"
value="$2"
if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then
value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g')
fi;
DB_ARGS+=("--${param}")
DB_ARGS+=("${value}")
}
check_config "db_host" "$HOST"
check_config "db_port" "$PORT"
check_config "db_user" "$USER"
check_config "db_password" "$PASSWORD"
case "$1" in
flow)
shift
wait-for-psql.py ${DB_ARGS[@]} --timeout=60
: ${DB_NAME:='odoo'}
: ${DATA_DIR:='/var/lib/odoo'}
check_config "db_name" "$DB_NAME"
check_config "data_dir" "$DATA_DIR"
cd /flow
FLOW_ARGS=()
CONTINUE="1"
while [[ "$#" && $CONTINUE ]]; do
# We want the -- shifted, but not in the FLOW_ARGS
if [[ "$1" == "--" ]]; then
CONTINUE=""
shift
fi
if [[ "$1" && $CONTINUE ]]; then
FLOW_ARGS+=("$1")
shift
else
# if we shift too many times we exit...
CONTINUE=""
fi
done
/flow/entrypoint.sh ${FLOW_ARGS[@]} ${DB_ARGS[@]}
exec /entrypoint.sh "$@"
;;
-- | odoo)
shift
if [[ "$1" == "scaffold" ]] ; then
exec odoo "$@"
else
wait-for-psql.py ${DB_ARGS[@]} --timeout=30
exec odoo "$@" "${DB_ARGS[@]}"
fi
;;
-*)
wait-for-psql.py ${DB_ARGS[@]} --timeout=30
exec odoo "$@" "${DB_ARGS[@]}"
;;
*)
exec "$@"
esac
# notably do not exit 1 as we can complete a job like a backup

42
odoo-reload.py Executable file
View File

@@ -0,0 +1,42 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
import psutil
import os
import signal
import sys
# once upon a time
# we tried to find 'odoo' and 'python'
# but sometimes, it would be something like "/usr/local/bin/...."
# so we now just try not to signal/kill 'node'
PID = 1
PNAME = 'node'
KILL_OTHER = sys.argv[1] == 'KILL_OTHER' if len(sys.argv) >= 2 else False
if KILL_OTHER:
print('Will find other Odoo Processes and Kill them.')
is_foreground = False
foreground_name = ''
for proc in psutil.process_iter():
try:
process_name = proc.name()
process_id = proc.pid
print('Inspecting %s:%s' % (process_id, process_name))
if process_id == PID:
is_foreground = process_name != PNAME
foreground_name = process_name
if not KILL_OTHER:
break
if process_id != PID and KILL_OTHER and process_name != PNAME:
print('Killing %s:%s' % (process_id, process_name))
os.kill(process_id, signal.SIGKILL)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
if not is_foreground:
print('Odoo is not the foreground process.')
exit(-1)
print('Signalling reload to foreground process "%s"' % (foreground_name, ))
os.kill(PID, signal.SIGHUP)

5
odoo-run.py Executable file
View File

@@ -0,0 +1,5 @@
__import__('os').environ['TZ'] = 'UTC'
import odoo
if __name__ == "__main__":
odoo.cli.main()