aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Juszkiewicz <marcin.juszkiewicz@linaro.org>2020-12-07 14:25:09 +0100
committerMarcin Juszkiewicz <marcin.juszkiewicz@linaro.org>2021-01-20 17:01:25 +0100
commita69f38198a0eff7576afff672f5496c27e520092 (patch)
treed04185462004f5ba4110aedcf8d3bfa8601ea50d
parent62da72f5dbf93071b8997ccd5a93f4f0788721e0 (diff)
downloadkolla-a69f38198a0eff7576afff672f5496c27e520092.tar.gz
kolla-a69f38198a0eff7576afff672f5496c27e520092.zip
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
-rwxr-xr-xkolla/cmd/build.py4
-rwxr-xr-xkolla/common/config.py4
-rwxr-xr-xkolla/image/build.py34
-rw-r--r--kolla/tests/test_build.py14
-rw-r--r--releasenotes/notes/allowed-to-fail-e2ff5bf61c857b55.yaml9
5 files changed, 47 insertions, 18 deletions
diff --git a/kolla/cmd/build.py b/kolla/cmd/build.py
index 67a350415..e7b2cd76d 100755
--- a/kolla/cmd/build.py
+++ b/kolla/cmd/build.py
@@ -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
diff --git a/kolla/common/config.py b/kolla/common/config.py
index f0ff3b4e5..f27506b67 100755
--- a/kolla/common/config.py
+++ b/kolla/common/config.py
@@ -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'),
]
diff --git a/kolla/image/build.py b/kolla/image/build.py
index 2172cb4be..3acc4d6e7 100755
--- a/kolla/image/build.py
+++ b/kolla/image/build.py
@@ -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()):
- LOG.error('%s Failed with status: %s', name, status.value)
+ 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
@@ -1228,12 +1238,17 @@ class KollaWorker(object):
elif image.status == Status.UNBUILDABLE:
self.image_statuses_unbuildable[image.name] = image.status
else:
- self.image_statuses_bad[image.name] = image.status
+ 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')
diff --git a/kolla/tests/test_build.py b/kolla/tests/test_build.py
index 00bdd6d32..8dd34f2fd 100644
--- a/kolla/tests/test_build.py
+++ b/kolla/tests/test_build.py
@@ -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)
diff --git a/releasenotes/notes/allowed-to-fail-e2ff5bf61c857b55.yaml b/releasenotes/notes/allowed-to-fail-e2ff5bf61c857b55.yaml
new file mode 100644
index 000000000..595c97b18
--- /dev/null
+++ b/releasenotes/notes/allowed-to-fail-e2ff5bf61c857b55.yaml
@@ -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.