Object Storage - unsafe mode

This commit is contained in:
Stephane Mangin
2022-04-13 12:45:14 +02:00
parent 78b626ee97
commit 79e34cd493
3 changed files with 49 additions and 1 deletions
+5
View File
@@ -162,3 +162,8 @@ environment. It will refuse to start if anything is badly configured.
The checks can be bypassed with the environment variable The checks can be bypassed with the environment variable
`ODOO_CLOUD_PLATFORM_UNSAFE` set to `1`. `ODOO_CLOUD_PLATFORM_UNSAFE` set to `1`.
### Ongoing instance checks
To prevent object storage to be accessed while failing for any kind of reason
set this environment variable `ATTACHMENT_STORAGE_UNSAFE` set to `1`.
@@ -38,3 +38,10 @@ Default configuration means:
stored in database stored in database
* application/javascript are stored in database whatever their size * application/javascript are stored in database whatever their size
* text/css are stored in database whatever their size * text/css are stored in database whatever their size
Unsafe mode
-----------
Define a environment variable `ATTACHMENT_STORAGE_UNSAFE` set to `1`
This will prevent and avoid any king of exceptions and filestore read/write
issues.
@@ -5,6 +5,7 @@ import inspect
import logging import logging
import os import os
import time import time
from distutils.util import strtobool
import psycopg2 import psycopg2
import odoo import odoo
@@ -18,6 +19,10 @@ from odoo.tools.safe_eval import const_eval
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
def is_true(strval):
return bool(strtobool(strval or '0'))
def clean_fs(files): def clean_fs(files):
_logger.info('cleaning old files from filestore') _logger.info('cleaning old files from filestore')
for full_path in files: for full_path in files:
@@ -185,17 +190,36 @@ class IrAttachment(models.Model):
def _store_file_read(self, fname): def _store_file_read(self, fname):
storage = fname.partition('://')[0] storage = fname.partition('://')[0]
unsafe_mode = is_true(os.environ.get("ATTACHMENT_STORAGE_UNSAFE"))
if unsafe_mode:
_logger.warning(_(
"Storage '%s' is deactivated (see environment configuration)." % (storage,)
))
return
raise NotImplementedError( raise NotImplementedError(
'No implementation for %s' % (storage,) 'No implementation for %s' % (storage,)
) )
def _store_file_write(self, key, bin_data): def _store_file_write(self, key, bin_data):
storage = self.storage()
unsafe_mode = is_true(os.environ.get("ATTACHMENT_STORAGE_UNSAFE"))
if unsafe_mode:
_logger.warning(_(
"Storage '%s' is deactivated (see environment configuration)." % (storage,)
))
return
raise NotImplementedError( raise NotImplementedError(
'No implementation for %s' % (self.storage(),) 'No implementation for %s' % (storage,)
) )
def _store_file_delete(self, fname): def _store_file_delete(self, fname):
storage = fname.partition('://')[0] storage = fname.partition('://')[0]
unsafe_mode = is_true(os.environ.get("ATTACHMENT_STORAGE_UNSAFE"))
if unsafe_mode:
_logger.warning(_(
"Storage '%s' is deactivated (see environment configuration)." % (storage,)
))
return
raise NotImplementedError( raise NotImplementedError(
'No implementation for %s' % (storage,) 'No implementation for %s' % (storage,)
) )
@@ -305,6 +329,12 @@ class IrAttachment(models.Model):
It is not called anywhere, but can be called by RPC or scripts. It is not called anywhere, but can be called by RPC or scripts.
""" """
storage = self._storage() storage = self._storage()
unsafe_mode = is_true(os.environ.get("ATTACHMENT_STORAGE_UNSAFE"))
if unsafe_mode:
_logger.warning(_(
"Storage '%s' is deactivated (see environment configuration)." % (storage,)
))
return
if storage not in self._get_stores(): if storage not in self._get_stores():
return return
@@ -358,6 +388,12 @@ class IrAttachment(models.Model):
def _force_storage_to_object_storage(self, new_cr=False): def _force_storage_to_object_storage(self, new_cr=False):
_logger.info('migrating files to the object storage') _logger.info('migrating files to the object storage')
storage = self.env.context.get('storage_location') or self._storage() storage = self.env.context.get('storage_location') or self._storage()
unsafe_mode = is_true(os.environ.get("ATTACHMENT_STORAGE_UNSAFE"))
if unsafe_mode:
_logger.warning(_(
"Storage is %s deactivated (see environment configuration)." % (storage,)
))
return
# The weird "res_field = False OR res_field != False" domain # The weird "res_field = False OR res_field != False" domain
# is required! It's because of an override of _search in ir.attachment # is required! It's because of an override of _search in ir.attachment
# which adds ('res_field', '=', False) when the domain does not # which adds ('res_field', '=', False) when the domain does not