mirror of
https://github.com/camptocamp/odoo-cloud-platform.git
synced 2026-06-23 18:04:34 +00:00
Object Storage - inactive mode
This commit is contained in:
committed by
Maksym Yankin
co-authored by
Maksym Yankin
parent
22726869cf
commit
f06ac95508
@@ -162,3 +162,8 @@ environment. It will refuse to start if anything is badly configured.
|
||||
|
||||
The checks can be bypassed with the environment variable
|
||||
`ODOO_CLOUD_PLATFORM_UNSAFE` set to `1`.
|
||||
|
||||
### Attachment storage inactivation
|
||||
|
||||
To prevent object storage to be accessed while failing for any kind of reason
|
||||
set this environment variable `ATTACHMENT_STORAGE_INACTIVE` set to `1`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Base class for attachments on external object store
|
||||
===================================================
|
||||
|
||||
This is a base addon that regroup common code used by addons targeting specific object store
|
||||
This is a base addon that regroup common code used by addons targeting specific object store
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
@@ -38,3 +38,9 @@ Default configuration means:
|
||||
stored in database
|
||||
* application/javascript are stored in database whatever their size
|
||||
* text/css are stored in database whatever their size
|
||||
|
||||
Inactivate attachment storage I/O
|
||||
---------------------------------
|
||||
|
||||
Define a environment variable `ATTACHMENT_STORAGE_INACTIVE` set to `1`
|
||||
This will prevent any kind of exceptions and read/write on storage attachments.
|
||||
|
||||
@@ -5,6 +5,7 @@ import inspect
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from distutils.util import strtobool
|
||||
|
||||
import psycopg2
|
||||
import odoo
|
||||
@@ -18,6 +19,10 @@ from odoo.tools.safe_eval import const_eval
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def is_true(strval):
|
||||
return bool(strtobool(strval or '0'))
|
||||
|
||||
|
||||
def clean_fs(files):
|
||||
_logger.info('cleaning old files from filestore')
|
||||
for full_path in files:
|
||||
@@ -40,6 +45,18 @@ def clean_fs(files):
|
||||
class IrAttachment(models.Model):
|
||||
_inherit = 'ir.attachment'
|
||||
|
||||
@staticmethod
|
||||
def is_storage_inactive(storage=None, log=True):
|
||||
msg = _("Storages are inactive (see environment configuration).")
|
||||
if storage:
|
||||
msg = _(
|
||||
"Storage '%s' is inactive (see environment configuration)."
|
||||
) % (storage,)
|
||||
is_inactive = is_true(os.environ.get("ATTACHMENT_STORAGE_INACTIVE"))
|
||||
if is_inactive and log:
|
||||
_logger.warning(msg)
|
||||
return is_inactive
|
||||
|
||||
def _register_hook(self):
|
||||
super()._register_hook()
|
||||
location = self.env.context.get('storage_location') or self._storage()
|
||||
@@ -151,6 +168,8 @@ class IrAttachment(models.Model):
|
||||
``_store_in_db_instead_of_object_storage_domain``.
|
||||
|
||||
"""
|
||||
if self.is_storage_inactive():
|
||||
return True
|
||||
storage_config = self._get_storage_force_db_config()
|
||||
for mimetype_key, limit in storage_config.items():
|
||||
if mimetype.startswith(mimetype_key):
|
||||
@@ -190,8 +209,9 @@ class IrAttachment(models.Model):
|
||||
)
|
||||
|
||||
def _store_file_write(self, key, bin_data):
|
||||
storage = self.storage()
|
||||
raise NotImplementedError(
|
||||
'No implementation for %s' % (self.storage(),)
|
||||
'No implementation for %s' % (storage,)
|
||||
)
|
||||
|
||||
def _store_file_delete(self, fname):
|
||||
@@ -229,6 +249,8 @@ class IrAttachment(models.Model):
|
||||
@api.model
|
||||
def _is_file_from_a_store(self, fname):
|
||||
for store_name in self._get_stores():
|
||||
if self.is_storage_inactive(store_name):
|
||||
continue
|
||||
uri = '{}://'.format(store_name)
|
||||
if fname.startswith(uri):
|
||||
return True
|
||||
@@ -263,6 +285,9 @@ class IrAttachment(models.Model):
|
||||
self.ensure_one()
|
||||
_logger.info('inspecting attachment %s (%d)', self.name, self.id)
|
||||
fname = self.store_fname
|
||||
storage = fname.partition('://')[0]
|
||||
if self.is_storage_inactive(storage):
|
||||
fname = False
|
||||
if fname:
|
||||
# migrating from filesystem filestore
|
||||
# or from the old 'store_fname' without the bucket name
|
||||
@@ -305,6 +330,8 @@ class IrAttachment(models.Model):
|
||||
It is not called anywhere, but can be called by RPC or scripts.
|
||||
"""
|
||||
storage = self._storage()
|
||||
if self.is_storage_inactive(storage):
|
||||
return
|
||||
if storage not in self._get_stores():
|
||||
return
|
||||
|
||||
@@ -358,6 +385,8 @@ class IrAttachment(models.Model):
|
||||
def _force_storage_to_object_storage(self, new_cr=False):
|
||||
_logger.info('migrating files to the object storage')
|
||||
storage = self.env.context.get('storage_location') or self._storage()
|
||||
if self.is_storage_inactive(storage):
|
||||
return
|
||||
# The weird "res_field = False OR res_field != False" domain
|
||||
# is required! It's because of an override of _search in ir.attachment
|
||||
# which adds ('res_field', '=', False) when the domain does not
|
||||
|
||||
Reference in New Issue
Block a user