implement "allowed to fail" images
Sometimes we have images failing. Not always we care about them. So let allow them to fail and stop caring do they build or not. Change-Id: I01cf3635814255f682d6bd161cf1d985d92a9a31
This commit is contained in:
parent
62da72f5db
commit
a69f38198a
|
@ -32,8 +32,8 @@ def main():
|
|||
try:
|
||||
statuses = build.run_build()
|
||||
if statuses:
|
||||
(bad_results, good_results, unmatched_results,
|
||||
skipped_results, unbuildable_results) = statuses
|
||||
(bad_results, good_results, unmatched_results, skipped_results,
|
||||
unbuildable_results, allowed_to_fail_results) = statuses
|
||||
if bad_results:
|
||||
return 1
|
||||
return 0
|
||||
|
|
|
@ -273,7 +273,9 @@ _BASE_OPTS = [
|
|||
cfg.StrOpt('squash-tmp-dir',
|
||||
help='Temporary directory to be used during squashing'),
|
||||
cfg.BoolOpt('clean_package_cache', default=True,
|
||||
help='Clean all package cache.')
|
||||
help='Clean all package cache.'),
|
||||
cfg.ListOpt('allowed-to-fail', default=[],
|
||||
help='Images which are allowed to fail'),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -760,6 +760,7 @@ class KollaWorker(object):
|
|||
self.image_statuses_unmatched = dict()
|
||||
self.image_statuses_skipped = dict()
|
||||
self.image_statuses_unbuildable = dict()
|
||||
self.image_statuses_allowed_to_fail = dict()
|
||||
self.maintainer = conf.maintainer
|
||||
self.distro_python_version = conf.distro_python_version
|
||||
|
||||
|
@ -1154,12 +1155,19 @@ class KollaWorker(object):
|
|||
'name': name,
|
||||
})
|
||||
|
||||
if self.image_statuses_bad:
|
||||
if self.image_statuses_bad or self.image_statuses_allowed_to_fail:
|
||||
LOG.info("===========================")
|
||||
LOG.info("Images that failed to build")
|
||||
LOG.info("===========================")
|
||||
for name, status in sorted(self.image_statuses_bad.items()):
|
||||
all_bad_statuses = self.image_statuses_bad.copy()
|
||||
all_bad_statuses.update(self.image_statuses_allowed_to_fail)
|
||||
for name, status in sorted(all_bad_statuses.items()):
|
||||
if name in self.image_statuses_allowed_to_fail:
|
||||
LOG.error('%s Failed with status: %s (allowed to fail)',
|
||||
name, status.value)
|
||||
else:
|
||||
LOG.error('%s Failed with status: %s', name, status.value)
|
||||
|
||||
results['failed'].append({
|
||||
'name': name,
|
||||
'status': status.value,
|
||||
|
@ -1212,12 +1220,14 @@ class KollaWorker(object):
|
|||
self.image_statuses_good,
|
||||
self.image_statuses_unmatched,
|
||||
self.image_statuses_skipped,
|
||||
self.image_statuses_unbuildable]):
|
||||
self.image_statuses_unbuildable,
|
||||
self.image_statuses_allowed_to_fail]):
|
||||
return (self.image_statuses_bad,
|
||||
self.image_statuses_good,
|
||||
self.image_statuses_unmatched,
|
||||
self.image_statuses_skipped,
|
||||
self.image_statuses_unbuildable)
|
||||
self.image_statuses_unbuildable,
|
||||
self.image_statuses_allowed_to_fail)
|
||||
for image in self.images:
|
||||
if image.status == Status.BUILT:
|
||||
self.image_statuses_good[image.name] = image.status
|
||||
|
@ -1227,13 +1237,18 @@ class KollaWorker(object):
|
|||
self.image_statuses_skipped[image.name] = image.status
|
||||
elif image.status == Status.UNBUILDABLE:
|
||||
self.image_statuses_unbuildable[image.name] = image.status
|
||||
else:
|
||||
if image.name in self.conf.allowed_to_fail:
|
||||
self.image_statuses_allowed_to_fail[
|
||||
image.name] = image.status
|
||||
else:
|
||||
self.image_statuses_bad[image.name] = image.status
|
||||
return (self.image_statuses_bad,
|
||||
self.image_statuses_good,
|
||||
self.image_statuses_unmatched,
|
||||
self.image_statuses_skipped,
|
||||
self.image_statuses_unbuildable)
|
||||
self.image_statuses_unbuildable,
|
||||
self.image_statuses_allowed_to_fail)
|
||||
|
||||
def build_image_list(self):
|
||||
def process_source_installation(image, section):
|
||||
|
@ -1404,8 +1419,9 @@ class KollaWorker(object):
|
|||
def run_build():
|
||||
"""Build container images.
|
||||
|
||||
:return: A 4-tuple containing bad, good, unmatched and skipped container
|
||||
image status dicts, or None if no images were built.
|
||||
:return: A 6-tuple containing bad, good, unmatched, skipped,
|
||||
unbuildable and allowed to fail container image status dicts,
|
||||
or None if no images were built.
|
||||
"""
|
||||
conf = cfg.ConfigOpts()
|
||||
common_config.parse(conf, sys.argv[1:], prog='kolla-build')
|
||||
|
|
|
@ -648,9 +648,11 @@ class KollaWorkerTest(base.TestCase):
|
|||
kolla.images = self.images
|
||||
kolla.image_statuses_good['good'] = build.Status.BUILT
|
||||
kolla.image_statuses_bad['bad'] = build.Status.ERROR
|
||||
kolla.image_statuses_allowed_to_fail['bad2'] = build.Status.ERROR
|
||||
kolla.image_statuses_unmatched['unmatched'] = build.Status.UNMATCHED
|
||||
results = kolla.summary()
|
||||
self.assertEqual('error', results['failed'][0]['status'])
|
||||
self.assertEqual('error', results['failed'][0]['status']) # bad
|
||||
self.assertEqual('error', results['failed'][1]['status']) # bad2
|
||||
|
||||
@mock.patch('shutil.copytree')
|
||||
def test_work_dir(self, copytree_mock):
|
||||
|
@ -664,14 +666,14 @@ class MainTest(base.TestCase):
|
|||
|
||||
@mock.patch.object(build, 'run_build')
|
||||
def test_images_built(self, mock_run_build):
|
||||
image_statuses = ({}, {'img': 'built'}, {}, {}, {})
|
||||
image_statuses = ({}, {'img': 'built'}, {}, {}, {}, {})
|
||||
mock_run_build.return_value = image_statuses
|
||||
result = build_cmd.main()
|
||||
self.assertEqual(0, result)
|
||||
|
||||
@mock.patch.object(build, 'run_build')
|
||||
def test_images_unmatched(self, mock_run_build):
|
||||
image_statuses = ({}, {}, {'img': 'unmatched'}, {}, {})
|
||||
image_statuses = ({}, {}, {'img': 'unmatched'}, {}, {}, {})
|
||||
mock_run_build.return_value = image_statuses
|
||||
result = build_cmd.main()
|
||||
self.assertEqual(0, result)
|
||||
|
@ -684,7 +686,7 @@ class MainTest(base.TestCase):
|
|||
|
||||
@mock.patch.object(build, 'run_build')
|
||||
def test_bad_images(self, mock_run_build):
|
||||
image_statuses = ({'img': 'error'}, {}, {}, {}, {})
|
||||
image_statuses = ({'img': 'error'}, {}, {}, {}, {}, {})
|
||||
mock_run_build.return_value = image_statuses
|
||||
result = build_cmd.main()
|
||||
self.assertEqual(1, result)
|
||||
|
@ -697,14 +699,14 @@ class MainTest(base.TestCase):
|
|||
|
||||
@mock.patch.object(build, 'run_build')
|
||||
def test_skipped_images(self, mock_run_build):
|
||||
image_statuses = ({}, {}, {}, {'img': 'skipped'}, {})
|
||||
image_statuses = ({}, {}, {}, {'img': 'skipped'}, {}, {})
|
||||
mock_run_build.return_value = image_statuses
|
||||
result = build_cmd.main()
|
||||
self.assertEqual(0, result)
|
||||
|
||||
@mock.patch.object(build, 'run_build')
|
||||
def test_unbuildable_images(self, mock_run_build):
|
||||
image_statuses = ({}, {}, {}, {}, {'img': 'unbuildable'})
|
||||
image_statuses = ({}, {}, {}, {}, {'img': 'unbuildable'}, {})
|
||||
mock_run_build.return_value = image_statuses
|
||||
result = build_cmd.main()
|
||||
self.assertEqual(0, result)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
New option 'allowed-to-fail' can be used in Kolla build config files. It
|
||||
provides list of images which are allowed to fail during build without
|
||||
marking whole build as failed.
|
||||
|
||||
Main use of this option is to keep CI systems in working state despite some
|
||||
less important images failing.
|
Loading…
Reference in New Issue