Add enabled flag for sources

Sometimes it might be useful to disable a source for an image, e.g. for
a plugin that is not used. This may be to reduce image sizes, or
restrict the dependencies necessary to build images.

This change adds a new 'enabled' option to each source definition. This
allows sources, plugins or additions for each source image to be
disabled individually.

Change-Id: I31ee0744574fb3db96bee2e9f545600de53d9ee4
This commit is contained in:
Mark Goddard 2022-03-14 13:57:12 +00:00
parent 5bb6489922
commit c9f93c30c1
5 changed files with 73 additions and 21 deletions

View File

@ -130,10 +130,11 @@ installed from upstream sources. The default method of the OpenStack install is
ones. ones.
The locations of OpenStack source code are written in ``kolla-build.conf``. The locations of OpenStack source code are written in ``kolla-build.conf``.
The source type supports ``url``, ``git``, and ``local``. The location of The source's ``type`` supports ``url``, ``git`` and ``local``. The
the ``local`` source type can point to either a directory containing the source ``location`` of the ``local`` source type can point to either a directory
code or to a tarball of the source. The ``local`` source type permits to make containing the source code or to a tarball of the source. The ``local`` source
the best use of the Docker cache. type permits to make the best use of the Docker cache. A source may be
disabled by setting ``enabled`` to ``False``.
The ``kolla-build.conf`` file could look like this: The ``kolla-build.conf`` file could look like this:
@ -156,6 +157,7 @@ The ``kolla-build.conf`` file could look like this:
[ironic-base] [ironic-base]
type = local type = local
location = /tmp/ironic.tar.gz location = /tmp/ironic.tar.gz
enabled = False
.. note:: .. note::
@ -369,8 +371,11 @@ The template now becomes:
python3 -m pip --no-cache-dir install /plugins/* python3 -m pip --no-cache-dir install /plugins/*
{% endblock %} {% endblock %}
Many of the Dockerfiles already copy the ``plugins-archive`` to the image and Some plugins are installed by default. For images with default plugins, the
install available plugins at build time. Dockerfiles already copy the ``plugins-archive`` to the image and install
available plugins at build time. These default plugins may be disabled by
setting ``enabled`` to ``False`` in the relevant plugin source configuration
section in ``kolla-build.conf``.
Neutron plugins Neutron plugins
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^

View File

@ -955,7 +955,7 @@ USERS = {
} }
def get_source_opts(type_=None, location=None, reference=None): def get_source_opts(type_=None, location=None, reference=None, enabled=True):
return [cfg.StrOpt('type', choices=['local', 'git', 'url'], return [cfg.StrOpt('type', choices=['local', 'git', 'url'],
default=type_, default=type_,
help='Source location type'), help='Source location type'),
@ -963,7 +963,9 @@ def get_source_opts(type_=None, location=None, reference=None):
help='The location for source install'), help='The location for source install'),
cfg.StrOpt('reference', default=reference, cfg.StrOpt('reference', default=reference,
help=('Git reference to pull, commit sha, tag ' help=('Git reference to pull, commit sha, tag '
'or branch name'))] 'or branch name')),
cfg.BoolOpt('enabled', default=enabled,
help=('Whether the source is enabled'))]
def get_user_opts(uid, gid, group): def get_user_opts(uid, gid, group):
@ -990,7 +992,8 @@ def gen_all_source_opts():
type_ = params['type'] type_ = params['type']
location = params['location'] location = params['location']
reference = params.get('reference') reference = params.get('reference')
yield name, get_source_opts(type_, location, reference) enabled = params.get('enabled', True)
yield name, get_source_opts(type_, location, reference, enabled)
def list_opts(): def list_opts():

View File

@ -361,6 +361,10 @@ class BuildTask(DockerTask):
return followups return followups
def process_source(self, image, source): def process_source(self, image, source):
if not source['enabled']:
self.logger.debug("Skipping disabled source %s", source['name'])
return
dest_archive = os.path.join(image.path, source['name'] + '-archive') dest_archive = os.path.join(image.path, source['name'] + '-archive')
if source.get('type') == 'url': if source.get('type') == 'url':
@ -458,6 +462,7 @@ class BuildTask(DockerTask):
archive_path = self.process_source(image, item) archive_path = self.process_source(image, item)
if image.status in STATUS_ERRORS: if image.status in STATUS_ERRORS:
raise ArchivingError raise ArchivingError
if archive_path:
archives.append(archive_path) archives.append(archive_path)
if archives: if archives:
for archive in archives: for archive in archives:
@ -1206,6 +1211,7 @@ class KollaWorker(object):
installation['name'] = section installation['name'] = section
if installation['type'] == 'git': if installation['type'] == 'git':
installation['reference'] = self.conf[section]['reference'] installation['reference'] = self.conf[section]['reference']
installation['enabled'] = self.conf[section]['enabled']
return installation return installation
all_sections = (set(self.conf._groups.keys()) | all_sections = (set(self.conf._groups.keys()) |

View File

@ -254,7 +254,8 @@ class TasksTest(base.TestCase):
self.image.source = { self.image.source = {
'source': 'http://fake/source', 'source': 'http://fake/source',
'type': 'url', 'type': 'url',
'name': 'fake-image-base' 'name': 'fake-image-base',
'enabled': True
} }
push_queue = mock.Mock() push_queue = mock.Mock()
builder = build.BuildTask(self.conf, self.image, push_queue) builder = build.BuildTask(self.conf, self.image, push_queue)
@ -277,16 +278,20 @@ class TasksTest(base.TestCase):
mock_rmtree, mock_copyfile, mock_utime): mock_rmtree, mock_copyfile, mock_utime):
for source in [{'source': 'http://fake/source1', 'type': 'url', for source in [{'source': 'http://fake/source1', 'type': 'url',
'name': 'fake-image-base1', 'name': 'fake-image-base1',
'reference': 'http://fake/reference1'}, 'reference': 'http://fake/reference1',
'enabled': True},
{'source': 'http://fake/source2', 'type': 'git', {'source': 'http://fake/source2', 'type': 'git',
'name': 'fake-image-base2', 'name': 'fake-image-base2',
'reference': 'http://fake/reference2'}, 'reference': 'http://fake/reference2',
'enabled': True},
{'source': 'http://fake/source3', 'type': 'local', {'source': 'http://fake/source3', 'type': 'local',
'name': 'fake-image-base3', 'name': 'fake-image-base3',
'reference': 'http://fake/reference3'}, 'reference': 'http://fake/reference3',
'enabled': True},
{'source': 'http://fake/source4', 'type': None, {'source': 'http://fake/source4', 'type': None,
'name': 'fake-image-base4', 'name': 'fake-image-base4',
'reference': 'http://fake/reference4'}]: 'reference': 'http://fake/reference4',
'enabled': True}]:
self.image.source = source self.image.source = source
push_queue = mock.Mock() push_queue = mock.Mock()
builder = build.BuildTask(self.conf, self.image, push_queue) builder = build.BuildTask(self.conf, self.image, push_queue)
@ -305,7 +310,8 @@ class TasksTest(base.TestCase):
mock_path_exists): mock_path_exists):
source = {'source': 'http://fake/source1', 'type': 'git', source = {'source': 'http://fake/source1', 'type': 'git',
'name': 'fake-image1', 'name': 'fake-image1',
'reference': 'fake/reference1'} 'reference': 'fake/reference1',
'enabled': True}
self.image.source = source self.image.source = source
self.image.path = "fake_image_path" self.image.path = "fake_image_path"
@ -385,7 +391,8 @@ class KollaWorkerTest(base.TestCase):
'name': 'neutron-server-plugin-networking-arista', 'name': 'neutron-server-plugin-networking-arista',
'reference': 'master', 'reference': 'master',
'source': 'https://opendev.org/x/networking-arista', 'source': 'https://opendev.org/x/networking-arista',
'type': 'git' 'type': 'git',
'enabled': True
} }
found = False found = False
@ -399,6 +406,30 @@ class KollaWorkerTest(base.TestCase):
if not found: if not found:
self.fail('Can not find the expected neutron arista plugin') self.fail('Can not find the expected neutron arista plugin')
def test_build_image_list_skips_disabled_plugins(self):
self.conf.set_override('install_type', 'source')
self.conf.set_override('enabled', False,
'neutron-base-plugin-networking-baremetal')
kolla = build.KollaWorker(self.conf)
kolla.setup_working_dir()
kolla.find_dockerfiles()
kolla.create_dockerfiles()
kolla.build_image_list()
disabled_plugin = 'neutron-base-plugin-networking-baremetal'
found = False
for image in kolla.images:
if image.name == 'neutron-server':
for plugin in image.plugins:
if plugin == disabled_plugin:
found = True
break
break
if found:
self.fail('Found disabled neutron networking-baremetal plugin')
def test_build_image_list_plugin_parsing(self): def test_build_image_list_plugin_parsing(self):
"""Ensure regex used to parse plugins adds them to the correct image""" """Ensure regex used to parse plugins adds them to the correct image"""
self.conf.set_override('install_type', 'source') self.conf.set_override('install_type', 'source')

View File

@ -0,0 +1,7 @@
---
features:
- |
Adds a new ``enabled`` option to each source definition. This allows
sources, plugins or additions for each source image to be disabled
individually. This may be used to reduce image sizes, or restrict the
dependencies necessary to build images.