Add hooks for Image Import plugins

This change adds hooks for pulling in plugins for
Interoperable Image Import taksflow. Boilerplate Noop
plugin is provided as an example and for testing.

Change-Id: If14c7dc4f38360006f9cb350fbba54fa2f33be61
This commit is contained in:
Erno Kuvaja 2017-12-18 12:48:10 +00:00 committed by Brian Rosmaita
parent 6d31337bcd
commit 1231fb5f6e
5 changed files with 142 additions and 2 deletions

View File

@ -23,6 +23,7 @@ from taskflow.patterns import linear_flow as lf
from taskflow import retry
from taskflow import task
import glance.async.flows.plugins as import_plugins
from glance.common import exception
from glance.common.scripts.image_import import main as image_import
from glance.common.scripts import utils as script_utils
@ -35,9 +36,42 @@ LOG = logging.getLogger(__name__)
CONF = cfg.CONF
api_import_opts = [
cfg.ListOpt('image_import_plugins',
item_type=cfg.types.String(quotes=True),
bounds=True,
sample_default='[no_op]',
default=[],
help=_("""
Image import plugins to be enabled for task processing.
Provide list of strings reflecting to the task Objects
that should be included to the Image Import flow. The
task objects needs to be defined in the 'glance/async/
flows/plugins/*' and may be implemented by OpenStack
Glance project team, deployer or 3rd party.
By default no plugins are enabled and to take advantage
of the plugin model the list of plugins must be set
explicitly in the glance-image-import.conf file.
The allowed values for this option is comma separated
list of object names in between ``[`` and ``]``.
Possible values:
* no_op (only logs debug level message that the
plugin has been executed)
* Any provided Task object name to be included
in to the flow.
""")),
]
CONF.register_opts(api_import_opts, group='image_import_opts')
# TODO(jokke): We should refactor the task implementations so that we do not
# need to duplicate what we have already for example in base_import.py.
class _DeleteFromFS(task.Task):
def __init__(self, task_id, task_type):
@ -336,8 +370,8 @@ def get_flow(**kwargs):
flow = lf.Flow(task_type, retry=retry.AlwaysRevert())
flow.add(_VerifyStaging(task_id, task_type, task_repo, uri))
# TODO(jokke): For the pluggable tasks like image verification or
# image conversion we need to implement the plugin logic here.
for plugin in import_plugins.get_import_plugins(**kwargs):
flow.add(plugin)
import_to_store = _ImportToStore(task_id,
task_type,

View File

@ -0,0 +1,31 @@
# Copyright 2017 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from stevedore import named
CONF = cfg.CONF
def get_import_plugins(**kwargs):
task_list = CONF.image_import_opts.image_import_plugins
extensions = named.NamedExtensionManager('glance.image_import.plugins',
names=task_list,
name_order=True,
invoke_on_load=True,
invoke_kwds=kwargs)
for extension in extensions.extensions:
yield extension.obj

View File

@ -0,0 +1,62 @@
# Copyright 2017 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
from oslo_log import log as logging
from taskflow.patterns import linear_flow as lf
from taskflow import task
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
class _Noop(task.Task):
def __init__(self, task_id, task_type, image_repo):
self.task_id = task_id
self.task_type = task_type
self.image_repo = image_repo
super(_Noop, self).__init__(
name='%s-Noop-%s' % (task_type, task_id))
def execute(self, **kwargs):
LOG.debug("No_op import plugin")
return
def revert(self, result=None, **kwargs):
# NOTE(flaper87): If result is None, it probably
# means this task failed. Otherwise, we would have
# a result from its execution.
if result is not None:
LOG.debug("No_op import plugin failed")
return
def get_flow(**kwargs):
"""Return task flow for no-op.
:param task_id: Task ID.
:param task_type: Type of the task.
:param image_repo: Image repository used.
"""
task_id = kwargs.get('task_id')
task_type = kwargs.get('task_type')
image_repo = kwargs.get('image_repo')
return lf.Flow(task_type).add(
_Noop(task_id, task_type, image_repo),
)

View File

@ -18,6 +18,7 @@ __all__ = [
'list_scrubber_opts',
'list_cache_opts',
'list_manage_opts',
'list_image_import_opts',
]
import copy
@ -27,6 +28,7 @@ from osprofiler import opts as profiler
import glance.api.middleware.context
import glance.api.versions
import glance.async.flows.api_image_import
import glance.async.flows.convert
import glance.async.taskflow_executor
import glance.common.config
@ -107,6 +109,9 @@ _cache_opts = [
_manage_opts = [
(None, [])
]
_image_import_opts = [
('image_import_opts', glance.async.flows.api_image_import.api_import_opts)
]
def list_api_opts():
@ -153,3 +158,8 @@ def list_cache_opts():
def list_manage_opts():
"""Return a list of oslo_config options available in Glance manage."""
return [(g, copy.deepcopy(o)) for g, o in _manage_opts]
def list_image_import_opts():
"""Return a list of oslo_config options available for Image Import"""
return [(g, copy.deepcopy(o)) for g, o in _image_import_opts]

View File

@ -71,6 +71,9 @@ glance.flows.import =
introspect = glance.async.flows.introspect:get_flow
ovf_process = glance.async.flows.ovf_process:get_flow
glance.image_import.plugins =
no_op = glance.async.flows.plugins.no_op:get_flow
[build_sphinx]
builder = html man
all_files = 1