odoo-devops-tools 1.23.0__tar.gz → 1.23.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/PKG-INFO +55 -9
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/README.md +54 -8
- odoo_devops_tools-1.23.2/odoo_devops_tools/__init__.py +1 -0
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools/env.py +171 -12
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/PKG-INFO +55 -9
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/pyproject.toml +1 -1
- odoo_devops_tools-1.23.0/odoo_devops_tools/__init__.py +0 -1
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/LICENSE +0 -0
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/SOURCES.txt +0 -0
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/dependency_links.txt +0 -0
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/entry_points.txt +0 -0
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/top_level.txt +0 -0
- {odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: odoo-devops-tools
|
|
3
|
-
Version: 1.23.
|
|
3
|
+
Version: 1.23.2
|
|
4
4
|
Summary: Build reproducible Odoo workspaces from a single project definition.
|
|
5
5
|
Author: Roman Lacko
|
|
6
6
|
License-Expression: MIT
|
|
@@ -120,7 +120,7 @@ Choose the workflow that fits your environment. Both use the same `odoo-project.
|
|
|
120
120
|
Create a new workspace:
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
odoo-compose --init
|
|
123
|
+
odoo-compose --init ./odoo19
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
Start the Docker Compose environment:
|
|
@@ -238,6 +238,7 @@ On Unix-like systems:
|
|
|
238
238
|
docker/local/scripts/
|
|
239
239
|
├── backup-db.sh
|
|
240
240
|
├── restore-db.sh
|
|
241
|
+
├── neutralize-db.sh
|
|
241
242
|
├── backup-filestore.sh
|
|
242
243
|
├── restore-filestore.sh
|
|
243
244
|
├── restic.sh
|
|
@@ -281,6 +282,21 @@ Restore a database dump with `pg_restore`:
|
|
|
281
282
|
./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
|
|
282
283
|
```
|
|
283
284
|
|
|
285
|
+
Database restores use copy semantics by default, matching `click-odoo-restoredb --copy`.
|
|
286
|
+
After `pg_restore`, Odoo database identity parameters are regenerated so the restored
|
|
287
|
+
database can coexist with the source database:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
./docker/local/scripts/restore-db.sh --copy ./odoo-backups/pre-upgrade.dump
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Use `--move` only when the restored database replaces the original database and its
|
|
294
|
+
identity must be preserved:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
./docker/local/scripts/restore-db.sh --move ./odoo-backups/pre-upgrade.dump
|
|
298
|
+
```
|
|
299
|
+
|
|
284
300
|
If the target database already exists, the restore is rejected unless `--force` is used. With `--force`, the existing database is dropped and recreated before the dump is restored. When restoring the database currently used by the Odoo service, stop Odoo first and start it again after the restore:
|
|
285
301
|
|
|
286
302
|
```bash
|
|
@@ -295,7 +311,37 @@ To restore the same dump into another database without replacing the default dat
|
|
|
295
311
|
ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
|
|
296
312
|
```
|
|
297
313
|
|
|
298
|
-
#### 1.3.3.
|
|
314
|
+
#### 1.3.3. Database neutralization
|
|
315
|
+
|
|
316
|
+
For development or test databases restored from production, run the generated neutralization helper explicitly:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
./docker/local/scripts/neutralize-db.sh
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Override the target database with `ODOO_DB_NAME` when needed:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
ODOO_DB_NAME=odoo_test ./docker/local/scripts/neutralize-db.sh
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
For Odoo 16.0 and newer, the helper uses Odoo's native database neutralization mechanism. This applies the `neutralize.sql` scripts provided by installed Odoo modules, disabling or redirecting production-side effects such as scheduled actions, outgoing email, and supported external integrations.
|
|
329
|
+
|
|
330
|
+
For Odoo 13.0 through 15.0, where the native neutralization framework is not available, the helper applies a deliberately minimal compatibility neutralization through the Odoo ORM: it disables scheduled actions, configured outgoing mail servers, and configured incoming mail servers.
|
|
331
|
+
|
|
332
|
+
Neutralization is intentionally separate from database restore. A typical test/staging restore workflow is therefore:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
docker compose stop odoo
|
|
336
|
+
./docker/local/scripts/restore-db.sh --copy ./odoo-backups/production.dump
|
|
337
|
+
./docker/local/scripts/restore-filestore.sh ./odoo-backups/production-filestore.tar.gz
|
|
338
|
+
./docker/local/scripts/neutralize-db.sh
|
|
339
|
+
docker compose up -d odoo
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
`--copy` / `--move` and neutralization serve different purposes: copy/move controls restored database identity, while neutralization controls production side effects.
|
|
343
|
+
|
|
344
|
+
#### 1.3.4. Filestore backup
|
|
299
345
|
|
|
300
346
|
Create a compressed tar archive of the selected database filestore:
|
|
301
347
|
|
|
@@ -326,7 +372,7 @@ docker compose stop odoo
|
|
|
326
372
|
docker compose up -d odoo
|
|
327
373
|
```
|
|
328
374
|
|
|
329
|
-
#### 1.3.
|
|
375
|
+
#### 1.3.5. Filestore restore
|
|
330
376
|
|
|
331
377
|
Restore a filestore archive:
|
|
332
378
|
|
|
@@ -350,7 +396,7 @@ ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-filestore.sh ./odoo-bac
|
|
|
350
396
|
|
|
351
397
|
Database and filestore backups are intentionally separate. This allows either part to be restored independently while still making it possible to create matching database and filestore backups when both are needed.
|
|
352
398
|
|
|
353
|
-
#### 1.3.
|
|
399
|
+
#### 1.3.6. Restic filestore backup
|
|
354
400
|
|
|
355
401
|
The generated Docker image also includes `restic`. Restic is an additional option intended especially for large filestores where incremental snapshots and deduplication are useful.
|
|
356
402
|
|
|
@@ -398,7 +444,7 @@ List or inspect snapshots through the generic wrapper:
|
|
|
398
444
|
./docker/local/scripts/restic.sh check
|
|
399
445
|
```
|
|
400
446
|
|
|
401
|
-
#### 1.3.
|
|
447
|
+
#### 1.3.7. Restic filestore restore
|
|
402
448
|
|
|
403
449
|
Restore the latest matching filestore snapshot:
|
|
404
450
|
|
|
@@ -468,7 +514,7 @@ In this workflow, Odoo runs directly on the host using a generated Python virtua
|
|
|
468
514
|
Create the workspace with the Odoo source and virtual environment:
|
|
469
515
|
|
|
470
516
|
```bash
|
|
471
|
-
odoo-compose --init
|
|
517
|
+
odoo-compose --init ./odoo19 --sync-all --create-venv \
|
|
472
518
|
--set config:db_host=127.0.0.1 \
|
|
473
519
|
--set config:db_name=odoo \
|
|
474
520
|
--set config:db_user=odoo \
|
|
@@ -906,7 +952,7 @@ The merged project file is saved as `ROOT/odoo-project.ini`, replacing any exist
|
|
|
906
952
|
### Paths and outputs
|
|
907
953
|
|
|
908
954
|
- `--root ROOT` — workspace root directory. Default: the directory containing a local INI file, or the current working directory for a remote INI or omitted INI. In include mode, the default is the directory of the first local source, or the current working directory when the first source is remote.
|
|
909
|
-
- `--init
|
|
955
|
+
- `--init [ROOT]` — create `ROOT/odoo-project.ini` from the bundled default template if it does not already exist. `ROOT` is optional; when supplied, it is a shorthand for selecting the workspace root directly, for example `odoo-compose --init ./odoo19`. When the optional value is omitted, `--root ROOT` remains supported for backward compatibility. Do not supply both `--init ROOT` and `--root ROOT`; the command exits with an error instead of choosing one implicitly. This option is valid only when `INI` is omitted and no `-i/--include` is provided. Existing project files are not overwritten.
|
|
910
956
|
- `--include INI`, `-i INI` — include an additional project INI layer; can be repeated. Later layers override earlier layers.
|
|
911
957
|
- `--extra-var KEY=VALUE`, `-e KEY=VALUE` — override or inject a value in the optional `[vars]` section; can be repeated.
|
|
912
958
|
- `--set SECTION:KEY=VALUE`, `-S SECTION:KEY=VALUE` — set or override a supported project option; can be repeated. Missing supported sections/options are created automatically. Structured sections (`[virtualenv]`, `[odoo]`, `[addons.<name>]`, and `[docker]`) accept only documented keys; `[config]` remains open to standard Odoo configuration options except `addons_path`.
|
|
@@ -977,7 +1023,7 @@ The following sections are supported:
|
|
|
977
1023
|
|
|
978
1024
|
### General rules
|
|
979
1025
|
|
|
980
|
-
- The project file can have any filename when passed explicitly. When `INI` is omitted, `odoo-compose` uses the existing `ROOT/odoo-project.ini`; if it is missing, use `--init
|
|
1026
|
+
- The project file can have any filename when passed explicitly. When `INI` is omitted, `odoo-compose` uses the existing `ROOT/odoo-project.ini`; if it is missing, use `--init` to create it explicitly from the bundled default template. Remote INI sources and merged include layers are materialized as `ROOT/odoo-project.ini`.
|
|
981
1027
|
- INI interpolation is supported, so values such as `${odoo:version}` can be reused across sections.
|
|
982
1028
|
- Multiple INI layers can be composed with `-i/--include`. Later layers override earlier layers; multi-line values are replaced as whole option values, not appended.
|
|
983
1029
|
- The optional `[vars]` section is useful for reusable values referenced as `${vars:name}`.
|
|
@@ -92,7 +92,7 @@ Choose the workflow that fits your environment. Both use the same `odoo-project.
|
|
|
92
92
|
Create a new workspace:
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
|
-
odoo-compose --init
|
|
95
|
+
odoo-compose --init ./odoo19
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
Start the Docker Compose environment:
|
|
@@ -210,6 +210,7 @@ On Unix-like systems:
|
|
|
210
210
|
docker/local/scripts/
|
|
211
211
|
├── backup-db.sh
|
|
212
212
|
├── restore-db.sh
|
|
213
|
+
├── neutralize-db.sh
|
|
213
214
|
├── backup-filestore.sh
|
|
214
215
|
├── restore-filestore.sh
|
|
215
216
|
├── restic.sh
|
|
@@ -253,6 +254,21 @@ Restore a database dump with `pg_restore`:
|
|
|
253
254
|
./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
|
|
254
255
|
```
|
|
255
256
|
|
|
257
|
+
Database restores use copy semantics by default, matching `click-odoo-restoredb --copy`.
|
|
258
|
+
After `pg_restore`, Odoo database identity parameters are regenerated so the restored
|
|
259
|
+
database can coexist with the source database:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
./docker/local/scripts/restore-db.sh --copy ./odoo-backups/pre-upgrade.dump
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Use `--move` only when the restored database replaces the original database and its
|
|
266
|
+
identity must be preserved:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
./docker/local/scripts/restore-db.sh --move ./odoo-backups/pre-upgrade.dump
|
|
270
|
+
```
|
|
271
|
+
|
|
256
272
|
If the target database already exists, the restore is rejected unless `--force` is used. With `--force`, the existing database is dropped and recreated before the dump is restored. When restoring the database currently used by the Odoo service, stop Odoo first and start it again after the restore:
|
|
257
273
|
|
|
258
274
|
```bash
|
|
@@ -267,7 +283,37 @@ To restore the same dump into another database without replacing the default dat
|
|
|
267
283
|
ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
|
|
268
284
|
```
|
|
269
285
|
|
|
270
|
-
#### 1.3.3.
|
|
286
|
+
#### 1.3.3. Database neutralization
|
|
287
|
+
|
|
288
|
+
For development or test databases restored from production, run the generated neutralization helper explicitly:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
./docker/local/scripts/neutralize-db.sh
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Override the target database with `ODOO_DB_NAME` when needed:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
ODOO_DB_NAME=odoo_test ./docker/local/scripts/neutralize-db.sh
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
For Odoo 16.0 and newer, the helper uses Odoo's native database neutralization mechanism. This applies the `neutralize.sql` scripts provided by installed Odoo modules, disabling or redirecting production-side effects such as scheduled actions, outgoing email, and supported external integrations.
|
|
301
|
+
|
|
302
|
+
For Odoo 13.0 through 15.0, where the native neutralization framework is not available, the helper applies a deliberately minimal compatibility neutralization through the Odoo ORM: it disables scheduled actions, configured outgoing mail servers, and configured incoming mail servers.
|
|
303
|
+
|
|
304
|
+
Neutralization is intentionally separate from database restore. A typical test/staging restore workflow is therefore:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
docker compose stop odoo
|
|
308
|
+
./docker/local/scripts/restore-db.sh --copy ./odoo-backups/production.dump
|
|
309
|
+
./docker/local/scripts/restore-filestore.sh ./odoo-backups/production-filestore.tar.gz
|
|
310
|
+
./docker/local/scripts/neutralize-db.sh
|
|
311
|
+
docker compose up -d odoo
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
`--copy` / `--move` and neutralization serve different purposes: copy/move controls restored database identity, while neutralization controls production side effects.
|
|
315
|
+
|
|
316
|
+
#### 1.3.4. Filestore backup
|
|
271
317
|
|
|
272
318
|
Create a compressed tar archive of the selected database filestore:
|
|
273
319
|
|
|
@@ -298,7 +344,7 @@ docker compose stop odoo
|
|
|
298
344
|
docker compose up -d odoo
|
|
299
345
|
```
|
|
300
346
|
|
|
301
|
-
#### 1.3.
|
|
347
|
+
#### 1.3.5. Filestore restore
|
|
302
348
|
|
|
303
349
|
Restore a filestore archive:
|
|
304
350
|
|
|
@@ -322,7 +368,7 @@ ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-filestore.sh ./odoo-bac
|
|
|
322
368
|
|
|
323
369
|
Database and filestore backups are intentionally separate. This allows either part to be restored independently while still making it possible to create matching database and filestore backups when both are needed.
|
|
324
370
|
|
|
325
|
-
#### 1.3.
|
|
371
|
+
#### 1.3.6. Restic filestore backup
|
|
326
372
|
|
|
327
373
|
The generated Docker image also includes `restic`. Restic is an additional option intended especially for large filestores where incremental snapshots and deduplication are useful.
|
|
328
374
|
|
|
@@ -370,7 +416,7 @@ List or inspect snapshots through the generic wrapper:
|
|
|
370
416
|
./docker/local/scripts/restic.sh check
|
|
371
417
|
```
|
|
372
418
|
|
|
373
|
-
#### 1.3.
|
|
419
|
+
#### 1.3.7. Restic filestore restore
|
|
374
420
|
|
|
375
421
|
Restore the latest matching filestore snapshot:
|
|
376
422
|
|
|
@@ -440,7 +486,7 @@ In this workflow, Odoo runs directly on the host using a generated Python virtua
|
|
|
440
486
|
Create the workspace with the Odoo source and virtual environment:
|
|
441
487
|
|
|
442
488
|
```bash
|
|
443
|
-
odoo-compose --init
|
|
489
|
+
odoo-compose --init ./odoo19 --sync-all --create-venv \
|
|
444
490
|
--set config:db_host=127.0.0.1 \
|
|
445
491
|
--set config:db_name=odoo \
|
|
446
492
|
--set config:db_user=odoo \
|
|
@@ -878,7 +924,7 @@ The merged project file is saved as `ROOT/odoo-project.ini`, replacing any exist
|
|
|
878
924
|
### Paths and outputs
|
|
879
925
|
|
|
880
926
|
- `--root ROOT` — workspace root directory. Default: the directory containing a local INI file, or the current working directory for a remote INI or omitted INI. In include mode, the default is the directory of the first local source, or the current working directory when the first source is remote.
|
|
881
|
-
- `--init
|
|
927
|
+
- `--init [ROOT]` — create `ROOT/odoo-project.ini` from the bundled default template if it does not already exist. `ROOT` is optional; when supplied, it is a shorthand for selecting the workspace root directly, for example `odoo-compose --init ./odoo19`. When the optional value is omitted, `--root ROOT` remains supported for backward compatibility. Do not supply both `--init ROOT` and `--root ROOT`; the command exits with an error instead of choosing one implicitly. This option is valid only when `INI` is omitted and no `-i/--include` is provided. Existing project files are not overwritten.
|
|
882
928
|
- `--include INI`, `-i INI` — include an additional project INI layer; can be repeated. Later layers override earlier layers.
|
|
883
929
|
- `--extra-var KEY=VALUE`, `-e KEY=VALUE` — override or inject a value in the optional `[vars]` section; can be repeated.
|
|
884
930
|
- `--set SECTION:KEY=VALUE`, `-S SECTION:KEY=VALUE` — set or override a supported project option; can be repeated. Missing supported sections/options are created automatically. Structured sections (`[virtualenv]`, `[odoo]`, `[addons.<name>]`, and `[docker]`) accept only documented keys; `[config]` remains open to standard Odoo configuration options except `addons_path`.
|
|
@@ -949,7 +995,7 @@ The following sections are supported:
|
|
|
949
995
|
|
|
950
996
|
### General rules
|
|
951
997
|
|
|
952
|
-
- The project file can have any filename when passed explicitly. When `INI` is omitted, `odoo-compose` uses the existing `ROOT/odoo-project.ini`; if it is missing, use `--init
|
|
998
|
+
- The project file can have any filename when passed explicitly. When `INI` is omitted, `odoo-compose` uses the existing `ROOT/odoo-project.ini`; if it is missing, use `--init` to create it explicitly from the bundled default template. Remote INI sources and merged include layers are materialized as `ROOT/odoo-project.ini`.
|
|
953
999
|
- INI interpolation is supported, so values such as `${odoo:version}` can be reused across sections.
|
|
954
1000
|
- Multiple INI layers can be composed with `-i/--include`. Later layers override earlier layers; multi-line values are replaced as whole option values, not appended.
|
|
955
1001
|
- The optional `[vars]` section is useful for reusable values referenced as `${vars:name}`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.23.2"
|
|
@@ -3024,10 +3024,11 @@ ROOT_DIR="$(cd "${{SCRIPT_DIR}}/../../.." && pwd)"
|
|
|
3024
3024
|
DEFAULT_DB_NAME={default_db_name}
|
|
3025
3025
|
DB_NAME="${{ODOO_DB_NAME:-${{DEFAULT_DB_NAME}}}}"
|
|
3026
3026
|
FORCE=false
|
|
3027
|
+
RESTORE_MODE=copy
|
|
3027
3028
|
SOURCE=""
|
|
3028
3029
|
|
|
3029
3030
|
usage() {{
|
|
3030
|
-
echo "Usage: $(basename "$0") [--force] BACKUP.dump" >&2
|
|
3031
|
+
echo "Usage: $(basename "$0") [--force] [--copy|--move] BACKUP.dump" >&2
|
|
3031
3032
|
}}
|
|
3032
3033
|
|
|
3033
3034
|
while [[ $# -gt 0 ]]; do
|
|
@@ -3035,6 +3036,12 @@ while [[ $# -gt 0 ]]; do
|
|
|
3035
3036
|
--force)
|
|
3036
3037
|
FORCE=true
|
|
3037
3038
|
;;
|
|
3039
|
+
--copy)
|
|
3040
|
+
RESTORE_MODE=copy
|
|
3041
|
+
;;
|
|
3042
|
+
--move)
|
|
3043
|
+
RESTORE_MODE=move
|
|
3044
|
+
;;
|
|
3038
3045
|
-*)
|
|
3039
3046
|
echo "ERROR: unknown option: $1" >&2
|
|
3040
3047
|
usage
|
|
@@ -3086,11 +3093,86 @@ docker compose exec -T db \
|
|
|
3086
3093
|
pg_restore --exit-on-error --no-owner --no-acl -U odoo -d "${{DB_NAME}}" \
|
|
3087
3094
|
< "${{SOURCE}}"
|
|
3088
3095
|
|
|
3096
|
+
if [[ "${{RESTORE_MODE}}" == "copy" ]]; then
|
|
3097
|
+
echo "INFO: Resetting copied Odoo database identity for '${{DB_NAME}}'."
|
|
3098
|
+
printf '%s\n' 'env["ir.config_parameter"].init(force=True)' | \
|
|
3099
|
+
docker compose run --rm --no-deps -T \
|
|
3100
|
+
--entrypoint click-odoo odoo \
|
|
3101
|
+
-c /etc/odoo/odoo.conf \
|
|
3102
|
+
-d "${{DB_NAME}}" \
|
|
3103
|
+
--log-level=error
|
|
3104
|
+
|
|
3105
|
+
docker compose exec -T db \
|
|
3106
|
+
psql -v ON_ERROR_STOP=1 -U odoo -d "${{DB_NAME}}" <<'SQL'
|
|
3107
|
+
DELETE FROM ir_config_parameter
|
|
3108
|
+
WHERE key = 'database.enterprise_code';
|
|
3109
|
+
|
|
3110
|
+
UPDATE ir_config_parameter
|
|
3111
|
+
SET value = 'copy'
|
|
3112
|
+
WHERE key = 'database.expiration_reason'
|
|
3113
|
+
AND value != 'demo';
|
|
3114
|
+
|
|
3115
|
+
UPDATE ir_config_parameter
|
|
3116
|
+
SET value = CURRENT_DATE + INTERVAL '2 month'
|
|
3117
|
+
WHERE key = 'database.expiration_date';
|
|
3118
|
+
SQL
|
|
3119
|
+
else
|
|
3120
|
+
echo "INFO: Preserving Odoo database identity (--move)."
|
|
3121
|
+
fi
|
|
3122
|
+
|
|
3089
3123
|
echo "INFO: Database restore completed: ${{DB_NAME}}"
|
|
3090
3124
|
"""
|
|
3091
3125
|
return _write_docker_local_script(layout, "restore-db", content)
|
|
3092
3126
|
|
|
3093
3127
|
|
|
3128
|
+
def write_docker_neutralize_db_sh(layout: Layout, cfg: ProjectConfig) -> Path:
|
|
3129
|
+
default_db_name = shlex.quote(_docker_default_db_name(cfg))
|
|
3130
|
+
odoo_major_version = _parse_odoo_version(cfg.odoo.version)
|
|
3131
|
+
if odoo_major_version >= 16:
|
|
3132
|
+
neutralize_command = rf"""
|
|
3133
|
+
echo "INFO: Using native Odoo neutralization for Odoo {odoo_major_version}. "
|
|
3134
|
+
docker compose run --rm --no-deps -T \
|
|
3135
|
+
--entrypoint odoo odoo \
|
|
3136
|
+
neutralize \
|
|
3137
|
+
-c /etc/odoo/odoo.conf \
|
|
3138
|
+
-d "${{DB_NAME}}"
|
|
3139
|
+
"""
|
|
3140
|
+
else:
|
|
3141
|
+
neutralize_command = rf"""
|
|
3142
|
+
echo "INFO: Using legacy minimal neutralization for Odoo {odoo_major_version}."
|
|
3143
|
+
printf '%s\n' \
|
|
3144
|
+
'[(model.search([("active", "=", True)]).write({{"active": False}})) for model_name in ("ir.cron", "ir.mail_server", "fetchmail.server") if model_name in env for model in (env[model_name],) if "active" in model._fields]; env.cr.commit()' | \
|
|
3145
|
+
docker compose run --rm --no-deps -T \
|
|
3146
|
+
--entrypoint click-odoo odoo \
|
|
3147
|
+
-c /etc/odoo/odoo.conf \
|
|
3148
|
+
-d "${{DB_NAME}}" \
|
|
3149
|
+
--log-level=error
|
|
3150
|
+
"""
|
|
3151
|
+
|
|
3152
|
+
content = fr"""#!/usr/bin/env bash
|
|
3153
|
+
set -euo pipefail
|
|
3154
|
+
|
|
3155
|
+
SCRIPT_DIR="$(cd "$(dirname "${{BASH_SOURCE[0]}}")" && pwd)"
|
|
3156
|
+
ROOT_DIR="$(cd "${{SCRIPT_DIR}}/../../.." && pwd)"
|
|
3157
|
+
DEFAULT_DB_NAME={default_db_name}
|
|
3158
|
+
DB_NAME="${{ODOO_DB_NAME:-${{DEFAULT_DB_NAME}}}}"
|
|
3159
|
+
|
|
3160
|
+
cd "${{ROOT_DIR}}"
|
|
3161
|
+
|
|
3162
|
+
DATABASES="$(docker compose exec -T db \
|
|
3163
|
+
psql -U odoo -d postgres -Atqc "SELECT datname FROM pg_database")"
|
|
3164
|
+
if ! grep -Fxq "${{DB_NAME}}" <<< "${{DATABASES}}"; then
|
|
3165
|
+
echo "ERROR: target database '${{DB_NAME}}' does not exist." >&2
|
|
3166
|
+
exit 1
|
|
3167
|
+
fi
|
|
3168
|
+
|
|
3169
|
+
echo "INFO: Neutralizing Odoo database '${{DB_NAME}}'."
|
|
3170
|
+
{neutralize_command}
|
|
3171
|
+
echo "INFO: Database neutralization completed: ${{DB_NAME}}"
|
|
3172
|
+
"""
|
|
3173
|
+
return _write_docker_local_script(layout, "neutralize-db", content)
|
|
3174
|
+
|
|
3175
|
+
|
|
3094
3176
|
def write_docker_backup_filestore_sh(layout: Layout, cfg: ProjectConfig) -> Path:
|
|
3095
3177
|
default_db_name = shlex.quote(_docker_default_db_name(cfg))
|
|
3096
3178
|
content = fr"""#!/usr/bin/env bash
|
|
@@ -3446,6 +3528,7 @@ if defined ODOO_DB_NAME (
|
|
|
3446
3528
|
set "DB_NAME=%DEFAULT_DB_NAME%"
|
|
3447
3529
|
)
|
|
3448
3530
|
set "FORCE=false"
|
|
3531
|
+
set "RESTORE_MODE=copy"
|
|
3449
3532
|
set "SOURCE="
|
|
3450
3533
|
|
|
3451
3534
|
goto parse_args
|
|
@@ -3453,6 +3536,8 @@ goto parse_args
|
|
|
3453
3536
|
:parse_args
|
|
3454
3537
|
if "%~1"=="" goto args_done
|
|
3455
3538
|
if /i "%~1"=="--force" goto force_arg
|
|
3539
|
+
if /i "%~1"=="--copy" goto copy_arg
|
|
3540
|
+
if /i "%~1"=="--move" goto move_arg
|
|
3456
3541
|
if "%~1:~0,1%"=="-" goto unknown_option
|
|
3457
3542
|
if defined SOURCE goto usage_error
|
|
3458
3543
|
set "SOURCE=%~1"
|
|
@@ -3464,6 +3549,16 @@ set "FORCE=true"
|
|
|
3464
3549
|
shift
|
|
3465
3550
|
goto parse_args
|
|
3466
3551
|
|
|
3552
|
+
:copy_arg
|
|
3553
|
+
set "RESTORE_MODE=copy"
|
|
3554
|
+
shift
|
|
3555
|
+
goto parse_args
|
|
3556
|
+
|
|
3557
|
+
:move_arg
|
|
3558
|
+
set "RESTORE_MODE=move"
|
|
3559
|
+
shift
|
|
3560
|
+
goto parse_args
|
|
3561
|
+
|
|
3467
3562
|
:args_done
|
|
3468
3563
|
if not defined SOURCE goto usage_error
|
|
3469
3564
|
if not exist "%SOURCE%" (
|
|
@@ -3495,6 +3590,18 @@ if errorlevel 1 exit /b 1
|
|
|
3495
3590
|
docker compose exec -T db pg_restore --exit-on-error --no-owner --no-acl -U odoo -d "%DB_NAME%" < "%SOURCE%"
|
|
3496
3591
|
if errorlevel 1 exit /b 1
|
|
3497
3592
|
|
|
3593
|
+
if /i "%RESTORE_MODE%"=="move" goto restore_done
|
|
3594
|
+
|
|
3595
|
+
echo INFO: Resetting copied Odoo database identity for '%DB_NAME%'.
|
|
3596
|
+
echo env["ir.config_parameter"].init(force=True^) | docker compose run --rm --no-deps -T --entrypoint click-odoo odoo -c /etc/odoo/odoo.conf -d "%DB_NAME%" --log-level=error
|
|
3597
|
+
if errorlevel 1 exit /b 1
|
|
3598
|
+
|
|
3599
|
+
docker compose exec -T db psql -v ON_ERROR_STOP=1 -U odoo -d "%DB_NAME%" -c "DELETE FROM ir_config_parameter WHERE key = 'database.enterprise_code'; UPDATE ir_config_parameter SET value = 'copy' WHERE key = 'database.expiration_reason' AND value != 'demo'; UPDATE ir_config_parameter SET value = CURRENT_DATE + INTERVAL '2 month' WHERE key = 'database.expiration_date';"
|
|
3600
|
+
if errorlevel 1 exit /b 1
|
|
3601
|
+
goto restore_done
|
|
3602
|
+
|
|
3603
|
+
:restore_done
|
|
3604
|
+
if /i "%RESTORE_MODE%"=="move" echo INFO: Preserving Odoo database identity (--move).
|
|
3498
3605
|
echo INFO: Database restore completed: %DB_NAME%
|
|
3499
3606
|
endlocal
|
|
3500
3607
|
exit /b 0
|
|
@@ -3504,12 +3611,60 @@ echo ERROR: unknown option: %~1
|
|
|
3504
3611
|
goto usage_error
|
|
3505
3612
|
|
|
3506
3613
|
:usage_error
|
|
3507
|
-
echo Usage: %~nx0 [--force] BACKUP.dump
|
|
3614
|
+
echo Usage: %~nx0 [--force] [--copy^|--move] BACKUP.dump
|
|
3508
3615
|
exit /b 2
|
|
3509
3616
|
"""
|
|
3510
3617
|
return _write_docker_local_script(layout, "restore-db", content, ext="bat")
|
|
3511
3618
|
|
|
3512
3619
|
|
|
3620
|
+
def write_docker_neutralize_db_bat(layout: Layout, cfg: ProjectConfig) -> Path:
|
|
3621
|
+
default_db_name = _docker_default_db_name(cfg).replace("%", "%%")
|
|
3622
|
+
odoo_major_version = _parse_odoo_version(cfg.odoo.version)
|
|
3623
|
+
if odoo_major_version >= 16:
|
|
3624
|
+
neutralize_command = rf"""echo INFO: Using native Odoo neutralization for Odoo {odoo_major_version}.
|
|
3625
|
+
docker compose run --rm --no-deps -T --entrypoint odoo odoo neutralize -c /etc/odoo/odoo.conf -d "%DB_NAME%"
|
|
3626
|
+
if errorlevel 1 exit /b 1
|
|
3627
|
+
"""
|
|
3628
|
+
else:
|
|
3629
|
+
neutralize_command = rf"""echo INFO: Using legacy minimal neutralization for Odoo {odoo_major_version}.
|
|
3630
|
+
echo [(model.search([("active", "=", True)]).write({{"active": False}})) for model_name in ("ir.cron", "ir.mail_server", "fetchmail.server") if model_name in env for model in (env[model_name],) if "active" in model._fields]; env.cr.commit() | docker compose run --rm --no-deps -T --entrypoint click-odoo odoo -c /etc/odoo/odoo.conf -d "%DB_NAME%" --log-level=error
|
|
3631
|
+
if errorlevel 1 exit /b 1
|
|
3632
|
+
"""
|
|
3633
|
+
|
|
3634
|
+
content = rf"""@echo off
|
|
3635
|
+
setlocal
|
|
3636
|
+
|
|
3637
|
+
set "SCRIPT_DIR=%~dp0"
|
|
3638
|
+
if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
|
|
3639
|
+
for %%I in ("%SCRIPT_DIR%\..\..\..") do set "ROOT_DIR=%%~fI"
|
|
3640
|
+
set "DEFAULT_DB_NAME={default_db_name}"
|
|
3641
|
+
if defined ODOO_DB_NAME (
|
|
3642
|
+
set "DB_NAME=%ODOO_DB_NAME%"
|
|
3643
|
+
) else (
|
|
3644
|
+
set "DB_NAME=%DEFAULT_DB_NAME%"
|
|
3645
|
+
)
|
|
3646
|
+
|
|
3647
|
+
cd /d "%ROOT_DIR%" || exit /b 1
|
|
3648
|
+
|
|
3649
|
+
set "DB_EXISTS=false"
|
|
3650
|
+
for /f "usebackq delims=" %%D in (`docker compose exec -T db psql -U odoo -d postgres -Atqc "SELECT datname FROM pg_database"`) do (
|
|
3651
|
+
if "%%D"=="%DB_NAME%" set "DB_EXISTS=true"
|
|
3652
|
+
)
|
|
3653
|
+
|
|
3654
|
+
if not "%DB_EXISTS%"=="true" (
|
|
3655
|
+
echo ERROR: target database '%DB_NAME%' does not exist.
|
|
3656
|
+
exit /b 1
|
|
3657
|
+
)
|
|
3658
|
+
|
|
3659
|
+
echo INFO: Neutralizing Odoo database '%DB_NAME%'.
|
|
3660
|
+
{neutralize_command}
|
|
3661
|
+
echo INFO: Database neutralization completed: %DB_NAME%
|
|
3662
|
+
endlocal
|
|
3663
|
+
exit /b 0
|
|
3664
|
+
"""
|
|
3665
|
+
return _write_docker_local_script(layout, "neutralize-db", content, ext="bat")
|
|
3666
|
+
|
|
3667
|
+
|
|
3513
3668
|
def write_docker_backup_filestore_bat(layout: Layout, cfg: ProjectConfig) -> Path:
|
|
3514
3669
|
default_db_name = _docker_default_db_name(cfg).replace("%", "%%")
|
|
3515
3670
|
content = rf"""@echo off
|
|
@@ -3874,6 +4029,7 @@ def write_docker_local_scripts(layout: Layout, cfg: ProjectConfig) -> dict[str,
|
|
|
3874
4029
|
return {
|
|
3875
4030
|
"backup_db": write_docker_backup_db_bat(layout, cfg),
|
|
3876
4031
|
"restore_db": write_docker_restore_db_bat(layout, cfg),
|
|
4032
|
+
"neutralize_db": write_docker_neutralize_db_bat(layout, cfg),
|
|
3877
4033
|
"backup_filestore": write_docker_backup_filestore_bat(layout, cfg),
|
|
3878
4034
|
"restore_filestore": write_docker_restore_filestore_bat(layout, cfg),
|
|
3879
4035
|
"restic": write_docker_restic_bat(layout),
|
|
@@ -3884,6 +4040,7 @@ def write_docker_local_scripts(layout: Layout, cfg: ProjectConfig) -> dict[str,
|
|
|
3884
4040
|
return {
|
|
3885
4041
|
"backup_db": write_docker_backup_db_sh(layout, cfg),
|
|
3886
4042
|
"restore_db": write_docker_restore_db_sh(layout, cfg),
|
|
4043
|
+
"neutralize_db": write_docker_neutralize_db_sh(layout, cfg),
|
|
3887
4044
|
"backup_filestore": write_docker_backup_filestore_sh(layout, cfg),
|
|
3888
4045
|
"restore_filestore": write_docker_restore_filestore_sh(layout, cfg),
|
|
3889
4046
|
"restic": write_docker_restic_sh(layout),
|
|
@@ -6090,11 +6247,11 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
6090
6247
|
Examples:
|
|
6091
6248
|
|
|
6092
6249
|
Creating a workspace:
|
|
6093
|
-
odoo-compose --init
|
|
6250
|
+
odoo-compose --init ./odoo18-workspace --sync-all --create-venv \\
|
|
6094
6251
|
--set odoo:version=18.0
|
|
6095
6252
|
|
|
6096
6253
|
Creating a workspace with explicit database settings:
|
|
6097
|
-
odoo-compose --init
|
|
6254
|
+
odoo-compose --init ./odoo18-workspace --sync-all --create-venv \\
|
|
6098
6255
|
--set odoo:version=18.0 \\
|
|
6099
6256
|
--set config:db_host=127.0.0.1 \\
|
|
6100
6257
|
--set config:db_name=odoo \\
|
|
@@ -6111,7 +6268,7 @@ Examples:
|
|
|
6111
6268
|
odoo-compose git+https://github.com/lck/odoo-devops-tools.git//examples/odoo18-minimal.ini?ref=main --sync-all --create-venv
|
|
6112
6269
|
|
|
6113
6270
|
Preparing local Docker development:
|
|
6114
|
-
odoo-compose --init
|
|
6271
|
+
odoo-compose --init ./odoo19 --sync-addons
|
|
6115
6272
|
|
|
6116
6273
|
Generating a deploy Docker build context:
|
|
6117
6274
|
odoo-compose /path/to/odoo-project.ini --sync-addons --create-docker-deploy
|
|
@@ -6179,7 +6336,9 @@ Examples:
|
|
|
6179
6336
|
)
|
|
6180
6337
|
|
|
6181
6338
|
parser.add_argument(
|
|
6339
|
+
"--init",
|
|
6182
6340
|
"--init-project",
|
|
6341
|
+
dest="init_project",
|
|
6183
6342
|
nargs="?",
|
|
6184
6343
|
const="",
|
|
6185
6344
|
default=None,
|
|
@@ -6188,7 +6347,7 @@ Examples:
|
|
|
6188
6347
|
"Create ROOT/odoo-project.ini from the bundled default template if it does not already exist. "
|
|
6189
6348
|
"An optional ROOT can be supplied directly as shorthand for --root. "
|
|
6190
6349
|
"If ROOT is supplied here, --root must not also be used. "
|
|
6191
|
-
"Without --init
|
|
6350
|
+
"Without --init, an existing ROOT/odoo-project.ini is required."
|
|
6192
6351
|
),
|
|
6193
6352
|
)
|
|
6194
6353
|
|
|
@@ -6435,12 +6594,12 @@ def main() -> None:
|
|
|
6435
6594
|
|
|
6436
6595
|
if init_project_root_raw and args.root:
|
|
6437
6596
|
parser.error(
|
|
6438
|
-
"workspace ROOT was specified both as --init
|
|
6597
|
+
"workspace ROOT was specified both as --init ROOT and --root; "
|
|
6439
6598
|
"use only one of them."
|
|
6440
6599
|
)
|
|
6441
6600
|
|
|
6442
6601
|
if bool(getattr(args, 'show_last_run', False)) and init_project:
|
|
6443
|
-
parser.error("--init
|
|
6602
|
+
parser.error("--init cannot be used together with --show-last-run.")
|
|
6444
6603
|
if bool(getattr(args, 'show_last_run', False)) and getattr(args, 'create_from_bundle', None):
|
|
6445
6604
|
parser.error("--create-from-bundle cannot be used together with --show-last-run.")
|
|
6446
6605
|
if bool(getattr(args, 'show_last_run', False)) and getattr(args, 'create_bundle', None) is not None:
|
|
@@ -6499,7 +6658,7 @@ def main() -> None:
|
|
|
6499
6658
|
if getattr(args, 'include_inis', None):
|
|
6500
6659
|
conflicting_options.append("--include")
|
|
6501
6660
|
if init_project:
|
|
6502
|
-
conflicting_options.append("--init
|
|
6661
|
+
conflicting_options.append("--init")
|
|
6503
6662
|
if args.all or args.odoo or args.addons:
|
|
6504
6663
|
conflicting_options.append("--sync-*")
|
|
6505
6664
|
if bool(getattr(args, 'create_venv', False)) or create_venv_from_wheelhouse:
|
|
@@ -6580,14 +6739,14 @@ def main() -> None:
|
|
|
6580
6739
|
project_ini_status: Optional[str] = None
|
|
6581
6740
|
|
|
6582
6741
|
if init_project and not implicit_ini:
|
|
6583
|
-
parser.error("--init
|
|
6742
|
+
parser.error("--init can only be used when INI is omitted and no -i/--include is provided.")
|
|
6584
6743
|
|
|
6585
6744
|
if implicit_ini:
|
|
6586
6745
|
if init_project_root_raw:
|
|
6587
6746
|
root_override = _validate_root_override(
|
|
6588
6747
|
parser,
|
|
6589
6748
|
init_project_root_raw,
|
|
6590
|
-
option_name="--init
|
|
6749
|
+
option_name="--init ROOT",
|
|
6591
6750
|
)
|
|
6592
6751
|
elif args.root:
|
|
6593
6752
|
root_override = _validate_root_override(parser, args.root)
|
|
@@ -6624,7 +6783,7 @@ def main() -> None:
|
|
|
6624
6783
|
project_ini_status = f"used existing ROOT/{_DEFAULT_PROJECT_INI_NAME}"
|
|
6625
6784
|
_logger.info("Project INI already exists, leaving it in place: %s", ini_path)
|
|
6626
6785
|
elif not ini_path.is_file():
|
|
6627
|
-
suggested_cmd = ["odoo-compose", "--init
|
|
6786
|
+
suggested_cmd = ["odoo-compose", "--init"]
|
|
6628
6787
|
if args.root:
|
|
6629
6788
|
suggested_cmd.append(str(root_override))
|
|
6630
6789
|
parser.error(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: odoo-devops-tools
|
|
3
|
-
Version: 1.23.
|
|
3
|
+
Version: 1.23.2
|
|
4
4
|
Summary: Build reproducible Odoo workspaces from a single project definition.
|
|
5
5
|
Author: Roman Lacko
|
|
6
6
|
License-Expression: MIT
|
|
@@ -120,7 +120,7 @@ Choose the workflow that fits your environment. Both use the same `odoo-project.
|
|
|
120
120
|
Create a new workspace:
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
odoo-compose --init
|
|
123
|
+
odoo-compose --init ./odoo19
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
Start the Docker Compose environment:
|
|
@@ -238,6 +238,7 @@ On Unix-like systems:
|
|
|
238
238
|
docker/local/scripts/
|
|
239
239
|
├── backup-db.sh
|
|
240
240
|
├── restore-db.sh
|
|
241
|
+
├── neutralize-db.sh
|
|
241
242
|
├── backup-filestore.sh
|
|
242
243
|
├── restore-filestore.sh
|
|
243
244
|
├── restic.sh
|
|
@@ -281,6 +282,21 @@ Restore a database dump with `pg_restore`:
|
|
|
281
282
|
./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
|
|
282
283
|
```
|
|
283
284
|
|
|
285
|
+
Database restores use copy semantics by default, matching `click-odoo-restoredb --copy`.
|
|
286
|
+
After `pg_restore`, Odoo database identity parameters are regenerated so the restored
|
|
287
|
+
database can coexist with the source database:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
./docker/local/scripts/restore-db.sh --copy ./odoo-backups/pre-upgrade.dump
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Use `--move` only when the restored database replaces the original database and its
|
|
294
|
+
identity must be preserved:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
./docker/local/scripts/restore-db.sh --move ./odoo-backups/pre-upgrade.dump
|
|
298
|
+
```
|
|
299
|
+
|
|
284
300
|
If the target database already exists, the restore is rejected unless `--force` is used. With `--force`, the existing database is dropped and recreated before the dump is restored. When restoring the database currently used by the Odoo service, stop Odoo first and start it again after the restore:
|
|
285
301
|
|
|
286
302
|
```bash
|
|
@@ -295,7 +311,37 @@ To restore the same dump into another database without replacing the default dat
|
|
|
295
311
|
ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
|
|
296
312
|
```
|
|
297
313
|
|
|
298
|
-
#### 1.3.3.
|
|
314
|
+
#### 1.3.3. Database neutralization
|
|
315
|
+
|
|
316
|
+
For development or test databases restored from production, run the generated neutralization helper explicitly:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
./docker/local/scripts/neutralize-db.sh
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Override the target database with `ODOO_DB_NAME` when needed:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
ODOO_DB_NAME=odoo_test ./docker/local/scripts/neutralize-db.sh
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
For Odoo 16.0 and newer, the helper uses Odoo's native database neutralization mechanism. This applies the `neutralize.sql` scripts provided by installed Odoo modules, disabling or redirecting production-side effects such as scheduled actions, outgoing email, and supported external integrations.
|
|
329
|
+
|
|
330
|
+
For Odoo 13.0 through 15.0, where the native neutralization framework is not available, the helper applies a deliberately minimal compatibility neutralization through the Odoo ORM: it disables scheduled actions, configured outgoing mail servers, and configured incoming mail servers.
|
|
331
|
+
|
|
332
|
+
Neutralization is intentionally separate from database restore. A typical test/staging restore workflow is therefore:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
docker compose stop odoo
|
|
336
|
+
./docker/local/scripts/restore-db.sh --copy ./odoo-backups/production.dump
|
|
337
|
+
./docker/local/scripts/restore-filestore.sh ./odoo-backups/production-filestore.tar.gz
|
|
338
|
+
./docker/local/scripts/neutralize-db.sh
|
|
339
|
+
docker compose up -d odoo
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
`--copy` / `--move` and neutralization serve different purposes: copy/move controls restored database identity, while neutralization controls production side effects.
|
|
343
|
+
|
|
344
|
+
#### 1.3.4. Filestore backup
|
|
299
345
|
|
|
300
346
|
Create a compressed tar archive of the selected database filestore:
|
|
301
347
|
|
|
@@ -326,7 +372,7 @@ docker compose stop odoo
|
|
|
326
372
|
docker compose up -d odoo
|
|
327
373
|
```
|
|
328
374
|
|
|
329
|
-
#### 1.3.
|
|
375
|
+
#### 1.3.5. Filestore restore
|
|
330
376
|
|
|
331
377
|
Restore a filestore archive:
|
|
332
378
|
|
|
@@ -350,7 +396,7 @@ ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-filestore.sh ./odoo-bac
|
|
|
350
396
|
|
|
351
397
|
Database and filestore backups are intentionally separate. This allows either part to be restored independently while still making it possible to create matching database and filestore backups when both are needed.
|
|
352
398
|
|
|
353
|
-
#### 1.3.
|
|
399
|
+
#### 1.3.6. Restic filestore backup
|
|
354
400
|
|
|
355
401
|
The generated Docker image also includes `restic`. Restic is an additional option intended especially for large filestores where incremental snapshots and deduplication are useful.
|
|
356
402
|
|
|
@@ -398,7 +444,7 @@ List or inspect snapshots through the generic wrapper:
|
|
|
398
444
|
./docker/local/scripts/restic.sh check
|
|
399
445
|
```
|
|
400
446
|
|
|
401
|
-
#### 1.3.
|
|
447
|
+
#### 1.3.7. Restic filestore restore
|
|
402
448
|
|
|
403
449
|
Restore the latest matching filestore snapshot:
|
|
404
450
|
|
|
@@ -468,7 +514,7 @@ In this workflow, Odoo runs directly on the host using a generated Python virtua
|
|
|
468
514
|
Create the workspace with the Odoo source and virtual environment:
|
|
469
515
|
|
|
470
516
|
```bash
|
|
471
|
-
odoo-compose --init
|
|
517
|
+
odoo-compose --init ./odoo19 --sync-all --create-venv \
|
|
472
518
|
--set config:db_host=127.0.0.1 \
|
|
473
519
|
--set config:db_name=odoo \
|
|
474
520
|
--set config:db_user=odoo \
|
|
@@ -906,7 +952,7 @@ The merged project file is saved as `ROOT/odoo-project.ini`, replacing any exist
|
|
|
906
952
|
### Paths and outputs
|
|
907
953
|
|
|
908
954
|
- `--root ROOT` — workspace root directory. Default: the directory containing a local INI file, or the current working directory for a remote INI or omitted INI. In include mode, the default is the directory of the first local source, or the current working directory when the first source is remote.
|
|
909
|
-
- `--init
|
|
955
|
+
- `--init [ROOT]` — create `ROOT/odoo-project.ini` from the bundled default template if it does not already exist. `ROOT` is optional; when supplied, it is a shorthand for selecting the workspace root directly, for example `odoo-compose --init ./odoo19`. When the optional value is omitted, `--root ROOT` remains supported for backward compatibility. Do not supply both `--init ROOT` and `--root ROOT`; the command exits with an error instead of choosing one implicitly. This option is valid only when `INI` is omitted and no `-i/--include` is provided. Existing project files are not overwritten.
|
|
910
956
|
- `--include INI`, `-i INI` — include an additional project INI layer; can be repeated. Later layers override earlier layers.
|
|
911
957
|
- `--extra-var KEY=VALUE`, `-e KEY=VALUE` — override or inject a value in the optional `[vars]` section; can be repeated.
|
|
912
958
|
- `--set SECTION:KEY=VALUE`, `-S SECTION:KEY=VALUE` — set or override a supported project option; can be repeated. Missing supported sections/options are created automatically. Structured sections (`[virtualenv]`, `[odoo]`, `[addons.<name>]`, and `[docker]`) accept only documented keys; `[config]` remains open to standard Odoo configuration options except `addons_path`.
|
|
@@ -977,7 +1023,7 @@ The following sections are supported:
|
|
|
977
1023
|
|
|
978
1024
|
### General rules
|
|
979
1025
|
|
|
980
|
-
- The project file can have any filename when passed explicitly. When `INI` is omitted, `odoo-compose` uses the existing `ROOT/odoo-project.ini`; if it is missing, use `--init
|
|
1026
|
+
- The project file can have any filename when passed explicitly. When `INI` is omitted, `odoo-compose` uses the existing `ROOT/odoo-project.ini`; if it is missing, use `--init` to create it explicitly from the bundled default template. Remote INI sources and merged include layers are materialized as `ROOT/odoo-project.ini`.
|
|
981
1027
|
- INI interpolation is supported, so values such as `${odoo:version}` can be reused across sections.
|
|
982
1028
|
- Multiple INI layers can be composed with `-i/--include`. Later layers override earlier layers; multi-line values are replaced as whole option values, not appended.
|
|
983
1029
|
- The optional `[vars]` section is useful for reusable values referenced as `${vars:name}`.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.23.0"
|
|
File without changes
|
{odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{odoo_devops_tools-1.23.0 → odoo_devops_tools-1.23.2}/odoo_devops_tools.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|