From cf8c2fe8aeef687c206fcbc656d8a53571c2c281 Mon Sep 17 00:00:00 2001
From: "Laurent Mignon (ACSONE)"
Date: Thu, 24 Sep 2026 20:26:44 +0200
Subject: [PATCH] [MIG] fs_storage: Migration from 19.0 to 20.0
---
.pre-commit-config.yaml | 1 -
fs_storage/README.rst | 10 +++----
fs_storage/__manifest__.py | 6 ++---
fs_storage/models/fs_storage.py | 26 +++++++++----------
fs_storage/pyproject.toml | 3 +++
fs_storage/security/ir.access.csv | 3 +++
fs_storage/security/ir.model.access.csv | 3 ---
fs_storage/static/description/index.html | 6 ++---
fs_storage/upgrades/18.0.2.1.0/post-update.py | 16 ------------
fs_storage/views/fs_storage_view.xml | 6 ++---
fs_storage/wizards/fs_test_connection.xml | 2 +-
requirements.txt | 2 ++
12 files changed, 35 insertions(+), 49 deletions(-)
create mode 100644 fs_storage/pyproject.toml
create mode 100644 fs_storage/security/ir.access.csv
delete mode 100644 fs_storage/security/ir.model.access.csv
delete mode 100644 fs_storage/upgrades/18.0.2.1.0/post-update.py
create mode 100644 requirements.txt
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 9de9ece027..57aa2bb97d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -11,7 +11,6 @@ exclude: |
^fs_folder_ms_drive/|
^fs_folder_webdav/|
^fs_image/|
- ^fs_storage/|
^fs_storage_environment/|
^fs_storage_ms_drive/|
^image_tag/|
diff --git a/fs_storage/README.rst b/fs_storage/README.rst
index 6aa9e919b6..e50daf8f26 100644
--- a/fs_storage/README.rst
+++ b/fs_storage/README.rst
@@ -21,13 +21,13 @@ Filesystem Storage Backend
: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/19.0/fs_storage
+ :target: https://github.com/OCA/storage/tree/20.0/fs_storage
:alt: OCA/storage
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/storage-19-0/storage-19-0-fs_storage
+ :target: https://translation.odoo-community.org/projects/storage-20-0/storage-20-0-fs_storage
: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=19.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=20.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -309,7 +309,7 @@ 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 `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -342,6 +342,6 @@ 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.
+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/__manifest__.py b/fs_storage/__manifest__.py
index e550fdc0a6..e880dd47dc 100644
--- a/fs_storage/__manifest__.py
+++ b/fs_storage/__manifest__.py
@@ -5,17 +5,17 @@
{
"name": "Filesystem Storage Backend",
"summary": "Implement the concept of Storage with amazon S3, sftp...",
- "version": "19.0.1.1.3",
+ "version": "20.0.1.0.0",
"category": "FS Storage",
"website": "https://github.com/OCA/storage",
"author": " ACSONE SA/NV, Odoo Community Association (OCA)",
"license": "LGPL-3",
"development_status": "Beta",
- "installable": False,
+ "installable": True,
"depends": ["base", "base_sparse_field"],
"data": [
"views/fs_storage_view.xml",
- "security/ir.model.access.csv",
+ "security/ir.access.csv",
"wizards/fs_test_connection.xml",
],
"external_dependencies": {"python": ["fsspec>=2024.5.0"]},
diff --git a/fs_storage/models/fs_storage.py b/fs_storage/models/fs_storage.py
index 98f422a510..46a1588573 100644
--- a/fs_storage/models/fs_storage.py
+++ b/fs_storage/models/fs_storage.py
@@ -299,7 +299,6 @@ def _get_check_connection_method_selection(self):
@prevent_call_from_safe_eval("create")
def create(self, vals_list):
records = super().create(vals_list)
- self.env.registry.clear_cache()
return records
@prevent_call_from_safe_eval("create")
@@ -309,7 +308,6 @@ def _create(self, data_list):
@prevent_call_from_safe_eval("write")
def write(self, vals):
self.__fs = None
- self.env.registry.clear_cache()
return super().write(vals)
@prevent_call_from_safe_eval("write")
@@ -330,7 +328,7 @@ def get_directory_path(self):
)
@api.model
- @tools.ormcache()
+ @api.ormcache()
def get_id_by_code_map(self):
"""Return a dictionary with the code as key and the id as value."""
return {rec.code: rec.id for rec in self.sudo().search([])}
@@ -350,13 +348,13 @@ def get_by_code(self, code) -> FSStorage:
return res
@api.model
- @tools.ormcache("code")
+ @api.ormcache("code")
def get_protocol_by_code(self, code):
record = self.get_by_code(code)
return record.protocol if record else None
@api.model
- @tools.ormcache("code")
+ @api.ormcache("code")
def _is_fs_cacheable(self, code):
"""Return True if the filesystem is cacheable."""
# This method is used to check if the filesystem is cacheable.
@@ -367,13 +365,13 @@ def _is_fs_cacheable(self, code):
return fs_storage and fs_storage.sudo().is_cacheable
@api.model
- @tools.ormcache()
+ @api.ormcache()
def get_storage_codes(self):
"""Return the list of codes of the existing filesystems."""
return [s.code for s in self.search([])]
@api.model
- @tools.ormcache("code")
+ @api.ormcache("code")
def _get_fs_by_code_from_cache(self, code):
return self.get_fs_by_code(code, force_no_cache=True)
@@ -395,7 +393,7 @@ def get_fs_by_code(self, code, force_no_cache=False):
return fs
@api.model
- @tools.ormcache("model_name", "field_name")
+ @api.ormcache("model_name", "field_name")
def get_storage_code_by_model_field(self, model_name, field_name=None):
"""Return the storage backend associated to the given model and field.
@@ -463,7 +461,7 @@ def _get_protocols(self) -> list[tuple[str, str]]:
try:
cls = fsspec.get_filesystem_class(p)
protocol.append((p, f"{p} ({cls.__name__})"))
- except Exception as e:
+ except (ValueError, ImportError) as e:
_logger.debug("Cannot load the protocol %s. Reason: %s", p, e)
return protocol
@@ -472,7 +470,7 @@ def _check_options(self) -> None:
for rec in self:
try:
json.loads(rec.options or "{}")
- except Exception as e:
+ except json.JSONDecodeError as e:
raise ValidationError(
self.env._("The options must be a valid JSON")
) from e
@@ -499,7 +497,7 @@ def _get_options_protocol(self) -> list[tuple[str, str]]:
try:
fsspec.get_filesystem_class(p)
protocol.append((p, p))
- except Exception as e:
+ except (ValueError, ImportError) as e:
_logger.debug("Cannot load the protocol %s. Reason: %s", p, e)
return protocol
@@ -601,10 +599,10 @@ def fs(self) -> fsspec.AbstractFileSystem:
# Use a marker file to limit the scope of the LS command for performance.
try:
self._check_connection(self.__fs, self.check_connection_method)
- except Exception as e:
+ except Exception:
self.__fs.clear_instance_cache()
self.__fs = None
- raise e
+ raise
return self.__fs
def _get_filesystem_storage_path(self) -> str:
@@ -782,7 +780,7 @@ def _test_config(self, connection_method):
title = self.env._("Connection Test Succeeded!")
message = self.env._("Everything seems properly set up!")
msg_type = "success"
- except Exception as err:
+ except Exception as err: # noqa: BLE001
title = self.env._("Connection Test Failed!")
message = str(err)
msg_type = "danger"
diff --git a/fs_storage/pyproject.toml b/fs_storage/pyproject.toml
new file mode 100644
index 0000000000..4231d0cccb
--- /dev/null
+++ b/fs_storage/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["whool"]
+build-backend = "whool.buildapi"
diff --git a/fs_storage/security/ir.access.csv b/fs_storage/security/ir.access.csv
new file mode 100644
index 0000000000..07d5b6d3c7
--- /dev/null
+++ b/fs_storage/security/ir.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id,group_id/id,operation,domain
+access_fs_storage_edit,fs_storage edit,fs.storage,base.group_system,crud
+access_fs_test_connection,fs.test.connection.access,fs.test.connection,base.group_system,crud
diff --git a/fs_storage/security/ir.model.access.csv b/fs_storage/security/ir.model.access.csv
deleted file mode 100644
index c1a81aae11..0000000000
--- a/fs_storage/security/ir.model.access.csv
+++ /dev/null
@@ -1,3 +0,0 @@
-id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_fs_storage_edit,fs_storage edit,model_fs_storage,base.group_system,1,1,1,1
-access_fs_test_connection,fs.test.connection.access,model_fs_test_connection,base.group_system,1,1,1,1
diff --git a/fs_storage/static/description/index.html b/fs_storage/static/description/index.html
index b99de322f5..a4ab01b31a 100644
--- a/fs_storage/static/description/index.html
+++ b/fs_storage/static/description/index.html
@@ -374,7 +374,7 @@ Filesystem Storage Backend
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:81951fe8521a3c09940411a4e9fa4b79f4571cb3cb9209762018c099656b472a
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-

+

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.
@@ -675,7 +675,7 @@
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.
+feedback.
Do not contact contributors directly about support or help with technical issues.
@@ -704,7 +704,7 @@
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.
+
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/upgrades/18.0.2.1.0/post-update.py b/fs_storage/upgrades/18.0.2.1.0/post-update.py
deleted file mode 100644
index 410e39265a..0000000000
--- a/fs_storage/upgrades/18.0.2.1.0/post-update.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2025 XCG
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-def migrate(cr, version):
- cr.execute(
- "SELECT true FROM pg_attribute WHERE attrelid = 'fs_storage'::regclass AND "
- "attname = 'check_connection_method' AND NOT attisdropped;"
- )
- if cr.fetchall():
- cr.execute(
- """UPDATE fs_storage
- SET server_env_defaults = (('{"x_check_connection_method_env_default": "' ||
- check_connection_method || '"}')::jsonb || server_env_defaults::jsonb)::text
- ;"""
- )
- # clean up
- cr.execute("ALTER TABLE fs_storage DROP COLUMN check_connection_method;")
diff --git a/fs_storage/views/fs_storage_view.xml b/fs_storage/views/fs_storage_view.xml
index 539ffdcd04..b11fc6e684 100644
--- a/fs_storage/views/fs_storage_view.xml
+++ b/fs_storage/views/fs_storage_view.xml
@@ -96,7 +96,7 @@
-
+
FS Storage
ir.actions.act_window
fs.storage
@@ -105,13 +105,13 @@
[]
{}
-
+
form
-
+
list
diff --git a/fs_storage/wizards/fs_test_connection.xml b/fs_storage/wizards/fs_test_connection.xml
index 2846f7e3d3..b10a692640 100644
--- a/fs_storage/wizards/fs_test_connection.xml
+++ b/fs_storage/wizards/fs_test_connection.xml
@@ -20,7 +20,7 @@
-
+
FS Test Connection
ir.actions.act_window
fs.test.connection
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000..0905f9449e
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
+# generated from manifests external_dependencies
+fsspec>=2024.5.0