From afed1350389c7850b6044687b320b620becb7932 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 16:12:10 +0200 Subject: [PATCH 01/34] [IMP] fs_storage: Remove environment data --- fs_storage/README.rst | 6 +-- fs_storage/__manifest__.py | 4 +- fs_storage/models/fs_storage.py | 15 ------ .../readme/newsfragments/627.feature.rst | 1 + fs_storage/static/description/index.html | 54 +++++++++---------- fs_storage/tests/test_fs_storage.py | 7 ++- 6 files changed, 34 insertions(+), 53 deletions(-) create mode 100644 fs_storage/readme/newsfragments/627.feature.rst diff --git a/fs_storage/README.rst b/fs_storage/README.rst index 4cdae5cb19..7ca6dee564 100644 --- a/fs_storage/README.rst +++ b/fs_storage/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ========================== Filesystem Storage Backend ========================== @@ -17,7 +13,7 @@ Filesystem Storage Backend .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github diff --git a/fs_storage/__manifest__.py b/fs_storage/__manifest__.py index 129a3f3626..201cd0f2be 100644 --- a/fs_storage/__manifest__.py +++ b/fs_storage/__manifest__.py @@ -5,14 +5,14 @@ { "name": "Filesystem Storage Backend", "summary": "Implement the concept of Storage with amazon S3, sftp...", - "version": "18.0.2.1.2", + "version": "18.0.2.1.3", "category": "FS Storage", "website": "https://github.com/OCA/storage", "author": " ACSONE SA/NV, Odoo Community Association (OCA)", "license": "LGPL-3", "development_status": "Beta", "installable": True, - "depends": ["base", "base_sparse_field", "server_environment"], + "depends": ["base", "base_sparse_field"], "data": [ "views/fs_storage_view.xml", "security/ir.model.access.csv", diff --git a/fs_storage/models/fs_storage.py b/fs_storage/models/fs_storage.py index 0e60422123..4e0452b195 100644 --- a/fs_storage/models/fs_storage.py +++ b/fs_storage/models/fs_storage.py @@ -89,7 +89,6 @@ def wrapper(self, *args, **kwargs): class FSStorage(models.Model): _name = "fs.storage" - _inherit = "server.env.mixin" _description = "FS Storage" __slots__ = ("__fs", "__odoo_storage_path") @@ -235,8 +234,6 @@ def __init__(self, env, ids=(), prefetch_ids=()): ), ] - _server_env_section_name_field = "code" - @api.constrains("model_xmlids") def _check_model_xmlid_storage_unique(self): """ @@ -302,18 +299,6 @@ def _get_check_connection_method_selection(self): ("ls", _("List File")), ] - @property - def _server_env_fields(self): - return { - "protocol": {}, - "options": {}, - "directory_path": {}, - "eval_options_from_env": {}, - "model_xmlids": {}, - "field_xmlids": {}, - "check_connection_method": {}, - } - @api.model_create_multi @prevent_call_from_safe_eval("create") def create(self, vals_list): diff --git a/fs_storage/readme/newsfragments/627.feature.rst b/fs_storage/readme/newsfragments/627.feature.rst new file mode 100644 index 0000000000..0107afb987 --- /dev/null +++ b/fs_storage/readme/newsfragments/627.feature.rst @@ -0,0 +1 @@ +- Remove the dependancy of server_environment module and make fs_storage_environment a bridge between fs_storage and server_environment modules. \ No newline at end of file diff --git a/fs_storage/static/description/index.html b/fs_storage/static/description/index.html index 3104d3767c..00cbd41c99 100644 --- a/fs_storage/static/description/index.html +++ b/fs_storage/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Filesystem Storage Backend -
+
+

Filesystem Storage Backend

- - -Odoo Community Association - -
-

Filesystem Storage Backend

-

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

This addon is a technical addon that allows you to define filesystem like storage for your data. It’s used by other addons to store their data in a transparent way into different kind of storages.

@@ -474,9 +469,9 @@

Filesystem Storage Backend

-

Usage

+

Usage

-

Configuration

+

Configuration

When you create a new backend, you must specify the following:

  • The name of the backend. This is the name that will be used to @@ -528,7 +523,7 @@

    Configuration

    wrapper around the odoofs protocol.

-

Server Environment

+

Server Environment

To ease the management of the filesystem storages configuration accross the different environments, the configuration of the filesystem storages can be defined in environment files or directly in the main @@ -554,7 +549,7 @@

Server Environment

controlled by configuration files.

-

Migration from storage_backend

+

Migration from storage_backend

The fs_storage addon can be used to replace the storage_backend addon. (It has been designed to be a drop-in replacement for the storage_backend addon). To ease the migration, the fs.storage model @@ -579,7 +574,7 @@

Migration from storage_backend

-

Known issues / Roadmap

+

Known issues / Roadmap

  • Transactions: fsspec comes with a transactional mechanism that once started, gathers all the files created during the transaction, and if @@ -594,11 +589,11 @@

    Known issues / Roadmap

-

Changelog

+

Changelog

-

18.0.2.1.0 (2025-10-20)

+

18.0.2.1.0 (2025-10-20)

-

Features

+

Features

  • Replace {db_name} by the database name in directory_path (#db_name)
  • @@ -606,18 +601,18 @@

    Features

-

18.0.2.0.1 (2025-07-23)

+

18.0.2.0.1 (2025-07-23)

-

Features

+

Features

  • Allow setting check_connection_method in configuration file.
-

18.0.1.0.1 (2024-11-10)

+

18.0.1.0.1 (2024-11-10)

-

Features

+

Features

  • Invalidate FS filesystem object cache when the connection fails, forcing a reconnection. @@ -626,7 +621,7 @@

    Features

-

16.0.1.1.0 (2023-12-22)

+

16.0.1.1.0 (2023-12-22)

Features

-

16.0.1.0.3 (2023-10-17)

+

16.0.1.0.3 (2023-10-17)

Bugfixes

-

16.0.1.0.2 (2023-10-09)

+

16.0.1.0.2 (2023-10-09)

Bugfixes

  • Avoid config error when using the webdav protocol. The auth option is @@ -657,7 +652,7 @@

    16.0.1.0.2 (2023-10-09)

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -665,15 +660,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -694,6 +689,5 @@

Maintainers

-
diff --git a/fs_storage/tests/test_fs_storage.py b/fs_storage/tests/test_fs_storage.py index 631ce4f250..e6be235af5 100644 --- a/fs_storage/tests/test_fs_storage.py +++ b/fs_storage/tests/test_fs_storage.py @@ -82,7 +82,12 @@ def test_ensure_one_fs_by_record(self): for i in range(4): backend_ids.append( self.backend.create( - {"name": f"name{i}", "directory_path": f"{i}", "code": f"code{i}"} + { + "name": f"name{i}", + "directory_path": f"{i}", + "code": f"code{i}", + "protocol": "odoofs", + } ).id ) records = self.backend.browse(backend_ids) From 4bd049311ccc9983c54c47443f838f82e1670e4d Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 16:12:24 +0200 Subject: [PATCH 02/34] [ADD] fs_storage_environment --- fs_storage/upgrades/18.0.2.1.3/post-update.py | 19 + fs_storage_environment/README.rst | 136 +++++ fs_storage_environment/__init__.py | 1 + fs_storage_environment/__manifest__.py | 15 + fs_storage_environment/models/__init__.py | 1 + fs_storage_environment/models/fs_storage.py | 28 + fs_storage_environment/pyproject.toml | 3 + fs_storage_environment/readme/CONTRIBUTORS.md | 3 + fs_storage_environment/readme/DESCRIPTION.md | 4 + fs_storage_environment/readme/USAGE.md | 49 ++ .../readme/newsfragments/.gitignore | 0 .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 483 ++++++++++++++++++ 13 files changed, 742 insertions(+) create mode 100644 fs_storage/upgrades/18.0.2.1.3/post-update.py create mode 100644 fs_storage_environment/README.rst create mode 100644 fs_storage_environment/__init__.py create mode 100644 fs_storage_environment/__manifest__.py create mode 100644 fs_storage_environment/models/__init__.py create mode 100644 fs_storage_environment/models/fs_storage.py create mode 100644 fs_storage_environment/pyproject.toml create mode 100644 fs_storage_environment/readme/CONTRIBUTORS.md create mode 100644 fs_storage_environment/readme/DESCRIPTION.md create mode 100644 fs_storage_environment/readme/USAGE.md create mode 100644 fs_storage_environment/readme/newsfragments/.gitignore create mode 100644 fs_storage_environment/static/description/icon.png create mode 100644 fs_storage_environment/static/description/index.html diff --git a/fs_storage/upgrades/18.0.2.1.3/post-update.py b/fs_storage/upgrades/18.0.2.1.3/post-update.py new file mode 100644 index 0000000000..626ada9ca6 --- /dev/null +++ b/fs_storage/upgrades/18.0.2.1.3/post-update.py @@ -0,0 +1,19 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search([("name", "=", "fs_storage_environment")]) + if not module: + raise exceptions.UserError( + _( + "The 'fs_storage_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'fs.storage'. Make it available on the " + "addons path before upgrading 'fs_storage'." + ) + ) + if module.state == "uninstalled": + module.button_install() diff --git a/fs_storage_environment/README.rst b/fs_storage_environment/README.rst new file mode 100644 index 0000000000..00fe7f7a67 --- /dev/null +++ b/fs_storage_environment/README.rst @@ -0,0 +1,136 @@ +========================== +Filesystem Storage Backend +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:bbd1be658bbe5cda3a0ca2391c1de17eafb45624ac49610b3b2503c65d2610af + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/fs_storage_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_storage_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to use server environment with fs storage. It is a +bridge between fs_storage and server_environment modules. It provides an +implementation of the StorageEnvironment class that uses the filesystem +as a storage backend. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To ease the management of the filesystem storages configuration accross +the different environments, the configuration of the filesystem storages +can be defined in environment files or directly in the main +configuration file. For example, the configuration of a filesystem +storage with the code fsprod can be provided in the main configuration +file as follows: + +.. code:: ini + + [fs_storage.fsprod] + protocol=s3 + options={"endpoint_url": "https://my_s3_server/", "key": "KEY", "secret": "SECRET"} + directory_path=my_bucket + +To work, a storage.backend record must exist with the code fsprod into +the database. In your configuration section, you can specify the value +for the following fields: + +- protocol +- options +- directory_path + +When evaluating directory_path, {db_name} is replaced by the database +name. This is usefull in multi-tenant with a setup completly controlled +by configuration files. + +Migration from storage_backend +------------------------------ + +The fs_storage addon can be used to replace the storage_backend addon. +(It has been designed to be a drop-in replacement for the +storage_backend addon). To ease the migration, the fs.storage model +defines the high-level methods available in the storage_backend model. +These methods are: + +- add +- get +- list_files +- find_files +- move_files +- delete + +These methods are wrappers around the methods of the +fsspec.AbstractFileSystem class (see +https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem). +These methods are marked as deprecated and will be removed in a future +version (V18) of the addon. You should use the methods of the +fsspec.AbstractFileSystem class instead since they are more flexible and +powerful. You can access the instance of the fsspec.AbstractFileSystem +class using the fs property of a fs.storage record. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ACSONE SA/NV +* Dixmit + +Contributors +------------ + +- Laurent Mignon +- Sébastien BEAU +- Enric Tobella + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fs_storage_environment/__init__.py b/fs_storage_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/fs_storage_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/fs_storage_environment/__manifest__.py b/fs_storage_environment/__manifest__.py new file mode 100644 index 0000000000..e28a2c07e9 --- /dev/null +++ b/fs_storage_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Dixmit +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Filesystem Storage Backend", + "summary": "Allows to use server environment with fs storage", + "version": "18.0.1.0.0", + "category": "FS Storage", + "website": "https://github.com/OCA/storage", + "author": " ACSONE SA/NV, Dixmit, Odoo Community Association (OCA)", + "license": "LGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["fs_storage", "server_environment"], +} diff --git a/fs_storage_environment/models/__init__.py b/fs_storage_environment/models/__init__.py new file mode 100644 index 0000000000..349bb0495a --- /dev/null +++ b/fs_storage_environment/models/__init__.py @@ -0,0 +1 @@ +from . import fs_storage diff --git a/fs_storage_environment/models/fs_storage.py b/fs_storage_environment/models/fs_storage.py new file mode 100644 index 0000000000..57b08ba17d --- /dev/null +++ b/fs_storage_environment/models/fs_storage.py @@ -0,0 +1,28 @@ +# Copyright 2023 ACSONE SA/NV (https://www.acsone.eu). +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +from __future__ import annotations + +import logging + +from odoo import models + +_logger = logging.getLogger(__name__) + + +class FSStorage(models.Model): + _name = "fs.storage" + _inherit = ["fs.storage", "server.env.mixin"] + + _server_env_section_name_field = "code" + + @property + def _server_env_fields(self): + return { + "protocol": {}, + "options": {}, + "directory_path": {}, + "eval_options_from_env": {}, + "model_xmlids": {}, + "field_xmlids": {}, + "check_connection_method": {}, + } diff --git a/fs_storage_environment/pyproject.toml b/fs_storage_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/fs_storage_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/fs_storage_environment/readme/CONTRIBUTORS.md b/fs_storage_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..b4896734fa --- /dev/null +++ b/fs_storage_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- Laurent Mignon \ +- Sébastien BEAU \ +- Enric Tobella diff --git a/fs_storage_environment/readme/DESCRIPTION.md b/fs_storage_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..a01fa9ab8d --- /dev/null +++ b/fs_storage_environment/readme/DESCRIPTION.md @@ -0,0 +1,4 @@ +This module allows to use server environment with fs storage. It is a +bridge between fs_storage and server_environment modules. It provides an +implementation of the StorageEnvironment class that uses the filesystem +as a storage backend. diff --git a/fs_storage_environment/readme/USAGE.md b/fs_storage_environment/readme/USAGE.md new file mode 100644 index 0000000000..fb7d2c073e --- /dev/null +++ b/fs_storage_environment/readme/USAGE.md @@ -0,0 +1,49 @@ +To ease the management of the filesystem storages configuration accross +the different environments, the configuration of the filesystem storages +can be defined in environment files or directly in the main +configuration file. For example, the configuration of a filesystem +storage with the code fsprod can be provided in the main configuration +file as follows: + +``` ini +[fs_storage.fsprod] +protocol=s3 +options={"endpoint_url": "https://my_s3_server/", "key": "KEY", "secret": "SECRET"} +directory_path=my_bucket +``` + +To work, a storage.backend record must exist with the code fsprod into +the database. In your configuration section, you can specify the value +for the following fields: + +- protocol +- options +- directory_path + +When evaluating directory_path, {db_name} is replaced by the database +name. This is usefull in multi-tenant with a setup completly controlled +by configuration files. + +## Migration from storage_backend + +The fs_storage addon can be used to replace the storage_backend addon. +(It has been designed to be a drop-in replacement for the +storage_backend addon). To ease the migration, the fs.storage model +defines the high-level methods available in the storage_backend model. +These methods are: + +- add +- get +- list_files +- find_files +- move_files +- delete + +These methods are wrappers around the methods of the +fsspec.AbstractFileSystem class (see +). +These methods are marked as deprecated and will be removed in a future +version (V18) of the addon. You should use the methods of the +fsspec.AbstractFileSystem class instead since they are more flexible and +powerful. You can access the instance of the fsspec.AbstractFileSystem +class using the fs property of a fs.storage record. diff --git a/fs_storage_environment/readme/newsfragments/.gitignore b/fs_storage_environment/readme/newsfragments/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fs_storage_environment/static/description/icon.png b/fs_storage_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/fs_storage_environment/static/description/index.html b/fs_storage_environment/static/description/index.html new file mode 100644 index 0000000000..c2c8c56fa6 --- /dev/null +++ b/fs_storage_environment/static/description/index.html @@ -0,0 +1,483 @@ + + + + + +Filesystem Storage Backend + + + +
+

Filesystem Storage Backend

+ + +

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

This module allows to use server environment with fs storage. It is a +bridge between fs_storage and server_environment modules. It provides an +implementation of the StorageEnvironment class that uses the filesystem +as a storage backend.

+

Table of contents

+ +
+

Usage

+

To ease the management of the filesystem storages configuration accross +the different environments, the configuration of the filesystem storages +can be defined in environment files or directly in the main +configuration file. For example, the configuration of a filesystem +storage with the code fsprod can be provided in the main configuration +file as follows:

+
+[fs_storage.fsprod]
+protocol=s3
+options={"endpoint_url": "https://my_s3_server/", "key": "KEY", "secret": "SECRET"}
+directory_path=my_bucket
+
+

To work, a storage.backend record must exist with the code fsprod into +the database. In your configuration section, you can specify the value +for the following fields:

+
    +
  • protocol
  • +
  • options
  • +
  • directory_path
  • +
+

When evaluating directory_path, {db_name} is replaced by the database +name. This is usefull in multi-tenant with a setup completly controlled +by configuration files.

+
+

Migration from storage_backend

+

The fs_storage addon can be used to replace the storage_backend addon. +(It has been designed to be a drop-in replacement for the +storage_backend addon). To ease the migration, the fs.storage model +defines the high-level methods available in the storage_backend model. +These methods are:

+
    +
  • add
  • +
  • get
  • +
  • list_files
  • +
  • find_files
  • +
  • move_files
  • +
  • delete
  • +
+

These methods are wrappers around the methods of the +fsspec.AbstractFileSystem class (see +https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem). +These methods are marked as deprecated and will be removed in a future +version (V18) of the addon. You should use the methods of the +fsspec.AbstractFileSystem class instead since they are more flexible and +powerful. You can access the instance of the fsspec.AbstractFileSystem +class using the fs property of a fs.storage record.

+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
  • Dixmit
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 33e8c46742552ca1d5f3a34d1e5c45e983701af7 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Wed, 19 Aug 2026 15:20:41 +0300 Subject: [PATCH 03/34] [IMP] fs_storage_environment: preserve data on install and restore columns on uninstall --- fs_storage_environment/__init__.py | 1 + fs_storage_environment/__manifest__.py | 2 ++ fs_storage_environment/hooks.py | 28 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 fs_storage_environment/hooks.py diff --git a/fs_storage_environment/__init__.py b/fs_storage_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/fs_storage_environment/__init__.py +++ b/fs_storage_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/fs_storage_environment/__manifest__.py b/fs_storage_environment/__manifest__.py index e28a2c07e9..b06aa578a7 100644 --- a/fs_storage_environment/__manifest__.py +++ b/fs_storage_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["fs_storage", "server_environment"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/fs_storage_environment/hooks.py b/fs_storage_environment/hooks.py new file mode 100644 index 0000000000..ce3e288b6a --- /dev/null +++ b/fs_storage_environment/hooks.py @@ -0,0 +1,28 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "protocol", + "options", + "directory_path", + "eval_options_from_env", + "model_xmlids", + "field_xmlids", + "check_connection_method", +] + + +def post_init_hook(env): + env["fs.storage"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "fs.storage", + ENV_MANAGED_FIELDS, + field_defaults={"protocol": "odoofs"}, + ) From 056cb5575b02a541c3ffc0a2affeb8b25625d8c1 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:31:29 +0200 Subject: [PATCH 04/34] [IMP] fs_attachment: Remove environment data --- fs_attachment/README.rst | 6 +----- fs_attachment/models/fs_storage.py | 17 ----------------- fs_attachment/tests/test_fs_storage.py | 1 + 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/fs_attachment/README.rst b/fs_attachment/README.rst index b50b5d9d27..6272d17692 100644 --- a/fs_attachment/README.rst +++ b/fs_attachment/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ============================ Base Attachment Object Store ============================ @@ -17,7 +13,7 @@ Base Attachment Object Store .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github diff --git a/fs_attachment/models/fs_storage.py b/fs_attachment/models/fs_storage.py index b403412cd9..6076b0363c 100644 --- a/fs_attachment/models/fs_storage.py +++ b/fs_attachment/models/fs_storage.py @@ -89,23 +89,6 @@ def _check_use_as_default_for_attachments(self): _("Only one storage can be used as default for attachments") ) - @property - def _server_env_fields(self): - env_fields = super()._server_env_fields - env_fields.update( - { - "optimizes_directory_path": {}, - "autovacuum_gc": {}, - "base_url": {}, - "is_directory_path_in_url": {}, - "use_x_sendfile_to_serve_internal_url": {}, - "use_as_default_for_attachments": {}, - "force_db_for_default_attachment_rules": {}, - "use_filename_obfuscation": {}, - } - ) - return env_fields - @property def _default_force_db_for_default_attachment_rules(self) -> str: return '{"image/": 51200, "application/javascript": 0, "text/css": 0}' diff --git a/fs_attachment/tests/test_fs_storage.py b/fs_attachment/tests/test_fs_storage.py index 981e2fcb79..8d8b8a00de 100644 --- a/fs_attachment/tests/test_fs_storage.py +++ b/fs_attachment/tests/test_fs_storage.py @@ -306,6 +306,7 @@ def test_url_for_image_dir_optimized_and_not_obfuscated(self): "name": "FS Product Image Backend", "code": "file", "base_url": "https://localhost/images", + "protocol": "odoofs", "optimizes_directory_path": True, "use_filename_obfuscation": False, } From bad98bf98ccca48b53044e3ed6b6a794778d45e0 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:32:01 +0200 Subject: [PATCH 05/34] [ADD] fs_attachment_environment --- fs_attachment_environment/README.rst | 79 ++++ fs_attachment_environment/__init__.py | 1 + fs_attachment_environment/__manifest__.py | 15 + fs_attachment_environment/models/__init__.py | 1 + .../models/fs_storage.py | 30 ++ fs_attachment_environment/pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 3 + .../readme/DESCRIPTION.md | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 426 ++++++++++++++++++ 10 files changed, 559 insertions(+) create mode 100644 fs_attachment_environment/README.rst create mode 100644 fs_attachment_environment/__init__.py create mode 100644 fs_attachment_environment/__manifest__.py create mode 100644 fs_attachment_environment/models/__init__.py create mode 100644 fs_attachment_environment/models/fs_storage.py create mode 100644 fs_attachment_environment/pyproject.toml create mode 100644 fs_attachment_environment/readme/CONTRIBUTORS.md create mode 100644 fs_attachment_environment/readme/DESCRIPTION.md create mode 100644 fs_attachment_environment/static/description/icon.png create mode 100644 fs_attachment_environment/static/description/index.html diff --git a/fs_attachment_environment/README.rst b/fs_attachment_environment/README.rst new file mode 100644 index 0000000000..b5f8eeec22 --- /dev/null +++ b/fs_attachment_environment/README.rst @@ -0,0 +1,79 @@ +============================= +Filesystem Attachment Backend +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:bbd1be658bbe5cda3a0ca2391c1de17eafb45624ac49610b3b2503c65d2610af + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/fs_attachment_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_attachment_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for fs_attachment to use fs_storage_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ACSONE SA/NV +* Dixmit + +Contributors +------------ + +- Laurent Mignon +- Sébastien BEAU +- Enric Tobella + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fs_attachment_environment/__init__.py b/fs_attachment_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/fs_attachment_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/fs_attachment_environment/__manifest__.py b/fs_attachment_environment/__manifest__.py new file mode 100644 index 0000000000..d342edc411 --- /dev/null +++ b/fs_attachment_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Filesystem Attachment Backend", + "summary": "Allows to use server environment with fs storage attachment", + "version": "18.0.1.0.0", + "category": "FS Storage", + "website": "https://github.com/OCA/storage", + "author": " ACSONE SA/NV, Dixmit, Odoo Community Association (OCA)", + "license": "AGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["fs_storage_environment", "fs_attachment"], +} diff --git a/fs_attachment_environment/models/__init__.py b/fs_attachment_environment/models/__init__.py new file mode 100644 index 0000000000..349bb0495a --- /dev/null +++ b/fs_attachment_environment/models/__init__.py @@ -0,0 +1 @@ +from . import fs_storage diff --git a/fs_attachment_environment/models/fs_storage.py b/fs_attachment_environment/models/fs_storage.py new file mode 100644 index 0000000000..6d520a3494 --- /dev/null +++ b/fs_attachment_environment/models/fs_storage.py @@ -0,0 +1,30 @@ +# Copyright 2023 ACSONE SA/NV (https://www.acsone.eu). +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +from __future__ import annotations + +import logging + +from odoo import models + +_logger = logging.getLogger(__name__) + + +class FSStorage(models.Model): + _inherit = "fs.storage" + + @property + def _server_env_fields(self): + env_fields = super()._server_env_fields + env_fields.update( + { + "optimizes_directory_path": {}, + "autovacuum_gc": {}, + "base_url": {}, + "is_directory_path_in_url": {}, + "use_x_sendfile_to_serve_internal_url": {}, + "use_as_default_for_attachments": {}, + "force_db_for_default_attachment_rules": {}, + "use_filename_obfuscation": {}, + } + ) + return env_fields diff --git a/fs_attachment_environment/pyproject.toml b/fs_attachment_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/fs_attachment_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/fs_attachment_environment/readme/CONTRIBUTORS.md b/fs_attachment_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..b4896734fa --- /dev/null +++ b/fs_attachment_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- Laurent Mignon \ +- Sébastien BEAU \ +- Enric Tobella diff --git a/fs_attachment_environment/readme/DESCRIPTION.md b/fs_attachment_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..9411ff1785 --- /dev/null +++ b/fs_attachment_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for fs_attachment to use fs_storage_environment diff --git a/fs_attachment_environment/static/description/icon.png b/fs_attachment_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/fs_attachment_environment/static/description/index.html b/fs_attachment_environment/static/description/index.html new file mode 100644 index 0000000000..4665787fe5 --- /dev/null +++ b/fs_attachment_environment/static/description/index.html @@ -0,0 +1,426 @@ + + + + + +Filesystem Attachment Backend + + + +
+

Filesystem Attachment Backend

+ + +

Beta License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Glue module for fs_attachment to use fs_storage_environment

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
  • Dixmit
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 2a28eef5af314e7222b5cf70582182c5656def42 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Thu, 4 Jun 2026 14:21:49 +0200 Subject: [PATCH 06/34] [FIX] fs_attachment: Add migration script for server_environment split --- fs_attachment/__manifest__.py | 2 +- fs_attachment/static/description/index.html | 56 +++++++++---------- .../upgrades/18.0.2.2.4/post-migration.py | 21 +++++++ 3 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 fs_attachment/upgrades/18.0.2.2.4/post-migration.py diff --git a/fs_attachment/__manifest__.py b/fs_attachment/__manifest__.py index c6c1ba9413..ef1a6fb5ab 100644 --- a/fs_attachment/__manifest__.py +++ b/fs_attachment/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Base Attachment Object Store", "summary": "Store attachments on external object store", - "version": "18.0.2.2.3", + "version": "18.0.2.2.4", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", "development_status": "Beta", diff --git a/fs_attachment/static/description/index.html b/fs_attachment/static/description/index.html index f3194d3593..8e3f785b54 100644 --- a/fs_attachment/static/description/index.html +++ b/fs_attachment/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Base Attachment Object Store -
+
+

Base Attachment Object Store

- - -Odoo Community Association - -
-

Base Attachment Object Store

-

Beta License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

In some cases, you need to store attachment in another system that the Odoo’s filestore. For example, when your deployment is based on a multi-server architecture to ensure redundancy and scalability, your @@ -453,9 +448,9 @@

Base Attachment Object Store

-

Usage

+

Usage

-

Configuration

+

Configuration

The configuration is done through the creation of a filesytem storage record into odoo. To create a new storage, go to the menu Settings > Technical > FS Storage and click on Create.

@@ -597,7 +592,7 @@

Configuration

-

Server Environment

+

Server Environment

When you configure a storage through the use of server environment file, you can provide values for the following keys:

-

Advanced usage: Using attachment as a file

+

Advanced usage: Using attachment as a file

The open method on the attachment can be used to open manipulate the attachment as a file object. The object returned by the call to the method implements methods from io.IOBase. The method can ba called @@ -666,7 +661,7 @@

Advanced usage: Using attachment

-

Tips & Tricks

+

Tips & Tricks

  • When working in multi staging environments, the management of the attachments can be tricky. For example, if you have a production @@ -696,11 +691,11 @@

    Tips & Tricks

-

Changelog

+

Changelog

-

18.0.2.2.0 (2025-10-20)

+

18.0.2.2.0 (2025-10-20)

-

Features

+

Features

  • Adapt to handle {db_name} in directory_path. (#db_name)
  • @@ -708,9 +703,9 @@

    Features

-

18.0.1.1.0 (2024-11-10)

+

18.0.1.1.0 (2024-11-10)

-

Bugfixes

+

Bugfixes

  • No crash o missign file.

    Prior to this change, Odoo was crashing as soon as access to a file @@ -724,7 +719,7 @@

    Bugfixes

-

16.0.1.0.8 (2023-12-20)

+

16.0.1.0.8 (2023-12-20)

Bugfixes

-

16.0.1.0.6 (2023-12-02)

+

16.0.1.0.6 (2023-12-02)

Bugfixes

-

16.0.1.0.5 (2023-11-29)

+

16.0.1.0.5 (2023-11-29)

Bugfixes

-

16.0.1.0.4 (2023-11-22)

+

16.0.1.0.4 (2023-11-22)

Bugfixes

-

16.0.1.0.3 (2023-10-17)

+

16.0.1.0.3 (2023-10-17)

Bugfixes

-

16.0.1.0.2 (2023-10-09)

+

16.0.1.0.2 (2023-10-09)

Bugfixes

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -800,16 +795,16 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Camptocamp
  • ACSONE SA/NV
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -844,6 +839,5 @@

Maintainers

-
diff --git a/fs_attachment/upgrades/18.0.2.2.4/post-migration.py b/fs_attachment/upgrades/18.0.2.2.4/post-migration.py new file mode 100644 index 0000000000..e6627838d5 --- /dev/null +++ b/fs_attachment/upgrades/18.0.2.2.4/post-migration.py @@ -0,0 +1,21 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search( + [("name", "=", "fs_attachment_environment")] + ) + if not module: + raise exceptions.UserError( + _( + "The 'fs_attachment_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'fs.storage'. Make it available on the " + "addons path before upgrading 'fs_attachment'." + ) + ) + if module.state == "uninstalled": + module.button_install() From 741aca43c06a174fa5663632849ebd9b95325781 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Wed, 19 Aug 2026 15:21:44 +0300 Subject: [PATCH 07/34] [IMP] fs_attachment_environment: preserve data on install and restore columns on uninstall --- fs_attachment_environment/__init__.py | 1 + fs_attachment_environment/__manifest__.py | 2 + fs_attachment_environment/hooks.py | 46 +++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 fs_attachment_environment/hooks.py diff --git a/fs_attachment_environment/__init__.py b/fs_attachment_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/fs_attachment_environment/__init__.py +++ b/fs_attachment_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/fs_attachment_environment/__manifest__.py b/fs_attachment_environment/__manifest__.py index d342edc411..2cbd06290d 100644 --- a/fs_attachment_environment/__manifest__.py +++ b/fs_attachment_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["fs_storage_environment", "fs_attachment"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/fs_attachment_environment/hooks.py b/fs_attachment_environment/hooks.py new file mode 100644 index 0000000000..f2fad32319 --- /dev/null +++ b/fs_attachment_environment/hooks.py @@ -0,0 +1,46 @@ +# Copyright 2026 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tools import SQL + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "optimizes_directory_path", + "autovacuum_gc", + "base_url", + "is_directory_path_in_url", + "use_x_sendfile_to_serve_internal_url", + "use_as_default_for_attachments", + "force_db_for_default_attachment_rules", + "use_filename_obfuscation", +] + + +def post_init_hook(env): + """Preserve fallback values without violating the attachment rule constraint. + + On a fresh install, Odoo initializes the new force database rules column on + existing storages with its non-empty default, even when the storage is not + the default attachment storage. The preservation helper writes fields back + through the ORM one at a time, so this temporary inconsistent state would + trigger the constraint. Normalize the stored fallback with SQL first. + """ + env.cr.execute( + SQL( + "UPDATE %s SET %s = NULL WHERE NOT COALESCE(%s, FALSE)", + SQL.identifier(env["fs.storage"]._table), + SQL.identifier("force_db_for_default_attachment_rules"), + SQL.identifier("use_as_default_for_attachments"), + ) + ) + env["fs.storage"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "fs.storage", + ENV_MANAGED_FIELDS, + ) From 723a47d8bb6d0c2540ba1404651629c1f540c884 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:33:56 +0200 Subject: [PATCH 08/34] [IMP] fs_attachment_s3: Remove environment data --- fs_attachment_s3/README.rst | 6 +----- fs_attachment_s3/models/fs_storage.py | 12 ------------ 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/fs_attachment_s3/README.rst b/fs_attachment_s3/README.rst index 790b298e67..5d6c92ee2f 100644 --- a/fs_attachment_s3/README.rst +++ b/fs_attachment_s3/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ================ Fs Attachment S3 ================ @@ -17,7 +13,7 @@ Fs Attachment S3 .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github diff --git a/fs_attachment_s3/models/fs_storage.py b/fs_attachment_s3/models/fs_storage.py index 1b737c722d..9007b85297 100644 --- a/fs_attachment_s3/models/fs_storage.py +++ b/fs_attachment_s3/models/fs_storage.py @@ -22,18 +22,6 @@ class FsStorage(models.Model): "Default is 30 seconds.", ) - @property - def _server_env_fields(self): - """Override to include S3 specific fields.""" - fields = super()._server_env_fields - fields.update( - { - "s3_uses_signed_url_for_x_sendfile": {}, - "s3_signed_url_expiration": {}, - } - ) - return fields - @property def is_s3_storage(self): """Check if the storage is an S3 storage.""" From 73c96f3aa5acfc2cd4620bcff52465f2f912e47a Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:34:31 +0200 Subject: [PATCH 09/34] [ADD] fs_attachment_s3_environemnt --- fs_attachment_s3_environment/README.rst | 79 ++++ fs_attachment_s3_environment/__init__.py | 1 + fs_attachment_s3_environment/__manifest__.py | 15 + .../models/__init__.py | 1 + .../models/fs_storage.py | 25 + fs_attachment_s3_environment/pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 3 + .../readme/DESCRIPTION.md | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 426 ++++++++++++++++++ 10 files changed, 554 insertions(+) create mode 100644 fs_attachment_s3_environment/README.rst create mode 100644 fs_attachment_s3_environment/__init__.py create mode 100644 fs_attachment_s3_environment/__manifest__.py create mode 100644 fs_attachment_s3_environment/models/__init__.py create mode 100644 fs_attachment_s3_environment/models/fs_storage.py create mode 100644 fs_attachment_s3_environment/pyproject.toml create mode 100644 fs_attachment_s3_environment/readme/CONTRIBUTORS.md create mode 100644 fs_attachment_s3_environment/readme/DESCRIPTION.md create mode 100644 fs_attachment_s3_environment/static/description/icon.png create mode 100644 fs_attachment_s3_environment/static/description/index.html diff --git a/fs_attachment_s3_environment/README.rst b/fs_attachment_s3_environment/README.rst new file mode 100644 index 0000000000..d91c12193f --- /dev/null +++ b/fs_attachment_s3_environment/README.rst @@ -0,0 +1,79 @@ +================================ +Filesystem Attachment Backend S3 +================================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:bbd1be658bbe5cda3a0ca2391c1de17eafb45624ac49610b3b2503c65d2610af + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/fs_attachment_s3_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_attachment_s3_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for fs_attachment to use fs_storage_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ACSONE SA/NV +* Dixmit + +Contributors +------------ + +- Laurent Mignon +- Sébastien BEAU +- Enric Tobella + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fs_attachment_s3_environment/__init__.py b/fs_attachment_s3_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/fs_attachment_s3_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/fs_attachment_s3_environment/__manifest__.py b/fs_attachment_s3_environment/__manifest__.py new file mode 100644 index 0000000000..6d978051b5 --- /dev/null +++ b/fs_attachment_s3_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Filesystem Attachment Backend S3", + "summary": "Allows to use server environment with fs storage attachment S3", + "version": "18.0.1.0.0", + "category": "FS Storage", + "website": "https://github.com/OCA/storage", + "author": " ACSONE SA/NV, Dixmit, Odoo Community Association (OCA)", + "license": "AGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["fs_attachment_environment", "fs_attachment_s3"], +} diff --git a/fs_attachment_s3_environment/models/__init__.py b/fs_attachment_s3_environment/models/__init__.py new file mode 100644 index 0000000000..349bb0495a --- /dev/null +++ b/fs_attachment_s3_environment/models/__init__.py @@ -0,0 +1 @@ +from . import fs_storage diff --git a/fs_attachment_s3_environment/models/fs_storage.py b/fs_attachment_s3_environment/models/fs_storage.py new file mode 100644 index 0000000000..3057681e7a --- /dev/null +++ b/fs_attachment_s3_environment/models/fs_storage.py @@ -0,0 +1,25 @@ +# Copyright 2023 ACSONE SA/NV (https://www.acsone.eu). +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +from __future__ import annotations + +import logging + +from odoo import models + +_logger = logging.getLogger(__name__) + + +class FSStorage(models.Model): + _inherit = "fs.storage" + + @property + def _server_env_fields(self): + """Override to include S3 specific fields.""" + fields = super()._server_env_fields + fields.update( + { + "s3_uses_signed_url_for_x_sendfile": {}, + "s3_signed_url_expiration": {}, + } + ) + return fields diff --git a/fs_attachment_s3_environment/pyproject.toml b/fs_attachment_s3_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/fs_attachment_s3_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/fs_attachment_s3_environment/readme/CONTRIBUTORS.md b/fs_attachment_s3_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..b4896734fa --- /dev/null +++ b/fs_attachment_s3_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- Laurent Mignon \ +- Sébastien BEAU \ +- Enric Tobella diff --git a/fs_attachment_s3_environment/readme/DESCRIPTION.md b/fs_attachment_s3_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..9411ff1785 --- /dev/null +++ b/fs_attachment_s3_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for fs_attachment to use fs_storage_environment diff --git a/fs_attachment_s3_environment/static/description/icon.png b/fs_attachment_s3_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/fs_attachment_s3_environment/static/description/index.html b/fs_attachment_s3_environment/static/description/index.html new file mode 100644 index 0000000000..f69aec169b --- /dev/null +++ b/fs_attachment_s3_environment/static/description/index.html @@ -0,0 +1,426 @@ + + + + + +Filesystem Attachment Backend S3 + + + +
+

Filesystem Attachment Backend S3

+ + +

Beta License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Glue module for fs_attachment to use fs_storage_environment

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
  • Dixmit
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 3e1baa75abb7f95a044587827b1156fd542d0752 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Thu, 4 Jun 2026 14:22:18 +0200 Subject: [PATCH 10/34] [FIX] fs_attachment_s3: Add migration script for server_environment split --- fs_attachment_s3/__manifest__.py | 2 +- .../static/description/index.html | 38 ++++++++----------- .../upgrades/18.0.1.2.2/post-migration.py | 21 ++++++++++ 3 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 fs_attachment_s3/upgrades/18.0.1.2.2/post-migration.py diff --git a/fs_attachment_s3/__manifest__.py b/fs_attachment_s3/__manifest__.py index f0228140aa..2bd5234857 100644 --- a/fs_attachment_s3/__manifest__.py +++ b/fs_attachment_s3/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Fs Attachment S3", "summary": """Store attachments into S3 complient filesystem""", - "version": "18.0.1.2.1", + "version": "18.0.1.2.2", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_attachment_s3/static/description/index.html b/fs_attachment_s3/static/description/index.html index 3443c3cb95..a3346bf8c8 100644 --- a/fs_attachment_s3/static/description/index.html +++ b/fs_attachment_s3/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Fs Attachment S3 -
+
+

Fs Attachment S3

- - -Odoo Community Association - -
-

Fs Attachment S3

-

Beta License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

This module extends the functionality of fs_attachment to better support Amazon S3 storage. It includes features such as:

@@ -411,7 +406,7 @@

Fs Attachment S3

-

Configuration

+

Configuration

On the Odoo instance, go to Settings > Technical > Storage > File Storage.

When you create a new storage for s3 or modify an existing one, when you @@ -476,11 +471,11 @@

Configuration

directory name as bucket name, and the file path.

-

Changelog

+

Changelog

-

18.0.1.2.1 (2026-05-27)

+

18.0.1.2.1 (2026-05-27)

-

Bugfixes

+

Bugfixes

  • Allow to use a prefix path and bucket in the directory_path on fs.storage When the directory_path parameter is configured as / the @@ -490,9 +485,9 @@

    Bugfixes

-

18.0.1.2.0 (2025-10-20)

+

18.0.1.2.0 (2025-10-20)

-

Features

+

Features

  • Adapt to handle {db_name} in directory_path. (#db_name)
  • @@ -501,7 +496,7 @@

    Features

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -509,22 +504,22 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
-

Other credits

+

Other credits

The development of this module has been financially supported by:

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -547,6 +542,5 @@

Maintainers

-
diff --git a/fs_attachment_s3/upgrades/18.0.1.2.2/post-migration.py b/fs_attachment_s3/upgrades/18.0.1.2.2/post-migration.py new file mode 100644 index 0000000000..19299f15da --- /dev/null +++ b/fs_attachment_s3/upgrades/18.0.1.2.2/post-migration.py @@ -0,0 +1,21 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search( + [("name", "=", "fs_attachment_s3_environment")] + ) + if not module: + raise exceptions.UserError( + _( + "The 'fs_attachment_s3_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'fs.storage'. Make it available on the " + "addons path before upgrading 'fs_attachment_s3'." + ) + ) + if module.state == "uninstalled": + module.button_install() From a7de763468fa73c690dc43a3e6982ae9b4f54a24 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Wed, 19 Aug 2026 15:23:48 +0300 Subject: [PATCH 11/34] [IMP] fs_attachment_s3_environment: preserve data on install and restore columns on uninstall --- fs_attachment_s3_environment/__init__.py | 1 + fs_attachment_s3_environment/__manifest__.py | 2 ++ fs_attachment_s3_environment/hooks.py | 22 ++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 fs_attachment_s3_environment/hooks.py diff --git a/fs_attachment_s3_environment/__init__.py b/fs_attachment_s3_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/fs_attachment_s3_environment/__init__.py +++ b/fs_attachment_s3_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/fs_attachment_s3_environment/__manifest__.py b/fs_attachment_s3_environment/__manifest__.py index 6d978051b5..49c3579f51 100644 --- a/fs_attachment_s3_environment/__manifest__.py +++ b/fs_attachment_s3_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["fs_attachment_environment", "fs_attachment_s3"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/fs_attachment_s3_environment/hooks.py b/fs_attachment_s3_environment/hooks.py new file mode 100644 index 0000000000..ab948acfd0 --- /dev/null +++ b/fs_attachment_s3_environment/hooks.py @@ -0,0 +1,22 @@ +# Copyright 2026 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "s3_uses_signed_url_for_x_sendfile", + "s3_signed_url_expiration", +] + + +def post_init_hook(env): + env["fs.storage"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "fs.storage", + ENV_MANAGED_FIELDS, + ) From de9788d4063ede73e990d8fc4a8c29b4b5d3588b Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:01 +0300 Subject: [PATCH 12/34] [IMP] storage_backend: Remove environment data --- storage_backend/README.rst | 6 +--- storage_backend/__manifest__.py | 4 +-- storage_backend/models/storage_backend.py | 6 +--- storage_backend/static/description/index.html | 30 ++++++++----------- 4 files changed, 16 insertions(+), 30 deletions(-) diff --git a/storage_backend/README.rst b/storage_backend/README.rst index e565dc2c16..0fab8e5f83 100644 --- a/storage_backend/README.rst +++ b/storage_backend/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - =============== Storage Backend =============== @@ -17,7 +13,7 @@ Storage Backend .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png :target: https://odoo-community.org/page/development-status :alt: Production/Stable -.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github diff --git a/storage_backend/__manifest__.py b/storage_backend/__manifest__.py index 54910063b2..b359c901bc 100644 --- a/storage_backend/__manifest__.py +++ b/storage_backend/__manifest__.py @@ -5,14 +5,14 @@ { "name": "Storage Backend", "summary": "Implement the concept of Storage with amazon S3, sftp...", - "version": "18.0.1.1.0", + "version": "18.0.1.1.1", "category": "Storage", "website": "https://github.com/OCA/storage", "author": " Akretion, Odoo Community Association (OCA)", "license": "LGPL-3", "development_status": "Production/Stable", "installable": True, - "depends": ["base", "component", "server_environment"], + "depends": ["base", "component"], "data": [ "views/backend_storage_view.xml", "views/storage_backend_category_view.xml", diff --git a/storage_backend/models/storage_backend.py b/storage_backend/models/storage_backend.py index bb8541d510..412820a021 100644 --- a/storage_backend/models/storage_backend.py +++ b/storage_backend/models/storage_backend.py @@ -55,7 +55,7 @@ def new_func1(*args, **kwargs): class StorageBackend(models.Model): _name = "storage.backend" - _inherit = ["collection.base", "server.env.mixin"] + _inherit = "collection.base" _backend_name = "storage_backend" _description = "Storage Backend" @@ -86,10 +86,6 @@ def _compute_has_validation(self): adapter = rec._get_adapter() rec.has_validation = hasattr(adapter, "validate_config") - @property - def _server_env_fields(self): - return {"backend_type": {}, "directory_path": {}} - def add(self, relative_path, data, binary=True, **kwargs): if not binary: data = base64.b64decode(data) diff --git a/storage_backend/static/description/index.html b/storage_backend/static/description/index.html index fa49bd30f7..3cff5eace3 100644 --- a/storage_backend/static/description/index.html +++ b/storage_backend/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Storage Backend -
+
+

Storage Backend

- - -Odoo Community Association - -
-

Storage Backend

-

Production/Stable License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Production/Stable License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

Table of contents

    @@ -391,13 +386,13 @@

    Storage Backend

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -405,15 +400,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Akretion
-

Contributors

+

Contributors

-

Other credits

+

Other credits

The migration of this module from 16.0 to 18.0 was financially supported by Camptocamp.

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -445,6 +440,5 @@

Maintainers

-
From 077e72d657847d27760b1a79f0be8b959ffecec2 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:08 +0300 Subject: [PATCH 13/34] [ADD] storage_backend_environment --- .../upgrades/18.0.1.1.1/post-update.py | 21 + storage_backend_environment/README.rst | 77 ++++ storage_backend_environment/__init__.py | 1 + storage_backend_environment/__manifest__.py | 15 + .../models/__init__.py | 1 + .../models/storage_backend.py | 12 + storage_backend_environment/pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 1 + .../readme/DESCRIPTION.md | 1 + .../readme/newsfragments/.gitignore | 0 .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 424 ++++++++++++++++++ 12 files changed, 556 insertions(+) create mode 100644 storage_backend/upgrades/18.0.1.1.1/post-update.py create mode 100644 storage_backend_environment/README.rst create mode 100644 storage_backend_environment/__init__.py create mode 100644 storage_backend_environment/__manifest__.py create mode 100644 storage_backend_environment/models/__init__.py create mode 100644 storage_backend_environment/models/storage_backend.py create mode 100644 storage_backend_environment/pyproject.toml create mode 100644 storage_backend_environment/readme/CONTRIBUTORS.md create mode 100644 storage_backend_environment/readme/DESCRIPTION.md create mode 100644 storage_backend_environment/readme/newsfragments/.gitignore create mode 100644 storage_backend_environment/static/description/icon.png create mode 100644 storage_backend_environment/static/description/index.html diff --git a/storage_backend/upgrades/18.0.1.1.1/post-update.py b/storage_backend/upgrades/18.0.1.1.1/post-update.py new file mode 100644 index 0000000000..d5fd1b6ad8 --- /dev/null +++ b/storage_backend/upgrades/18.0.1.1.1/post-update.py @@ -0,0 +1,21 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search( + [("name", "=", "storage_backend_environment")] + ) + if not module: + raise exceptions.UserError( + _( + "The 'storage_backend_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'storage.backend'. Make it available on the " + "addons path before upgrading 'storage_backend'." + ) + ) + if module.state == "uninstalled": + module.button_install() diff --git a/storage_backend_environment/README.rst b/storage_backend_environment/README.rst new file mode 100644 index 0000000000..d7aafc6750 --- /dev/null +++ b/storage_backend_environment/README.rst @@ -0,0 +1,77 @@ +=========================== +Storage Backend Environment +=========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:0000000000000000000000000000000000000000000000000000000000000000 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/storage_backend_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-storage_backend_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for storage_backend to use server_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Akretion +* Camptocamp + +Contributors +------------ + +- Sébastien BEAU + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/storage_backend_environment/__init__.py b/storage_backend_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/storage_backend_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/storage_backend_environment/__manifest__.py b/storage_backend_environment/__manifest__.py new file mode 100644 index 0000000000..b94d460480 --- /dev/null +++ b/storage_backend_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Storage Backend Environment", + "summary": "Allows to use server environment with storage backend", + "version": "18.0.1.0.0", + "category": "Storage", + "website": "https://github.com/OCA/storage", + "author": " Akretion, Camptocamp, Odoo Community Association (OCA)", + "license": "LGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["storage_backend", "server_environment"], +} diff --git a/storage_backend_environment/models/__init__.py b/storage_backend_environment/models/__init__.py new file mode 100644 index 0000000000..f45f402268 --- /dev/null +++ b/storage_backend_environment/models/__init__.py @@ -0,0 +1 @@ +from . import storage_backend diff --git a/storage_backend_environment/models/storage_backend.py b/storage_backend_environment/models/storage_backend.py new file mode 100644 index 0000000000..1297c7317d --- /dev/null +++ b/storage_backend_environment/models/storage_backend.py @@ -0,0 +1,12 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +from odoo import models + + +class StorageBackend(models.Model): + _name = "storage.backend" + _inherit = ["storage.backend", "server.env.mixin"] + + @property + def _server_env_fields(self): + return {"backend_type": {}, "directory_path": {}} diff --git a/storage_backend_environment/pyproject.toml b/storage_backend_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/storage_backend_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/storage_backend_environment/readme/CONTRIBUTORS.md b/storage_backend_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..2390547b4d --- /dev/null +++ b/storage_backend_environment/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Sébastien BEAU \ diff --git a/storage_backend_environment/readme/DESCRIPTION.md b/storage_backend_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..91a9864a9b --- /dev/null +++ b/storage_backend_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for storage_backend to use server_environment diff --git a/storage_backend_environment/readme/newsfragments/.gitignore b/storage_backend_environment/readme/newsfragments/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/storage_backend_environment/static/description/icon.png b/storage_backend_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/storage_backend_environment/static/description/index.html b/storage_backend_environment/static/description/index.html new file mode 100644 index 0000000000..7f76343057 --- /dev/null +++ b/storage_backend_environment/static/description/index.html @@ -0,0 +1,424 @@ + + + + + +Storage Backend Environment + + + +
+

Storage Backend Environment

+ + +

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Glue module for storage_backend to use server_environment

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 6df23dd2c69c15d48416c225624b5e4492d34584 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:35 +0300 Subject: [PATCH 14/34] [IMP] storage_backend_environment: preserve data on install and restore columns on uninstall --- storage_backend_environment/__init__.py | 1 + storage_backend_environment/__manifest__.py | 2 ++ storage_backend_environment/hooks.py | 22 +++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 storage_backend_environment/hooks.py diff --git a/storage_backend_environment/__init__.py b/storage_backend_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/storage_backend_environment/__init__.py +++ b/storage_backend_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/storage_backend_environment/__manifest__.py b/storage_backend_environment/__manifest__.py index b94d460480..51a7aa1d2f 100644 --- a/storage_backend_environment/__manifest__.py +++ b/storage_backend_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["storage_backend", "server_environment"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/storage_backend_environment/hooks.py b/storage_backend_environment/hooks.py new file mode 100644 index 0000000000..72372e4e0c --- /dev/null +++ b/storage_backend_environment/hooks.py @@ -0,0 +1,22 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "backend_type", + "directory_path", +] + + +def post_init_hook(env): + env["storage.backend"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "storage.backend", + ENV_MANAGED_FIELDS, + ) From 7d1b847a2e81c5f9e49d61e58fc75b5857174a77 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:59 +0300 Subject: [PATCH 15/34] [IMP] storage_backend_sftp: Remove environment data --- storage_backend_sftp/models/storage_backend.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/storage_backend_sftp/models/storage_backend.py b/storage_backend_sftp/models/storage_backend.py index f79870fbc6..826c4578dd 100644 --- a/storage_backend_sftp/models/storage_backend.py +++ b/storage_backend_sftp/models/storage_backend.py @@ -31,18 +31,3 @@ class StorageBackend(models.Model): "but to provide it via secret env variable. " "See `server_environment` docs.", ) - - @property - def _server_env_fields(self): - env_fields = super()._server_env_fields - env_fields.update( - { - "sftp_password": {}, - "sftp_login": {}, - "sftp_server": {}, - "sftp_port": {}, - "sftp_auth_method": {}, - "sftp_ssh_private_key": {}, - } - ) - return env_fields From 8e3c00e11a9c58171ac2af8bd04391f08de0f8c2 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:12:15 +0300 Subject: [PATCH 16/34] [ADD] storage_backend_sftp_environment --- storage_backend_sftp_environment/README.rst | 78 ++++ storage_backend_sftp_environment/__init__.py | 1 + .../__manifest__.py | 15 + .../models/__init__.py | 1 + .../models/storage_backend.py | 22 + .../pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 2 + .../readme/DESCRIPTION.md | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 425 ++++++++++++++++++ 10 files changed, 548 insertions(+) create mode 100644 storage_backend_sftp_environment/README.rst create mode 100644 storage_backend_sftp_environment/__init__.py create mode 100644 storage_backend_sftp_environment/__manifest__.py create mode 100644 storage_backend_sftp_environment/models/__init__.py create mode 100644 storage_backend_sftp_environment/models/storage_backend.py create mode 100644 storage_backend_sftp_environment/pyproject.toml create mode 100644 storage_backend_sftp_environment/readme/CONTRIBUTORS.md create mode 100644 storage_backend_sftp_environment/readme/DESCRIPTION.md create mode 100644 storage_backend_sftp_environment/static/description/icon.png create mode 100644 storage_backend_sftp_environment/static/description/index.html diff --git a/storage_backend_sftp_environment/README.rst b/storage_backend_sftp_environment/README.rst new file mode 100644 index 0000000000..cc60dbfa2d --- /dev/null +++ b/storage_backend_sftp_environment/README.rst @@ -0,0 +1,78 @@ +================================ +Storage Backend SFTP Environment +================================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:0000000000000000000000000000000000000000000000000000000000000000 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/storage_backend_sftp_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-storage_backend_sftp_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for storage_backend_sftp to use storage_backend_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Akretion +* Camptocamp + +Contributors +------------ + +- Sébastien BEAU +- Simone Orsi + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/storage_backend_sftp_environment/__init__.py b/storage_backend_sftp_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/storage_backend_sftp_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/storage_backend_sftp_environment/__manifest__.py b/storage_backend_sftp_environment/__manifest__.py new file mode 100644 index 0000000000..b07501b7cf --- /dev/null +++ b/storage_backend_sftp_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Storage Backend SFTP Environment", + "summary": "Allows to use server environment with storage backend SFTP", + "version": "18.0.1.0.0", + "category": "Storage", + "website": "https://github.com/OCA/storage", + "author": " Akretion, Camptocamp, Odoo Community Association (OCA)", + "license": "LGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["storage_backend_environment", "storage_backend_sftp"], +} diff --git a/storage_backend_sftp_environment/models/__init__.py b/storage_backend_sftp_environment/models/__init__.py new file mode 100644 index 0000000000..f45f402268 --- /dev/null +++ b/storage_backend_sftp_environment/models/__init__.py @@ -0,0 +1 @@ +from . import storage_backend diff --git a/storage_backend_sftp_environment/models/storage_backend.py b/storage_backend_sftp_environment/models/storage_backend.py new file mode 100644 index 0000000000..0a7fab21fe --- /dev/null +++ b/storage_backend_sftp_environment/models/storage_backend.py @@ -0,0 +1,22 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +from odoo import models + + +class StorageBackend(models.Model): + _inherit = "storage.backend" + + @property + def _server_env_fields(self): + env_fields = super()._server_env_fields + env_fields.update( + { + "sftp_password": {}, + "sftp_login": {}, + "sftp_server": {}, + "sftp_port": {}, + "sftp_auth_method": {}, + "sftp_ssh_private_key": {}, + } + ) + return env_fields diff --git a/storage_backend_sftp_environment/pyproject.toml b/storage_backend_sftp_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/storage_backend_sftp_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/storage_backend_sftp_environment/readme/CONTRIBUTORS.md b/storage_backend_sftp_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..0ac3138926 --- /dev/null +++ b/storage_backend_sftp_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Sébastien BEAU \ +- Simone Orsi diff --git a/storage_backend_sftp_environment/readme/DESCRIPTION.md b/storage_backend_sftp_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..1a183cbdc5 --- /dev/null +++ b/storage_backend_sftp_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for storage_backend_sftp to use storage_backend_environment diff --git a/storage_backend_sftp_environment/static/description/icon.png b/storage_backend_sftp_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/storage_backend_sftp_environment/static/description/index.html b/storage_backend_sftp_environment/static/description/index.html new file mode 100644 index 0000000000..7966e60f55 --- /dev/null +++ b/storage_backend_sftp_environment/static/description/index.html @@ -0,0 +1,425 @@ + + + + + +Storage Backend SFTP Environment + + + +
+

Storage Backend SFTP Environment

+ + +

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Glue module for storage_backend_sftp to use storage_backend_environment

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From deb8c9f07bb7d25ec5e38aec8555be03de02c7db Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:12:33 +0300 Subject: [PATCH 17/34] [FIX] storage_backend_sftp: Add migration script for server_environment split --- storage_backend_sftp/__manifest__.py | 2 +- .../upgrades/18.0.1.0.1/post-migration.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 storage_backend_sftp/upgrades/18.0.1.0.1/post-migration.py diff --git a/storage_backend_sftp/__manifest__.py b/storage_backend_sftp/__manifest__.py index 5679e59409..6fce6ac01f 100644 --- a/storage_backend_sftp/__manifest__.py +++ b/storage_backend_sftp/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Storage Backend SFTP", "summary": "Implement SFTP Storage", - "version": "18.0.1.0.0", + "version": "18.0.1.0.1", "category": "Storage", "website": "https://github.com/OCA/storage", "author": " Akretion,Odoo Community Association (OCA)", diff --git a/storage_backend_sftp/upgrades/18.0.1.0.1/post-migration.py b/storage_backend_sftp/upgrades/18.0.1.0.1/post-migration.py new file mode 100644 index 0000000000..9afb8d601d --- /dev/null +++ b/storage_backend_sftp/upgrades/18.0.1.0.1/post-migration.py @@ -0,0 +1,21 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search( + [("name", "=", "storage_backend_sftp_environment")] + ) + if not module: + raise exceptions.UserError( + _( + "The 'storage_backend_sftp_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'storage.backend'. Make it available on the " + "addons path before upgrading 'storage_backend_sftp'." + ) + ) + if module.state == "uninstalled": + module.button_install() From b43e94d62cd5d29af520f53f5e5f392f5b454dcd Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:12:53 +0300 Subject: [PATCH 18/34] [IMP] storage_backend_sftp_environment: preserve data on install and restore columns on uninstall --- storage_backend_sftp_environment/__init__.py | 1 + .../__manifest__.py | 2 ++ storage_backend_sftp_environment/hooks.py | 26 +++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 storage_backend_sftp_environment/hooks.py diff --git a/storage_backend_sftp_environment/__init__.py b/storage_backend_sftp_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/storage_backend_sftp_environment/__init__.py +++ b/storage_backend_sftp_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/storage_backend_sftp_environment/__manifest__.py b/storage_backend_sftp_environment/__manifest__.py index b07501b7cf..f0dde709f2 100644 --- a/storage_backend_sftp_environment/__manifest__.py +++ b/storage_backend_sftp_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["storage_backend_environment", "storage_backend_sftp"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/storage_backend_sftp_environment/hooks.py b/storage_backend_sftp_environment/hooks.py new file mode 100644 index 0000000000..20b9cbc05b --- /dev/null +++ b/storage_backend_sftp_environment/hooks.py @@ -0,0 +1,26 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "sftp_server", + "sftp_port", + "sftp_auth_method", + "sftp_login", + "sftp_password", + "sftp_ssh_private_key", +] + + +def post_init_hook(env): + env["storage.backend"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "storage.backend", + ENV_MANAGED_FIELDS, + ) From 5fbf123c057e2a3668c58bd48614f5e0c6111ec3 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:02:37 +0300 Subject: [PATCH 19/34] [IMP] fs_folder: Remove environment data --- fs_folder/models/fs_storage.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/fs_folder/models/fs_storage.py b/fs_folder/models/fs_storage.py index db7e57daca..7db38fc9ac 100644 --- a/fs_folder/models/fs_storage.py +++ b/fs_folder/models/fs_storage.py @@ -47,16 +47,6 @@ def _check_use_as_default_for_fs_contents(self): _("Only one storage can be used as default for filesystem contents.") ) - @property - def _server_env_fields(self): - env_fields = super()._server_env_fields - env_fields.update( - { - "use_as_default_for_fs_contents": {}, - } - ) - return env_fields - @api.model @tools.ormcache() def get_storage_code_for_fs_content_fallback(self) -> str | None: From ce257623e47b02b4f0e876243afacf7f2ad21f4a Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:03:59 +0300 Subject: [PATCH 20/34] [ADD] fs_folder_environment --- fs_folder_environment/README.rst | 78 ++++ fs_folder_environment/__init__.py | 1 + fs_folder_environment/__manifest__.py | 15 + fs_folder_environment/models/__init__.py | 1 + fs_folder_environment/models/fs_storage.py | 17 + fs_folder_environment/pyproject.toml | 3 + fs_folder_environment/readme/CONTRIBUTORS.md | 2 + fs_folder_environment/readme/DESCRIPTION.md | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 425 ++++++++++++++++++ 10 files changed, 543 insertions(+) create mode 100644 fs_folder_environment/README.rst create mode 100644 fs_folder_environment/__init__.py create mode 100644 fs_folder_environment/__manifest__.py create mode 100644 fs_folder_environment/models/__init__.py create mode 100644 fs_folder_environment/models/fs_storage.py create mode 100644 fs_folder_environment/pyproject.toml create mode 100644 fs_folder_environment/readme/CONTRIBUTORS.md create mode 100644 fs_folder_environment/readme/DESCRIPTION.md create mode 100644 fs_folder_environment/static/description/icon.png create mode 100644 fs_folder_environment/static/description/index.html diff --git a/fs_folder_environment/README.rst b/fs_folder_environment/README.rst new file mode 100644 index 0000000000..61f7ca6caf --- /dev/null +++ b/fs_folder_environment/README.rst @@ -0,0 +1,78 @@ +============================= +Filesystem Folder Environment +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:74857328367e1405bbce123c6d1bafafdbdc452b6a2de2c36e536ea8a77e6447 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/fs_folder_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-fs_folder_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for fs_folder to use fs_storage_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ACSONE SA/NV +* Camptocamp + +Contributors +------------ + +- Laurent Mignon +- Enric Tobella Alomar + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/fs_folder_environment/__init__.py b/fs_folder_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/fs_folder_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/fs_folder_environment/__manifest__.py b/fs_folder_environment/__manifest__.py new file mode 100644 index 0000000000..59b8f5a20f --- /dev/null +++ b/fs_folder_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Filesystem Folder Environment", + "summary": "Allows to use server environment with fs folder", + "version": "18.0.1.0.0", + "category": "FS Storage", + "website": "https://github.com/OCA/storage", + "author": "ACSONE SA/NV, Camptocamp, Odoo Community Association (OCA)", + "license": "LGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["fs_storage_environment", "fs_folder"], +} diff --git a/fs_folder_environment/models/__init__.py b/fs_folder_environment/models/__init__.py new file mode 100644 index 0000000000..349bb0495a --- /dev/null +++ b/fs_folder_environment/models/__init__.py @@ -0,0 +1 @@ +from . import fs_storage diff --git a/fs_folder_environment/models/fs_storage.py b/fs_folder_environment/models/fs_storage.py new file mode 100644 index 0000000000..9d48ace994 --- /dev/null +++ b/fs_folder_environment/models/fs_storage.py @@ -0,0 +1,17 @@ +# Copyright 2025 ACSONE SA/NV +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +from odoo import models + + +class FsStorage(models.Model): + _inherit = "fs.storage" + + @property + def _server_env_fields(self): + env_fields = super()._server_env_fields + env_fields.update( + { + "use_as_default_for_fs_contents": {}, + } + ) + return env_fields diff --git a/fs_folder_environment/pyproject.toml b/fs_folder_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/fs_folder_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/fs_folder_environment/readme/CONTRIBUTORS.md b/fs_folder_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..e5efec71e2 --- /dev/null +++ b/fs_folder_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Laurent Mignon \ +- Enric Tobella Alomar \ diff --git a/fs_folder_environment/readme/DESCRIPTION.md b/fs_folder_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..e8301e8c68 --- /dev/null +++ b/fs_folder_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for fs_folder to use fs_storage_environment diff --git a/fs_folder_environment/static/description/icon.png b/fs_folder_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/fs_folder_environment/static/description/index.html b/fs_folder_environment/static/description/index.html new file mode 100644 index 0000000000..ebd96ce997 --- /dev/null +++ b/fs_folder_environment/static/description/index.html @@ -0,0 +1,425 @@ + + + + + +Filesystem Folder Environment + + + +
+

Filesystem Folder Environment

+ + +

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Glue module for fs_folder to use fs_storage_environment

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/storage project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From e1c64fa4f7775457774d0b02fd1a28a5354b24d8 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:04:21 +0300 Subject: [PATCH 21/34] [FIX] fs_folder: Add migration script for server_environment split --- fs_folder/README.rst | 6 +-- fs_folder/__manifest__.py | 2 +- fs_folder/static/description/index.html | 46 ++++++++----------- .../upgrades/18.0.2.0.1/post-migration.py | 19 ++++++++ 4 files changed, 41 insertions(+), 32 deletions(-) create mode 100644 fs_folder/upgrades/18.0.2.0.1/post-migration.py diff --git a/fs_folder/README.rst b/fs_folder/README.rst index ad6c273206..f767310dd1 100644 --- a/fs_folder/README.rst +++ b/fs_folder/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ========= Fs Folder ========= @@ -17,7 +13,7 @@ Fs Folder .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github diff --git a/fs_folder/__manifest__.py b/fs_folder/__manifest__.py index 7b891d0e0c..d5ba4d50d7 100644 --- a/fs_folder/__manifest__.py +++ b/fs_folder/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Folder", "summary": """A module to link to Odoo records and manage from record forms forlders from external file systems """, - "version": "18.0.2.0.0", + "version": "18.0.2.0.1", "license": "LGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_folder/static/description/index.html b/fs_folder/static/description/index.html index 29220310e5..b75c15aba6 100644 --- a/fs_folder/static/description/index.html +++ b/fs_folder/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Fs Folder -
+
+

Fs Folder

- - -Odoo Community Association - -
-

Fs Folder

-

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

+

Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

If you need to link some specific models to a specific folder into an external filesystem and be able to manage the content of this folder from the model form view, this module is for you.

@@ -408,14 +403,14 @@

Fs Folder

-

Use Cases / Context

+

Use Cases / Context

Some organizations have a need to manage documents in an external filesystem next to odoo records. This module provides a generic way to do it through the use of a specialized field FsFolder that can be used in any Odoo model.

-

Usage

+

Usage

The module is a technical module providing a new field type to Odoo. It is not intended to be used directly by end-users. It is intended to be used by developers to create new modules that need to manage files in an @@ -438,7 +433,7 @@

Usage

  • how you can customize the field behavior
  • -

    Field declaration

    +

    Field declaration

    To declare a field of this type in a model, you need to import the field type and declare it in the model definition. By default, the field declaration requires no parampeters.

    @@ -562,12 +557,12 @@

    Field declaration

    -

    Security

    +

    Security

    Important: The security of the field should be managed by the filesystem backend.
    -

    In the python code

    +

    In the python code

    The initialization of the field value is only allowed if the user has write access to the record. From the field value, the user can get access to the filesystem client and interact with the filesystem. The @@ -576,7 +571,7 @@

    In the python code

    filesystem.

    -

    In the form view through widget

    +

    In the form view through widget

    The addon comes with a specific widget that will be used to display the field in the form view. The widget will display the folder content and allow the user to interact with it. The user can create, delete, rename, @@ -590,7 +585,7 @@

    In the form view through widget

    -

    Interacting with the filesystem

    +

    Interacting with the filesystem

    To interact with the filesystem you can simply use the filesystem client provided by the field value.

    @@ -608,13 +603,13 @@ 

    Interacting with the filesystem

    -

    Customizing the field behavior

    +

    Customizing the field behavior

    As specified above, you can define some methods to customize the field behavior. During the process of creating a directory in a filesystem, 1 additional mechanism comes into play to guarantee the conformity of the directory created.

    -

    Folder name conformity

    +

    Folder name conformity

    When it comes to creating a folder in the filesystem, we must prevent the use of special characters that could cause problems. This is done by default by the field when creating the folder by replacing the @@ -626,7 +621,7 @@

    Folder name conformity

    applies to the full path of the folder).

    -

    Other customizations

    +

    Other customizations

    In addition you can:

    • override the adapter that will be used to convert the field value to a @@ -641,7 +636,7 @@

      Other customizations

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -649,22 +644,22 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • ACSONE SA/NV
    -

    Other credits

    +

    Other credits

    The development of this module has been financially supported by:

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -687,6 +682,5 @@

    Maintainers

    -
    diff --git a/fs_folder/upgrades/18.0.2.0.1/post-migration.py b/fs_folder/upgrades/18.0.2.0.1/post-migration.py new file mode 100644 index 0000000000..5fe9c09eec --- /dev/null +++ b/fs_folder/upgrades/18.0.2.0.1/post-migration.py @@ -0,0 +1,19 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search([("name", "=", "fs_folder_environment")]) + if not module: + raise exceptions.UserError( + _( + "The 'fs_folder_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'fs.storage'. Make it available on the " + "addons path before upgrading 'fs_folder'." + ) + ) + if module.state == "uninstalled": + module.button_install() From 412937577bf3316a94aa7c951a87e675052fe9e4 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:05:05 +0300 Subject: [PATCH 22/34] [IMP] fs_folder_environment: preserve data on install and restore columns on uninstall --- fs_folder_environment/__init__.py | 1 + fs_folder_environment/__manifest__.py | 2 ++ fs_folder_environment/hooks.py | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 fs_folder_environment/hooks.py diff --git a/fs_folder_environment/__init__.py b/fs_folder_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/fs_folder_environment/__init__.py +++ b/fs_folder_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/fs_folder_environment/__manifest__.py b/fs_folder_environment/__manifest__.py index 59b8f5a20f..e300ff815b 100644 --- a/fs_folder_environment/__manifest__.py +++ b/fs_folder_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["fs_storage_environment", "fs_folder"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/fs_folder_environment/hooks.py b/fs_folder_environment/hooks.py new file mode 100644 index 0000000000..d405b216d4 --- /dev/null +++ b/fs_folder_environment/hooks.py @@ -0,0 +1,21 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "use_as_default_for_fs_contents", +] + + +def post_init_hook(env): + env["fs.storage"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "fs.storage", + ENV_MANAGED_FIELDS, + ) From 81207e5065d162913c86c118cee30893073c9cf4 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:05:40 +0300 Subject: [PATCH 23/34] [IMP] storage_backend_ftp: Remove environment data --- storage_backend_ftp/models/storage_backend.py | 16 ---------------- storage_backend_ftp/tests/test_ftp.py | 1 + 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/storage_backend_ftp/models/storage_backend.py b/storage_backend_ftp/models/storage_backend.py index 25fb0ea182..61231963af 100644 --- a/storage_backend_ftp/models/storage_backend.py +++ b/storage_backend_ftp/models/storage_backend.py @@ -37,19 +37,3 @@ class StorageBackend(models.Model): ftp_login = fields.Char(string="FTP Login", help="Login to connect to ftp server") ftp_password = fields.Char(string="FTP Password") ftp_passive = fields.Boolean(string="FTP Passive", default=False) - - @property - def _server_env_fields(self): - env_fields = super()._server_env_fields - env_fields.update( - { - "ftp_password": {}, - "ftp_login": {}, - "ftp_server": {}, - "ftp_port": {}, - "ftp_encryption": {}, - "ftp_security": {}, - "ftp_passive": {}, - } - ) - return env_fields diff --git a/storage_backend_ftp/tests/test_ftp.py b/storage_backend_ftp/tests/test_ftp.py index 96bb962c66..29d310e18c 100644 --- a/storage_backend_ftp/tests/test_ftp.py +++ b/storage_backend_ftp/tests/test_ftp.py @@ -33,6 +33,7 @@ def setUpClass(cls): "ftp_port": os.environ.get("FTP_PORT", "21"), "directory_path": "upload", "ftp_encryption": "ftp", + "ftp_security": "none", } ) cls.case_with_subdirectory = "upload/subdirectory/here" From 22611ffdbab28fe7b3979d8768a8d8f140b8087b Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:07:10 +0300 Subject: [PATCH 24/34] [ADD] storage_backend_ftp_environment --- storage_backend_ftp_environment/README.rst | 79 ++++ storage_backend_ftp_environment/__init__.py | 1 + .../__manifest__.py | 15 + .../models/__init__.py | 1 + .../models/storage_backend.py | 23 + .../pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 3 + .../readme/DESCRIPTION.md | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 426 ++++++++++++++++++ 10 files changed, 552 insertions(+) create mode 100644 storage_backend_ftp_environment/README.rst create mode 100644 storage_backend_ftp_environment/__init__.py create mode 100644 storage_backend_ftp_environment/__manifest__.py create mode 100644 storage_backend_ftp_environment/models/__init__.py create mode 100644 storage_backend_ftp_environment/models/storage_backend.py create mode 100644 storage_backend_ftp_environment/pyproject.toml create mode 100644 storage_backend_ftp_environment/readme/CONTRIBUTORS.md create mode 100644 storage_backend_ftp_environment/readme/DESCRIPTION.md create mode 100644 storage_backend_ftp_environment/static/description/icon.png create mode 100644 storage_backend_ftp_environment/static/description/index.html diff --git a/storage_backend_ftp_environment/README.rst b/storage_backend_ftp_environment/README.rst new file mode 100644 index 0000000000..00384d01fa --- /dev/null +++ b/storage_backend_ftp_environment/README.rst @@ -0,0 +1,79 @@ +=============================== +Storage Backend FTP Environment +=============================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:b2952bd81a90b56184bc8b1006723a4a593c2085d4f872e9b1c77b7628309c14 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/storage_backend_ftp_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-storage_backend_ftp_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for storage_backend_ftp to use storage_backend_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Acsone SA/NV +* Camptocamp + +Contributors +------------ + +- François Honoré +- Lois Rilo +- thienvh + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/storage_backend_ftp_environment/__init__.py b/storage_backend_ftp_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/storage_backend_ftp_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/storage_backend_ftp_environment/__manifest__.py b/storage_backend_ftp_environment/__manifest__.py new file mode 100644 index 0000000000..f303ed780e --- /dev/null +++ b/storage_backend_ftp_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Storage Backend FTP Environment", + "summary": "Allows to use server environment with storage backend FTP", + "version": "18.0.1.0.0", + "category": "Storage", + "website": "https://github.com/OCA/storage", + "author": "Acsone SA/NV, Camptocamp, Odoo Community Association (OCA)", + "license": "LGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["storage_backend_environment", "storage_backend_ftp"], +} diff --git a/storage_backend_ftp_environment/models/__init__.py b/storage_backend_ftp_environment/models/__init__.py new file mode 100644 index 0000000000..f45f402268 --- /dev/null +++ b/storage_backend_ftp_environment/models/__init__.py @@ -0,0 +1 @@ +from . import storage_backend diff --git a/storage_backend_ftp_environment/models/storage_backend.py b/storage_backend_ftp_environment/models/storage_backend.py new file mode 100644 index 0000000000..9535ae6992 --- /dev/null +++ b/storage_backend_ftp_environment/models/storage_backend.py @@ -0,0 +1,23 @@ +# Copyright 2021 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import models + + +class StorageBackend(models.Model): + _inherit = "storage.backend" + + @property + def _server_env_fields(self): + env_fields = super()._server_env_fields + env_fields.update( + { + "ftp_password": {}, + "ftp_login": {}, + "ftp_server": {}, + "ftp_port": {}, + "ftp_encryption": {}, + "ftp_security": {}, + "ftp_passive": {}, + } + ) + return env_fields diff --git a/storage_backend_ftp_environment/pyproject.toml b/storage_backend_ftp_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/storage_backend_ftp_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/storage_backend_ftp_environment/readme/CONTRIBUTORS.md b/storage_backend_ftp_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..25252eb455 --- /dev/null +++ b/storage_backend_ftp_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- François Honoré \ +- Lois Rilo \ +- thienvh \ diff --git a/storage_backend_ftp_environment/readme/DESCRIPTION.md b/storage_backend_ftp_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..8c03e93a7e --- /dev/null +++ b/storage_backend_ftp_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for storage_backend_ftp to use storage_backend_environment diff --git a/storage_backend_ftp_environment/static/description/icon.png b/storage_backend_ftp_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/storage_backend_ftp_environment/static/description/index.html b/storage_backend_ftp_environment/static/description/index.html new file mode 100644 index 0000000000..9580304799 --- /dev/null +++ b/storage_backend_ftp_environment/static/description/index.html @@ -0,0 +1,426 @@ + + + + + +Storage Backend FTP Environment + + + +
    +

    Storage Backend FTP Environment

    + + +

    Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    +

    Glue module for storage_backend_ftp to use storage_backend_environment

    +

    Table of contents

    + +
    +

    Bug Tracker

    +

    Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

    +

    Do not contact contributors directly about support or help with technical issues.

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • Acsone SA/NV
    • +
    • Camptocamp
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    + +Odoo Community Association + +

    OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

    +

    This module is part of the OCA/storage project on GitHub.

    +

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    +
    +
    +
    + + From 43f15c8d1fe6a8ee072fed4d1cc2447356bbec8b Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:07:33 +0300 Subject: [PATCH 25/34] [FIX] storage_backend_ftp: Add migration script for server_environment split --- storage_backend_ftp/__manifest__.py | 2 +- .../upgrades/18.0.1.0.1/post-migration.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 storage_backend_ftp/upgrades/18.0.1.0.1/post-migration.py diff --git a/storage_backend_ftp/__manifest__.py b/storage_backend_ftp/__manifest__.py index 091a2ccbcd..0e5bf12b74 100644 --- a/storage_backend_ftp/__manifest__.py +++ b/storage_backend_ftp/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Storage Backend FTP", "summary": "Implement FTP Storage", - "version": "18.0.1.0.0", + "version": "18.0.1.0.1", "category": "Storage", "website": "https://github.com/OCA/storage", "author": " Acsone SA/NV,Odoo Community Association (OCA)", diff --git a/storage_backend_ftp/upgrades/18.0.1.0.1/post-migration.py b/storage_backend_ftp/upgrades/18.0.1.0.1/post-migration.py new file mode 100644 index 0000000000..ecb8998491 --- /dev/null +++ b/storage_backend_ftp/upgrades/18.0.1.0.1/post-migration.py @@ -0,0 +1,21 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search( + [("name", "=", "storage_backend_ftp_environment")] + ) + if not module: + raise exceptions.UserError( + _( + "The 'storage_backend_ftp_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'storage.backend'. Make it available on the " + "addons path before upgrading 'storage_backend_ftp'." + ) + ) + if module.state == "uninstalled": + module.button_install() From 0e35a2b1ce879aa9c04a3a62a1e8f0e23de83f34 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:08:11 +0300 Subject: [PATCH 26/34] [IMP] storage_backend_ftp_environment: preserve data on install and restore columns on uninstall --- storage_backend_ftp/models/storage_backend.py | 1 + storage_backend_ftp_environment/__init__.py | 1 + .../__manifest__.py | 2 ++ storage_backend_ftp_environment/hooks.py | 28 +++++++++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 storage_backend_ftp_environment/hooks.py diff --git a/storage_backend_ftp/models/storage_backend.py b/storage_backend_ftp/models/storage_backend.py index 61231963af..e58cbbdbf7 100644 --- a/storage_backend_ftp/models/storage_backend.py +++ b/storage_backend_ftp/models/storage_backend.py @@ -32,6 +32,7 @@ class StorageBackend(models.Model): ("sslv23", "SSLv23"), ("sslv3", "SSLv3"), ], + default="none", required=True, ) ftp_login = fields.Char(string="FTP Login", help="Login to connect to ftp server") diff --git a/storage_backend_ftp_environment/__init__.py b/storage_backend_ftp_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/storage_backend_ftp_environment/__init__.py +++ b/storage_backend_ftp_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/storage_backend_ftp_environment/__manifest__.py b/storage_backend_ftp_environment/__manifest__.py index f303ed780e..5e1572ef50 100644 --- a/storage_backend_ftp_environment/__manifest__.py +++ b/storage_backend_ftp_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["storage_backend_environment", "storage_backend_ftp"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/storage_backend_ftp_environment/hooks.py b/storage_backend_ftp_environment/hooks.py new file mode 100644 index 0000000000..c022bb4efa --- /dev/null +++ b/storage_backend_ftp_environment/hooks.py @@ -0,0 +1,28 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "ftp_password", + "ftp_login", + "ftp_server", + "ftp_port", + "ftp_encryption", + "ftp_security", + "ftp_passive", +] + + +def post_init_hook(env): + env["storage.backend"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "storage.backend", + ENV_MANAGED_FIELDS, + field_defaults={"ftp_security": "none"}, + ) From 243bcb52b90515dbbbe90f32d916a23316e6d380 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:08:43 +0300 Subject: [PATCH 27/34] [IMP] storage_backend_s3: Remove environment data --- storage_backend_s3/models/storage_backend.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/storage_backend_s3/models/storage_backend.py b/storage_backend_s3/models/storage_backend.py index 52d8c36f6d..83eba84d7e 100644 --- a/storage_backend_s3/models/storage_backend.py +++ b/storage_backend_s3/models/storage_backend.py @@ -40,23 +40,6 @@ class StorageBackend(models.Model): ] ) - @property - def _server_env_fields(self): - env_fields = super()._server_env_fields - env_fields.update( - { - "aws_host": {}, - "aws_bucket": {}, - "aws_access_key_id": {}, - "aws_secret_access_key": {}, - "aws_region": {}, - "aws_other_region": {}, - "aws_cache_control": {}, - "aws_file_acl": {}, - } - ) - return env_fields - def _selection_aws_region(self): return ( [("", "None")] From 5f7e75326093a2588e906fa7819b613846845c15 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:10:02 +0300 Subject: [PATCH 28/34] [ADD] storage_backend_s3_environment --- storage_backend_s3_environment/README.rst | 79 ++++ storage_backend_s3_environment/__init__.py | 1 + .../__manifest__.py | 15 + .../models/__init__.py | 1 + .../models/storage_backend.py | 24 + storage_backend_s3_environment/pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 3 + .../readme/DESCRIPTION.md | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 426 ++++++++++++++++++ 10 files changed, 553 insertions(+) create mode 100644 storage_backend_s3_environment/README.rst create mode 100644 storage_backend_s3_environment/__init__.py create mode 100644 storage_backend_s3_environment/__manifest__.py create mode 100644 storage_backend_s3_environment/models/__init__.py create mode 100644 storage_backend_s3_environment/models/storage_backend.py create mode 100644 storage_backend_s3_environment/pyproject.toml create mode 100644 storage_backend_s3_environment/readme/CONTRIBUTORS.md create mode 100644 storage_backend_s3_environment/readme/DESCRIPTION.md create mode 100644 storage_backend_s3_environment/static/description/icon.png create mode 100644 storage_backend_s3_environment/static/description/index.html diff --git a/storage_backend_s3_environment/README.rst b/storage_backend_s3_environment/README.rst new file mode 100644 index 0000000000..0fe2da79d7 --- /dev/null +++ b/storage_backend_s3_environment/README.rst @@ -0,0 +1,79 @@ +============================== +Storage Backend S3 Environment +============================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c4af3e96c0589be3f8d7da30b13c45f0b6f147ebc3e20381818816d3508e1718 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/storage_backend_s3_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-storage_backend_s3_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for storage_backend_s3 to use storage_backend_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Akretion +* Camptocamp + +Contributors +------------ + +- Sebastien Beau +- Raphaël Reverdy +- Simone Orsi + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/storage_backend_s3_environment/__init__.py b/storage_backend_s3_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/storage_backend_s3_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/storage_backend_s3_environment/__manifest__.py b/storage_backend_s3_environment/__manifest__.py new file mode 100644 index 0000000000..b0d87e96e4 --- /dev/null +++ b/storage_backend_s3_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Storage Backend S3 Environment", + "summary": "Allows to use server environment with storage backend S3", + "version": "18.0.1.0.0", + "category": "Storage", + "website": "https://github.com/OCA/storage", + "author": "Akretion, Camptocamp, Odoo Community Association (OCA)", + "license": "LGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["storage_backend_environment", "storage_backend_s3"], +} diff --git a/storage_backend_s3_environment/models/__init__.py b/storage_backend_s3_environment/models/__init__.py new file mode 100644 index 0000000000..f45f402268 --- /dev/null +++ b/storage_backend_s3_environment/models/__init__.py @@ -0,0 +1 @@ +from . import storage_backend diff --git a/storage_backend_s3_environment/models/storage_backend.py b/storage_backend_s3_environment/models/storage_backend.py new file mode 100644 index 0000000000..7e08242ab4 --- /dev/null +++ b/storage_backend_s3_environment/models/storage_backend.py @@ -0,0 +1,24 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +from odoo import models + + +class StorageBackend(models.Model): + _inherit = "storage.backend" + + @property + def _server_env_fields(self): + env_fields = super()._server_env_fields + env_fields.update( + { + "aws_host": {}, + "aws_bucket": {}, + "aws_access_key_id": {}, + "aws_secret_access_key": {}, + "aws_region": {}, + "aws_other_region": {}, + "aws_cache_control": {}, + "aws_file_acl": {}, + } + ) + return env_fields diff --git a/storage_backend_s3_environment/pyproject.toml b/storage_backend_s3_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/storage_backend_s3_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/storage_backend_s3_environment/readme/CONTRIBUTORS.md b/storage_backend_s3_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..e19ee0be6b --- /dev/null +++ b/storage_backend_s3_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- Sebastien Beau \ +- Raphaël Reverdy \ +- Simone Orsi \ diff --git a/storage_backend_s3_environment/readme/DESCRIPTION.md b/storage_backend_s3_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..143e5aee46 --- /dev/null +++ b/storage_backend_s3_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for storage_backend_s3 to use storage_backend_environment diff --git a/storage_backend_s3_environment/static/description/icon.png b/storage_backend_s3_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/storage_backend_s3_environment/static/description/index.html b/storage_backend_s3_environment/static/description/index.html new file mode 100644 index 0000000000..135dbaa99f --- /dev/null +++ b/storage_backend_s3_environment/static/description/index.html @@ -0,0 +1,426 @@ + + + + + +Storage Backend S3 Environment + + + +
    +

    Storage Backend S3 Environment

    + + +

    Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    +

    Glue module for storage_backend_s3 to use storage_backend_environment

    +

    Table of contents

    + +
    +

    Bug Tracker

    +

    Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

    +

    Do not contact contributors directly about support or help with technical issues.

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • Akretion
    • +
    • Camptocamp
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    + +Odoo Community Association + +

    OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

    +

    This module is part of the OCA/storage project on GitHub.

    +

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    +
    +
    +
    + + From 2e2640bab760325d833b888841620ddaedd1a5f8 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:10:26 +0300 Subject: [PATCH 29/34] [FIX] storage_backend_s3: Add migration script for server_environment split --- storage_backend_s3/README.rst | 6 +--- storage_backend_s3/__manifest__.py | 2 +- .../static/description/index.html | 30 ++++++++----------- .../upgrades/18.0.1.1.1/post-migration.py | 21 +++++++++++++ 4 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 storage_backend_s3/upgrades/18.0.1.1.1/post-migration.py diff --git a/storage_backend_s3/README.rst b/storage_backend_s3/README.rst index 4434278e6b..d5a1540aac 100644 --- a/storage_backend_s3/README.rst +++ b/storage_backend_s3/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ================== Storage Backend S3 ================== @@ -17,7 +13,7 @@ Storage Backend S3 .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github diff --git a/storage_backend_s3/__manifest__.py b/storage_backend_s3/__manifest__.py index 3775631d9a..bf44a19134 100644 --- a/storage_backend_s3/__manifest__.py +++ b/storage_backend_s3/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Storage Backend S3", "summary": "Implement amazon S3 Storage", - "version": "18.0.1.1.0", + "version": "18.0.1.1.1", "category": "Storage", "website": "https://github.com/OCA/storage", "author": " Akretion, Odoo Community Association (OCA)", diff --git a/storage_backend_s3/static/description/index.html b/storage_backend_s3/static/description/index.html index 19f306780f..713e0cf58b 100644 --- a/storage_backend_s3/static/description/index.html +++ b/storage_backend_s3/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Storage Backend S3 -
    +
    +

    Storage Backend S3

    - - -Odoo Community Association - -
    -

    Storage Backend S3

    -

    Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    +

    Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    Add the possibility to store and get data from amazon S3 for your storage backend

    Table of contents

    @@ -393,7 +388,7 @@

    Storage Backend S3

    -

    Configuration

    +

    Configuration

    Go to “Technical -> Storage backend -> Storage backend” and create a new backend of type “Amazon S3”.

    Example of configuration via env

    @@ -412,13 +407,13 @@

    Configuration

    -

    Known issues / Roadmap

    +

    Known issues / Roadmap

    There is an issue with the latest version of boto3 and urllib3 - boto3 needs to be boto3<=1.15.18 related with https://github.com/OCA/storage/issues/67

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -426,15 +421,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Akretion
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The migration of this module from 15.0 to 18.0 was financially supported by Camptocamp.

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -460,6 +455,5 @@

    Maintainers

    -
    diff --git a/storage_backend_s3/upgrades/18.0.1.1.1/post-migration.py b/storage_backend_s3/upgrades/18.0.1.1.1/post-migration.py new file mode 100644 index 0000000000..d04e4d8fa7 --- /dev/null +++ b/storage_backend_s3/upgrades/18.0.1.1.1/post-migration.py @@ -0,0 +1,21 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search( + [("name", "=", "storage_backend_s3_environment")] + ) + if not module: + raise exceptions.UserError( + _( + "The 'storage_backend_s3_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'storage.backend'. Make it available on the " + "addons path before upgrading 'storage_backend_s3'." + ) + ) + if module.state == "uninstalled": + module.button_install() From eb62422eb49889ae6bbea9bcda43903a7f9d9261 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:11:09 +0300 Subject: [PATCH 30/34] [IMP] storage_backend_s3_environment: preserve data on install and restore columns on uninstall --- storage_backend_s3_environment/__init__.py | 1 + .../__manifest__.py | 2 ++ storage_backend_s3_environment/hooks.py | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 storage_backend_s3_environment/hooks.py diff --git a/storage_backend_s3_environment/__init__.py b/storage_backend_s3_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/storage_backend_s3_environment/__init__.py +++ b/storage_backend_s3_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/storage_backend_s3_environment/__manifest__.py b/storage_backend_s3_environment/__manifest__.py index b0d87e96e4..824d6c30f9 100644 --- a/storage_backend_s3_environment/__manifest__.py +++ b/storage_backend_s3_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["storage_backend_environment", "storage_backend_s3"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/storage_backend_s3_environment/hooks.py b/storage_backend_s3_environment/hooks.py new file mode 100644 index 0000000000..c25343f335 --- /dev/null +++ b/storage_backend_s3_environment/hooks.py @@ -0,0 +1,28 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "aws_host", + "aws_bucket", + "aws_access_key_id", + "aws_secret_access_key", + "aws_region", + "aws_other_region", + "aws_cache_control", + "aws_file_acl", +] + + +def post_init_hook(env): + env["storage.backend"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "storage.backend", + ENV_MANAGED_FIELDS, + ) From c32d15a9fbb6b40f6481e205facc03c8fe17a624 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:11:45 +0300 Subject: [PATCH 31/34] [IMP] storage_file: Remove environment data --- storage_file/models/storage_backend.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/storage_file/models/storage_backend.py b/storage_file/models/storage_backend.py index e011180b1b..0304cda3ff 100644 --- a/storage_file/models/storage_backend.py +++ b/storage_file/models/storage_backend.py @@ -71,19 +71,6 @@ def write(self, vals): self.action_recompute_base_url_for_files() return res - @property - def _server_env_fields(self): - env_fields = super()._server_env_fields - env_fields.update( - { - "filename_strategy": {}, - "served_by": {}, - "base_url": {}, - "url_include_directory_path": {}, - } - ) - return env_fields - _default_backend_xid = "storage_backend.default_storage_backend" @classmethod From fedf9b75842ed5dfa521ff7ce440634684ab1a5c Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:12:59 +0300 Subject: [PATCH 32/34] [ADD] storage_file_environment --- storage_file_environment/README.rst | 80 ++++ storage_file_environment/__init__.py | 1 + storage_file_environment/__manifest__.py | 15 + storage_file_environment/models/__init__.py | 1 + .../models/storage_backend.py | 20 + storage_file_environment/pyproject.toml | 3 + .../readme/CONTRIBUTORS.md | 4 + .../readme/DESCRIPTION.md | 1 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 427 ++++++++++++++++++ 10 files changed, 552 insertions(+) create mode 100644 storage_file_environment/README.rst create mode 100644 storage_file_environment/__init__.py create mode 100644 storage_file_environment/__manifest__.py create mode 100644 storage_file_environment/models/__init__.py create mode 100644 storage_file_environment/models/storage_backend.py create mode 100644 storage_file_environment/pyproject.toml create mode 100644 storage_file_environment/readme/CONTRIBUTORS.md create mode 100644 storage_file_environment/readme/DESCRIPTION.md create mode 100644 storage_file_environment/static/description/icon.png create mode 100644 storage_file_environment/static/description/index.html diff --git a/storage_file_environment/README.rst b/storage_file_environment/README.rst new file mode 100644 index 0000000000..1dd24b112b --- /dev/null +++ b/storage_file_environment/README.rst @@ -0,0 +1,80 @@ +======================== +Storage File Environment +======================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:2b84e5452f23dff857217d16795cfd2aafc13bc76365c975c9f8799a30806278 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github + :target: https://github.com/OCA/storage/tree/18.0/storage_file_environment + :alt: OCA/storage +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/storage-18-0/storage-18-0-storage_file_environment + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Glue module for storage_file to use storage_backend_environment + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Akretion +* Camptocamp + +Contributors +------------ + +- Sebastien Beau +- Raphaël Reverdy +- Vo Hong Thien +- Simone Orsi + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/storage `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/storage_file_environment/__init__.py b/storage_file_environment/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/storage_file_environment/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/storage_file_environment/__manifest__.py b/storage_file_environment/__manifest__.py new file mode 100644 index 0000000000..7e65ee8729 --- /dev/null +++ b/storage_file_environment/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Storage File Environment", + "summary": "Allows to use server environment with storage file", + "version": "18.0.1.0.0", + "category": "Storage", + "website": "https://github.com/OCA/storage", + "author": "Akretion, Camptocamp, Odoo Community Association (OCA)", + "license": "LGPL-3", + "development_status": "Beta", + "installable": True, + "depends": ["storage_backend_environment", "storage_file"], +} diff --git a/storage_file_environment/models/__init__.py b/storage_file_environment/models/__init__.py new file mode 100644 index 0000000000..f45f402268 --- /dev/null +++ b/storage_file_environment/models/__init__.py @@ -0,0 +1 @@ +from . import storage_backend diff --git a/storage_file_environment/models/storage_backend.py b/storage_file_environment/models/storage_backend.py new file mode 100644 index 0000000000..9c4ac9c2f2 --- /dev/null +++ b/storage_file_environment/models/storage_backend.py @@ -0,0 +1,20 @@ +# Copyright 2017 Akretion (http://www.akretion.com). +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +from odoo import models + + +class StorageBackend(models.Model): + _inherit = "storage.backend" + + @property + def _server_env_fields(self): + env_fields = super()._server_env_fields + env_fields.update( + { + "filename_strategy": {}, + "served_by": {}, + "base_url": {}, + "url_include_directory_path": {}, + } + ) + return env_fields diff --git a/storage_file_environment/pyproject.toml b/storage_file_environment/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/storage_file_environment/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/storage_file_environment/readme/CONTRIBUTORS.md b/storage_file_environment/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..261609d0d9 --- /dev/null +++ b/storage_file_environment/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Sebastien Beau \ +- Raphaël Reverdy \ +- Vo Hong Thien \ +- Simone Orsi \ diff --git a/storage_file_environment/readme/DESCRIPTION.md b/storage_file_environment/readme/DESCRIPTION.md new file mode 100644 index 0000000000..4113c6c40a --- /dev/null +++ b/storage_file_environment/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Glue module for storage_file to use storage_backend_environment diff --git a/storage_file_environment/static/description/icon.png b/storage_file_environment/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/storage_file_environment/static/description/index.html b/storage_file_environment/static/description/index.html new file mode 100644 index 0000000000..1c57080c38 --- /dev/null +++ b/storage_file_environment/static/description/index.html @@ -0,0 +1,427 @@ + + + + + +Storage File Environment + + + +
    +

    Storage File Environment

    + + +

    Beta License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    +

    Glue module for storage_file to use storage_backend_environment

    +

    Table of contents

    + +
    +

    Bug Tracker

    +

    Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

    +

    Do not contact contributors directly about support or help with technical issues.

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • Akretion
    • +
    • Camptocamp
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    + +Odoo Community Association + +

    OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

    +

    This module is part of the OCA/storage project on GitHub.

    +

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    +
    +
    +
    + + From 43f5812c02805a84c4acf641ac7531fda1a3f458 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:13:24 +0300 Subject: [PATCH 33/34] [FIX] storage_file: Add migration script for server_environment split --- storage_file/README.rst | 6 +---- storage_file/__manifest__.py | 2 +- storage_file/static/description/index.html | 26 +++++++------------ .../upgrades/18.0.1.3.1/post-migration.py | 19 ++++++++++++++ 4 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 storage_file/upgrades/18.0.1.3.1/post-migration.py diff --git a/storage_file/README.rst b/storage_file/README.rst index 36208ba90d..58c24d005f 100644 --- a/storage_file/README.rst +++ b/storage_file/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ============ Storage File ============ @@ -17,7 +13,7 @@ Storage File .. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png :target: https://odoo-community.org/page/development-status :alt: Production/Stable -.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstorage-lightgray.png?logo=github diff --git a/storage_file/__manifest__.py b/storage_file/__manifest__.py index 510b1d59b9..e0fa530ac1 100644 --- a/storage_file/__manifest__.py +++ b/storage_file/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Storage File", "summary": "Storage file in storage backend", - "version": "18.0.1.3.0", + "version": "18.0.1.3.1", "category": "Storage", "website": "https://github.com/OCA/storage", "author": " Akretion, Odoo Community Association (OCA)", diff --git a/storage_file/static/description/index.html b/storage_file/static/description/index.html index 4391f4351a..f9829f0ebf 100644 --- a/storage_file/static/description/index.html +++ b/storage_file/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Storage File -
    +
    +

    Storage File

    - - -Odoo Community Association - -
    -

    Storage File

    -

    Production/Stable License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    +

    Production/Stable License: LGPL-3 OCA/storage Translate me on Weblate Try me on Runboat

    External file management depending on Storage Backend module.

    It include these features: * link to any Odoo model/record * store metadata like: checksum, mimetype

    @@ -395,7 +390,7 @@

    Storage File

    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -403,15 +398,15 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • Akretion
    -

    Contributors

    +

    Contributors

    -

    Other credits

    +

    Other credits

    The migration of this module from 15.0 to 18.0 was financially supported by Camptocamp

    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -438,6 +433,5 @@

    Maintainers

    -
    diff --git a/storage_file/upgrades/18.0.1.3.1/post-migration.py b/storage_file/upgrades/18.0.1.3.1/post-migration.py new file mode 100644 index 0000000000..bebcfa8374 --- /dev/null +++ b/storage_file/upgrades/18.0.1.3.1/post-migration.py @@ -0,0 +1,19 @@ +from openupgradelib import openupgrade + +from odoo import _, exceptions + + +@openupgrade.migrate() +def migrate(env, version): + module = env["ir.module.module"].search([("name", "=", "storage_file_environment")]) + if not module: + raise exceptions.UserError( + _( + "The 'storage_file_environment' module is not available. " + "It is required to preserve the server environment managed " + "fields of 'storage.backend'. Make it available on the " + "addons path before upgrading 'storage_file'." + ) + ) + if module.state == "uninstalled": + module.button_install() From 4887db5d02e51b6e670dce96ea4b075250725222 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 13:14:29 +0300 Subject: [PATCH 34/34] [IMP] storage_file_environment: preserve data on install and restore columns on uninstall --- storage_file_environment/__init__.py | 1 + storage_file_environment/__manifest__.py | 2 ++ storage_file_environment/hooks.py | 24 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 storage_file_environment/hooks.py diff --git a/storage_file_environment/__init__.py b/storage_file_environment/__init__.py index 0650744f6b..1a9a001cf7 100644 --- a/storage_file_environment/__init__.py +++ b/storage_file_environment/__init__.py @@ -1 +1,2 @@ from . import models +from .hooks import post_init_hook, uninstall_hook diff --git a/storage_file_environment/__manifest__.py b/storage_file_environment/__manifest__.py index 7e65ee8729..be9811fb73 100644 --- a/storage_file_environment/__manifest__.py +++ b/storage_file_environment/__manifest__.py @@ -12,4 +12,6 @@ "development_status": "Beta", "installable": True, "depends": ["storage_backend_environment", "storage_file"], + "post_init_hook": "post_init_hook", + "uninstall_hook": "uninstall_hook", } diff --git a/storage_file_environment/hooks.py b/storage_file_environment/hooks.py new file mode 100644 index 0000000000..859e29c134 --- /dev/null +++ b/storage_file_environment/hooks.py @@ -0,0 +1,24 @@ +# Copyright 2026 Camptocamp SA +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.addons.server_environment.uninstall import restore_env_managed_columns + +ENV_MANAGED_FIELDS = [ + "filename_strategy", + "served_by", + "base_url", + "url_include_directory_path", +] + + +def post_init_hook(env): + env["storage.backend"]._preserve_not_env_managed_data(ENV_MANAGED_FIELDS) + + +def uninstall_hook(env): + """Restore database columns dropped by server.env.mixin.""" + restore_env_managed_columns( + env, + "storage.backend", + ENV_MANAGED_FIELDS, + )