The 0k dev-pack's compose script doesn't handle absolute paths correctly.
It passes HOST_COMPOSE_YML_FILE to the container, which tries to open
it directly instead of using the mounted path.
Add run_compose() wrapper that changes to PROJECT_ROOT before calling
compose with a relative path, ensuring consistent behavior regardless
of the current working directory.
Replace cd into version directories with absolute path execution:
Before:
cd "${version}.0"
./pre_upgrade.sh
./upgrade.sh
./post_upgrade.sh
cd ..
After:
"${SCRIPT_DIR}/${version}.0/pre_upgrade.sh"
"${SCRIPT_DIR}/${version}.0/upgrade.sh"
"${SCRIPT_DIR}/${version}.0/post_upgrade.sh"
Benefits:
- No working directory state to track
- More robust: script works regardless of where it's called from
- Easier debugging: no need to remember current directory
- Avoids potential issues if a subscript changes directory
Replace $FINALE_DB_MODEL_NAME with $FINALE_DB_NAME in the call to
prepare_db.sh.
FINALE_DB_MODEL_NAME was never defined anywhere in the codebase,
causing the script to fail immediately with 'set -u' (unbound variable
error). The intended variable is FINALE_DB_NAME which contains the
target database name (e.g., 'ou16').
Replace manual loop building version array with seq + readarray:
Before (4 lines):
declare -a versions
nb_migrations=$((FINAL_VERSION - ORIGIN_VERSION))
for ((i = 0; i < nb_migrations; i++)); do
versions[i]=$((ORIGIN_VERSION + 1 + i))
done
After (1 line):
readarray -t versions < <(seq $((ORIGIN_VERSION + 1)) "$FINAL_VERSION")
The seq command is purpose-built for generating number sequences,
making the intent clearer and the code more concise.
Replace double grep pattern with readarray for cleaner container detection:
- Single grep call instead of two
- Native bash array instead of string manipulation
- Array length check instead of grep -c
- Proper formatting when listing multiple containers
The readarray approach is more idiomatic and avoids edge cases with
empty strings and newline handling.
Add check_required_commands() function to verify that all required
external tools are available before the script begins execution:
- docker: Container runtime
- compose: Docker compose wrapper (0k-scripts)
- sudo: Required for filestore operations
Benefits:
- Fails fast with a clear error message listing missing commands
- Prevents cryptic 'command not found' errors mid-execution
- Documents script dependencies explicitly
- Called immediately after argument validation in upgrade.sh
Apply consistent naming conventions throughout upgrade.sh:
- UPPERCASE + readonly for script-level constants (immutable values)
- lowercase for temporary/local variables within the script flow
Constants marked readonly:
- ORIGIN_VERSION, FINAL_VERSION, ORIGIN_DB_NAME, ORIGIN_SERVICE_NAME
- COPY_DB_NAME, FINALE_DB_NAME, FINALE_SERVICE_NAME
- POSTGRES_SERVICE_NAME
Local variables renamed to lowercase:
- postgres_containers, postgres_count (detection phase)
- db_exists, filestore_path (validation phase)
This convention makes it immediately clear which variables are
configuration constants vs runtime values, and prevents accidental
modification of critical values.
Add logging functions to lib/common.sh for consistent output formatting:
- log_info(): Standard informational messages with [INFO] prefix
- log_warn(): Warning messages to stderr with [WARN] prefix
- log_error(): Error messages to stderr with [ERROR] prefix
- log_step(): Section headers with visual separators
Update upgrade.sh to use these functions throughout, replacing ad-hoc
echo statements. This provides:
- Consistent visual formatting across all scripts
- Clear distinction between info, warnings and errors
- Errors properly sent to stderr
- Easier log parsing and filtering
Also removed redundant '|| exit 1' statements since set -e handles
command failures automatically.
Extract shared utility functions into a dedicated library file:
- query_postgres_container: Execute SQL queries in postgres container
- copy_database: Copy database using pgm
- copy_filestore: Copy Odoo filestore directory
- exec_python_script_in_odoo_shell: Run Python scripts in Odoo shell
Benefits:
- Single source of truth for utility functions
- Easier maintenance and testing
- Consistent behavior across all scripts
- Reduced code duplication
Also introduces readonly constants DATASTORE_PATH and FILESTORE_SUBPATH
to avoid hardcoded paths scattered throughout the codebase.
Replace single bracket [ ] with double bracket [[ ]] for all test
conditionals in the main scripts.
Benefits of [[ over [:
- No need to quote variables (though we still do for consistency)
- Supports regex matching with =~
- Supports pattern matching with == and !=
- && and || work inside [[ ]] without escaping
- More predictable behavior with empty strings
- Is a bash keyword, not an external command
Note: posbox scripts are left unchanged as they appear to be
third-party code imported into the repository.
Properly quote all variable expansions to prevent word splitting and
glob expansion issues:
- Quote $POSTGRES_SERVICE_NAME in docker exec command
- Quote $REPERTOIRE in directory test
- Remove unnecessary $ inside arithmetic expressions (($VAR -> VAR))
Unquoted variables can cause unexpected behavior when values contain
spaces or special characters. In arithmetic contexts, $ is unnecessary
and can mask errors with set -u.
Add proper argument validation at the start of upgrade.sh:
- Check that exactly 4 arguments are provided
- Display a helpful usage message with argument descriptions
- Include a concrete example command
This prevents cryptic errors when the script is called incorrectly
and provides clear guidance on expected parameters. With set -u enabled,
accessing unset positional parameters would cause an unclear error message.
Enable bash strict mode in all shell scripts to catch errors early:
- set -e: Exit immediately if a command exits with non-zero status
- set -u: Treat unset variables as an error
- set -o pipefail: Return value of a pipeline is the status of the last
command to exit with non-zero status
This prevents silent failures and makes debugging easier by failing fast
when something goes wrong instead of continuing with potentially corrupted
state.