From 4c7ce560c11560580afad02f95a52fc867c3b3a4 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 16:12:10 +0200 Subject: [PATCH 01/18] [IMP] fs_storage: Remove environment data --- fs_storage/README.rst | 6 +-- fs_storage/__manifest__.py | 4 +- fs_storage/models/fs_storage.py | 13 ----- .../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(+), 51 deletions(-) create mode 100644 fs_storage/readme/newsfragments/627.feature.rst diff --git a/fs_storage/README.rst b/fs_storage/README.rst index 7ac52faa6a..9b47411c4e 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 279adc90f5..3ab375755b 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": "17.0.2.1.1", + "version": "17.0.2.1.2", "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 fce61a5c99..2f5dd158c1 100644 --- a/fs_storage/models/fs_storage.py +++ b/fs_storage/models/fs_storage.py @@ -87,7 +87,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") @@ -192,8 +191,6 @@ def __init__(self, env, ids=(), prefetch_ids=()): ), ] - _server_env_section_name_field = "code" - @api.model def _get_check_connection_method_selection(self): return [ @@ -201,16 +198,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": {}, - "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 4596359e2c..f71b222fca 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

-

17.0.2.1.0 (2025-10-22)

+

17.0.2.1.0 (2025-10-22)

-

Features

+

Features

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

    Features

-

17.0.2.0.4 (2025-08-19)

+

17.0.2.0.4 (2025-08-19)

-

Features

+

Features

  • Allow setting check_connection_method in configuration file.
-

17.0.2.0.0 (2024-10-07)

+

17.0.2.0.0 (2024-10-07)

-

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,22 +660,22 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -693,6 +688,5 @@

Maintainers

-
diff --git a/fs_storage/tests/test_fs_storage.py b/fs_storage/tests/test_fs_storage.py index 8536ac6f51..9597a37bcc 100644 --- a/fs_storage/tests/test_fs_storage.py +++ b/fs_storage/tests/test_fs_storage.py @@ -70,7 +70,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 8ab22a789b10de20a1370751401decc7651e989f Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 16:12:24 +0200 Subject: [PATCH 02/18] [ADD] fs_storage_environment --- fs_storage/upgrades/17.0.2.1.2/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 | 26 + 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, 740 insertions(+) create mode 100644 fs_storage/upgrades/17.0.2.1.2/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/17.0.2.1.2/post-update.py b/fs_storage/upgrades/17.0.2.1.2/post-update.py new file mode 100644 index 0000000000..626ada9ca6 --- /dev/null +++ b/fs_storage/upgrades/17.0.2.1.2/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..849298575d --- /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/17.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-17-0/storage-17-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=17.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..fada116433 --- /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": "17.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..e0cea72567 --- /dev/null +++ b/fs_storage_environment/models/fs_storage.py @@ -0,0 +1,26 @@ +# 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": {}, + "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..cbb26db797 --- /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 02f03015966f3e7c66419bed4e16adfa1d4367af Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Wed, 19 Aug 2026 15:20:41 +0300 Subject: [PATCH 03/18] [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 | 26 ++++++++++++++++++++++++++ 3 files changed, 29 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 fada116433..f77f77b0dc 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..55538d1d73 --- /dev/null +++ b/fs_storage_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 = [ + "protocol", + "options", + "directory_path", + "eval_options_from_env", + "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 6aeb992c7b7cf2bc34da59d2eafaadb44c7be9b6 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:31:29 +0200 Subject: [PATCH 04/18] [IMP] fs_attachment: Remove environment data --- fs_attachment/README.rst | 6 +-- fs_attachment/models/fs_storage.py | 19 ------- fs_attachment/static/description/index.html | 56 +++++++++------------ fs_attachment/tests/test_fs_storage.py | 1 + 4 files changed, 27 insertions(+), 55 deletions(-) diff --git a/fs_attachment/README.rst b/fs_attachment/README.rst index 9726d1fb59..eac7930af3 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 720af5a2ff..15f542283c 100644 --- a/fs_attachment/models/fs_storage.py +++ b/fs_attachment/models/fs_storage.py @@ -177,25 +177,6 @@ def _check_field_xmlid_storage_unique(self): % {"field": xmlid, "other_storage": other_storages[0].name} ) - @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": {}, - "model_xmlids": {}, - "field_xmlids": {}, - } - ) - 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/static/description/index.html b/fs_attachment/static/description/index.html index fa1a2c85c3..34fa0936e2 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

-

17.0.1.6.0 (2025-10-22)

+

17.0.1.6.0 (2025-10-22)

-

Features

+

Features

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

    Features

-

17.0.1.0.3 (2024-10-15)

+

17.0.1.0.3 (2024-10-15)

-

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/tests/test_fs_storage.py b/fs_attachment/tests/test_fs_storage.py index f0111abf09..3dbf43e280 100644 --- a/fs_attachment/tests/test_fs_storage.py +++ b/fs_attachment/tests/test_fs_storage.py @@ -389,6 +389,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 763dfd93398d5eb219b47357deeb13dbeeca9de9 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:32:01 +0200 Subject: [PATCH 05/18] [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 | 32 ++ 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, 561 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..a188a8b255 --- /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/17.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-17-0/storage-17-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=17.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..ff1eb9dfed --- /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": "17.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..ba8bb9754c --- /dev/null +++ b/fs_attachment_environment/models/fs_storage.py @@ -0,0 +1,32 @@ +# 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": {}, + "model_xmlids": {}, + "field_xmlids": {}, + } + ) + 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..fb723a85a2 --- /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 cb31e0a01f3db3e41bd153acd35cb1412f56d865 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Thu, 4 Jun 2026 14:21:49 +0200 Subject: [PATCH 06/18] [FIX] fs_attachment: Add migration script for server_environment split --- fs_attachment/__manifest__.py | 2 +- .../upgrades/17.0.1.6.4/post-migration.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 fs_attachment/upgrades/17.0.1.6.4/post-migration.py diff --git a/fs_attachment/__manifest__.py b/fs_attachment/__manifest__.py index 2e87fd9a2b..9976d325cf 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": "17.0.1.6.3", + "version": "17.0.1.6.4", "author": "Camptocamp, ACSONE SA/NV, Odoo Community Association (OCA)", "license": "AGPL-3", "development_status": "Beta", diff --git a/fs_attachment/upgrades/17.0.1.6.4/post-migration.py b/fs_attachment/upgrades/17.0.1.6.4/post-migration.py new file mode 100644 index 0000000000..e6627838d5 --- /dev/null +++ b/fs_attachment/upgrades/17.0.1.6.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 c28f6cde44e09662822d5fa79aacc709ba484cfb Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Wed, 19 Aug 2026 15:21:44 +0300 Subject: [PATCH 07/18] [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 | 48 +++++++++++++++++++++++ 3 files changed, 51 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 ff1eb9dfed..5cec3b3c2e 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..a61fb557ba --- /dev/null +++ b/fs_attachment_environment/hooks.py @@ -0,0 +1,48 @@ +# 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", + "model_xmlids", + "field_xmlids", +] + + +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 3a4de3beeedda86c4e5ac40c99fecb61cf96c768 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:33:56 +0200 Subject: [PATCH 08/18] [IMP] fs_attachment_s3: Remove environment data --- fs_attachment_s3/README.rst | 6 +-- fs_attachment_s3/models/fs_storage.py | 12 ------ .../static/description/index.html | 38 ++++++++----------- 3 files changed, 17 insertions(+), 39 deletions(-) diff --git a/fs_attachment_s3/README.rst b/fs_attachment_s3/README.rst index fad832a894..1ad30b8cb3 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 25170100fe..a2b54385a6 100644 --- a/fs_attachment_s3/models/fs_storage.py +++ b/fs_attachment_s3/models/fs_storage.py @@ -24,18 +24,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.""" diff --git a/fs_attachment_s3/static/description/index.html b/fs_attachment_s3/static/description/index.html index cf5e577569..6a47b7ad6d 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

-

17.0.1.2.1 (2026-05-27)

+

17.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

-

17.0.1.2.0 (2025-10-22)

+

17.0.1.2.0 (2025-10-22)

-

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,15 +504,15 @@

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 @@ -548,6 +543,5 @@

Maintainers

-
From a38ce73a7111818bee668fcec75e8562498e1a76 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 3 Jun 2026 18:34:31 +0200 Subject: [PATCH 09/18] [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..4f0335a3ce --- /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/17.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-17-0/storage-17-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=17.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..c01f8ee42f --- /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": "17.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..ec5c409566 --- /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 8076c14b73cf53c25071d1f60b1af6b21e0c0e36 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Thu, 4 Jun 2026 14:22:18 +0200 Subject: [PATCH 10/18] [FIX] fs_attachment_s3: Add migration script for server_environment split --- fs_attachment_s3/__manifest__.py | 2 +- .../upgrades/17.0.1.3.1/post-migration.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 fs_attachment_s3/upgrades/17.0.1.3.1/post-migration.py diff --git a/fs_attachment_s3/__manifest__.py b/fs_attachment_s3/__manifest__.py index 472b3ad27b..b0ac2bfab4 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": "17.0.1.3.0", + "version": "17.0.1.3.1", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_attachment_s3/upgrades/17.0.1.3.1/post-migration.py b/fs_attachment_s3/upgrades/17.0.1.3.1/post-migration.py new file mode 100644 index 0000000000..19299f15da --- /dev/null +++ b/fs_attachment_s3/upgrades/17.0.1.3.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", "=", "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 2c4a1a10576f400922007572a3d470506575e93b Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Wed, 19 Aug 2026 15:23:48 +0300 Subject: [PATCH 11/18] [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 c01f8ee42f..c763585398 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 070f0f696ad113c292fc6b78f11092b0eec9c065 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:01 +0300 Subject: [PATCH 12/18] [IMP] storage_backend: Remove environment data --- storage_backend/__manifest__.py | 4 ++-- storage_backend/models/storage_backend.py | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/storage_backend/__manifest__.py b/storage_backend/__manifest__.py index 05138d899a..1cfe236bf1 100644 --- a/storage_backend/__manifest__.py +++ b/storage_backend/__manifest__.py @@ -5,14 +5,14 @@ { "name": "Storage Bakend", "summary": "Implement the concept of Storage with amazon S3, sftp...", - "version": "17.0.1.0.0", + "version": "17.0.1.0.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", "data/data.xml", diff --git a/storage_backend/models/storage_backend.py b/storage_backend/models/storage_backend.py index 6ad9e051bf..b37661d279 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" @@ -80,10 +80,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) From 33cb05119a6c49372744df0a6aaace4d35673b7f Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:08 +0300 Subject: [PATCH 13/18] [ADD] storage_backend_environment --- .../upgrades/17.0.1.0.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/17.0.1.0.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/17.0.1.0.1/post-update.py b/storage_backend/upgrades/17.0.1.0.1/post-update.py new file mode 100644 index 0000000000..d5fd1b6ad8 --- /dev/null +++ b/storage_backend/upgrades/17.0.1.0.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..719e8d189e --- /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/17.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-17-0/storage-17-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=17.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..68baf2164f --- /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": "17.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..a77118c2a8 --- /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 6ee15eb5cc8d6b8470cf68ab68f694a98f98234d Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:35 +0300 Subject: [PATCH 14/18] [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 68baf2164f..985a00f3bf 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 cd48d8ef7a5c2aa4e74db759ded6abce54c1db77 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:10:59 +0300 Subject: [PATCH 15/18] [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 989eb629a72bdbb2067e04fe3e7ec32a61c4aa83 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:12:15 +0300 Subject: [PATCH 16/18] [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..5f7c7ddddd --- /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/17.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-17-0/storage-17-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=17.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..1d7df61680 --- /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": "17.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 z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N 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..b979fbb573 --- /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 c5c4c257cdb1f03b8dd88f6e60867e8410da7d25 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:12:33 +0300 Subject: [PATCH 17/18] [FIX] storage_backend_sftp: Add migration script for server_environment split --- storage_backend_sftp/__manifest__.py | 2 +- .../upgrades/17.0.1.0.1/post-migration.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 storage_backend_sftp/upgrades/17.0.1.0.1/post-migration.py diff --git a/storage_backend_sftp/__manifest__.py b/storage_backend_sftp/__manifest__.py index a7277e85e5..405000aefb 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": "17.0.1.0.0", + "version": "17.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/17.0.1.0.1/post-migration.py b/storage_backend_sftp/upgrades/17.0.1.0.1/post-migration.py new file mode 100644 index 0000000000..9afb8d601d --- /dev/null +++ b/storage_backend_sftp/upgrades/17.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 ca9cde7d4d03367fb382d330a9db17396d638b74 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Thu, 20 Aug 2026 11:12:53 +0300 Subject: [PATCH 18/18] [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 1d7df61680..5c348ac4d7 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, + )