Implement per artifact type configurations

Now we can specify some parameters per artifact
type in section [<type_name], like [images] or
[heat_templates] in glare.conf file.

It increases a flexibility of the system and
allows to tune the system more precisely.

Change-Id: I236716f88409169732661ade12168c560e2be112
This commit is contained in:
Mike Fedosin 2017-06-22 19:25:23 +03:00
parent 991dcdca21
commit 14a0fb1c90
4 changed files with 65 additions and 9 deletions

View File

@ -340,7 +340,13 @@ class Engine(object):
policy.authorize(action_name, af.to_dict(), context)
af.validate_delete(context, af)
blobs = af.delete(context, af)
if not CONF.delayed_delete:
delayed_delete = getattr(CONF, type_name).delayed_delete
# use global parameter if delayed delete isn't set per artifact type
if delayed_delete is None:
delayed_delete = CONF.delayed_delete
if not delayed_delete:
if blobs:
# delete blobs one by one
self._delete_blobs(context, af, blobs)

View File

@ -26,15 +26,16 @@ from glare.objects.meta import fields as glare_fields
from glare.objects.meta import validators
from glare.objects.meta import wrappers
artifact_opts = [
global_artifact_opts = [
cfg.BoolOpt('delayed_delete', default=False,
help=_("Defines if artifact must be deleted immediately "
"or just marked as deleted so it can be cleaned "
help=_("If False defines that artifacts must be deleted "
"immediately after the user call. Otherwise they just "
"will be marked as deleted so they can be scrubbed "
"by some other tool in the background.")),
]
CONF = cfg.CONF
CONF.register_opts(artifact_opts)
CONF.register_opts(global_artifact_opts)
LOG = logging.getLogger(__name__)
@ -123,6 +124,25 @@ class BaseArtifact(base.VersionedObject):
description="Artifact version(semver).")
}
artifact_type_opts = [
cfg.BoolOpt('delayed_delete',
help=_(
"If False defines that artifacts must be deleted "
"immediately after the user call. Otherwise they just "
"will be marked as deleted so they can be scrubbed "
"by some other tool in the background. "
"Redefines global parameter of the same name "
"from [DEFAULT] section.")),
]
def __new__(cls, *args, **kwargs):
CONF.register_opts(cls.artifact_type_opts, group=cls.get_type_name())
return base.VersionedObject.__new__(cls)
@classmethod
def list_artifact_type_opts(cls):
return cls.artifact_type_opts
db_api = artifact_api.ArtifactAPI()
@classmethod

View File

@ -29,7 +29,7 @@ import glare.common.config
import glare.common.wsgi
import glare.notification
import glare.objects.base
import glare.objects.meta.registry
from glare.objects.meta import registry
import glare.scrubber
_artifacts_opts = [
@ -42,8 +42,8 @@ _artifacts_opts = [
glare.common.wsgi.eventlet_opts,
glare.common.wsgi.socket_opts,
glare.notification.notifier_opts,
glare.objects.base.artifact_opts,
glare.objects.meta.registry.registry_options))),
glare.objects.base.global_artifact_opts,
registry.registry_options))),
profiler.list_opts()[0],
('paste_deploy', glare.common.config.paste_deploy_opts),
('keycloak_oidc', glare.api.middleware.keycloak_auth.keycloak_oidc_opts),
@ -53,6 +53,11 @@ _artifacts_opts = [
glare.scrubber.scrubber_cmd_cli_opts)
]
registry.ArtifactRegistry.register_all_artifacts()
for af_type in registry.ArtifactRegistry.obj_classes().values():
_artifacts_opts.append(
(af_type[0].get_type_name(), af_type[0].list_artifact_type_opts()))
def list_artifacts_opts():
"""Return a list of oslo_config options available in Glare"""

View File

@ -151,7 +151,7 @@ class TestArtifactUpdate(base.BaseTestArtifactAPI):
@mock.patch('glare.common.store_api.delete_blob',
side_effect=store_api.delete_blob)
def test_delayed_delete(self, mocked_delete):
def test_delayed_delete_global(self, mocked_delete):
# Enable delayed delete
self.config(delayed_delete=True)
# Delete artifact and check that 'delete_blob' was not called
@ -172,3 +172,28 @@ class TestArtifactUpdate(base.BaseTestArtifactAPI):
self.assertEqual(1, mocked_delete.call_count)
self.assertRaises(exc.NotFound, self.controller.show,
self.req, 'sample_artifact', self.artifact['id'])
@mock.patch('glare.common.store_api.delete_blob',
side_effect=store_api.delete_blob)
def test_delayed_delete_per_artifact_type(self, mocked_delete):
# Enable delayed delete for sample_artifact type
# Global parameter is disabled
self.config(delayed_delete=True, group='sample_artifact')
# Delete artifact and check that 'delete_blob' was not called
self.controller.delete(self.req, 'sample_artifact',
self.artifact['id'])
self.assertEqual(0, mocked_delete.call_count)
# Check that artifact status is 'deleted' and its blob is
# 'pending_delete'
self.artifact = self.controller.show(
self.req, 'sample_artifact', self.artifact['id'])
self.assertEqual('deleted', self.artifact['status'])
self.assertEqual('active', self.artifact['blob']['status'])
# Disable delayed delete
self.config(delayed_delete=False, group='sample_artifact')
# Delete artifact and check that 'delete_blob' was called this time
self.controller.delete(self.req, 'sample_artifact',
self.artifact['id'])
self.assertEqual(1, mocked_delete.call_count)
self.assertRaises(exc.NotFound, self.controller.show,
self.req, 'sample_artifact', self.artifact['id'])