summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-03-30 13:42:22 +0000
committerGerrit Code Review <review@openstack.org>2017-03-30 13:42:23 +0000
commitf37bf1bf272b3d779ad88b90ac9dd30caadc5e33 (patch)
treee6259cf0e3d4990deadc5dedeccbef691a1ab115
parenta32b2d7d4b2aecf4657106ad70007e17dd652be7 (diff)
parente5410950c4cd3f89bef44f07f354cd71d8038105 (diff)
downloadkolla-f37bf1bf272b3d779ad88b90ac9dd30caadc5e33.tar.gz
kolla-f37bf1bf272b3d779ad88b90ac9dd30caadc5e33.zip
Merge "Allow the use of previously built parent images"
-rwxr-xr-xkolla/cmd/build.py3
-rwxr-xr-xkolla/common/config.py2
-rwxr-xr-xkolla/image/build.py41
-rw-r--r--kolla/tests/test_build.py23
-rw-r--r--releasenotes/notes/build-skip-parents-102a82736935f027.yaml6
-rw-r--r--tests/test_build.py3
6 files changed, 66 insertions, 12 deletions
diff --git a/kolla/cmd/build.py b/kolla/cmd/build.py
index 4674de762..69e1138e9 100755
--- a/kolla/cmd/build.py
+++ b/kolla/cmd/build.py
@@ -29,7 +29,8 @@ from kolla.image import build
def main():
statuses = build.run_build()
if statuses:
- bad_results, good_results, unmatched_results = statuses
+ (bad_results, good_results, unmatched_results,
+ skipped_results) = statuses
if bad_results:
return 1
return 0
diff --git a/kolla/common/config.py b/kolla/common/config.py
index 047963498..db4668246 100755
--- a/kolla/common/config.py
+++ b/kolla/common/config.py
@@ -156,6 +156,8 @@ _CLI_OPTS = [
help='The base image name. Default is the same with base'),
cfg.BoolOpt('debug', short='d', default=False,
help='Turn on debugging log level'),
+ cfg.BoolOpt('skip-parents', default=False,
+ help='Do not rebuild parents of matched images'),
cfg.DictOpt('build-args',
help='Set docker build time variables'),
cfg.BoolOpt('keep', default=False,
diff --git a/kolla/image/build.py b/kolla/image/build.py
index 7db9a24a0..125a3bdcb 100755
--- a/kolla/image/build.py
+++ b/kolla/image/build.py
@@ -88,6 +88,7 @@ STATUS_BUILDING = 'building'
STATUS_UNMATCHED = 'unmatched'
STATUS_MATCHED = 'matched'
STATUS_UNPROCESSED = 'unprocessed'
+STATUS_SKIPPED = 'skipped'
# All error status constants.
STATUS_ERRORS = (STATUS_CONNECTION_ERROR, STATUS_PUSH_ERROR,
@@ -257,7 +258,7 @@ class BuildTask(DockerTask):
def run(self):
self.builder(self.image)
- if self.image.status == STATUS_BUILT:
+ if self.image.status in (STATUS_BUILT, STATUS_SKIPPED):
self.success = True
@property
@@ -395,6 +396,11 @@ class BuildTask(DockerTask):
return len(os.listdir(items_path))
self.logger.debug('Processing')
+
+ if image.status == STATUS_SKIPPED:
+ self.logger.info('Skipping %s (--skip-parents)' % image.name)
+ return
+
if image.status == STATUS_UNMATCHED:
return
@@ -567,6 +573,7 @@ class KollaWorker(object):
self.image_statuses_bad = dict()
self.image_statuses_good = dict()
self.image_statuses_unmatched = dict()
+ self.image_statuses_skipped = dict()
self.maintainer = conf.maintainer
def _get_images_dir(self):
@@ -787,14 +794,18 @@ class KollaWorker(object):
if filter_:
patterns = re.compile(r"|".join(filter_).join('()'))
for image in self.images:
- if image.status == STATUS_MATCHED:
+ if image.status in (STATUS_MATCHED, STATUS_SKIPPED):
continue
if re.search(patterns, image.name):
image.status = STATUS_MATCHED
while (image.parent is not None and
- image.parent.status != STATUS_MATCHED):
+ image.parent.status not in (STATUS_MATCHED,
+ STATUS_SKIPPED)):
image = image.parent
- image.status = STATUS_MATCHED
+ if self.conf.skip_parents:
+ image.status = STATUS_SKIPPED
+ else:
+ image.status = STATUS_MATCHED
LOG.debug('Image %s matched regex', image.name)
else:
image.status = STATUS_UNMATCHED
@@ -815,6 +826,7 @@ class KollaWorker(object):
'built': [],
'failed': [],
'not_matched': [],
+ 'skipped': [],
}
if self.image_statuses_good:
@@ -848,25 +860,40 @@ class KollaWorker(object):
'name': name,
})
+ if self.image_statuses_skipped:
+ LOG.debug("=====================================")
+ LOG.debug("Images skipped due to --skip-parents")
+ LOG.debug("=====================================")
+ for name in self.image_statuses_skipped.keys():
+ LOG.debug(name)
+ results['skipped'].append({
+ 'name': name,
+ })
+
return results
def get_image_statuses(self):
if any([self.image_statuses_bad,
self.image_statuses_good,
- self.image_statuses_unmatched]):
+ self.image_statuses_unmatched,
+ self.image_statuses_skipped]):
return (self.image_statuses_bad,
self.image_statuses_good,
- self.image_statuses_unmatched)
+ self.image_statuses_unmatched,
+ self.image_statuses_skipped)
for image in self.images:
if image.status == STATUS_BUILT:
self.image_statuses_good[image.name] = image.status
elif image.status == STATUS_UNMATCHED:
self.image_statuses_unmatched[image.name] = image.status
+ elif image.status == STATUS_SKIPPED:
+ self.image_statuses_skipped[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_unmatched,
+ self.image_statuses_skipped)
def build_image_list(self):
def process_source_installation(image, section):
diff --git a/kolla/tests/test_build.py b/kolla/tests/test_build.py
index a5b020b1b..8f1fac835 100644
--- a/kolla/tests/test_build.py
+++ b/kolla/tests/test_build.py
@@ -209,6 +209,7 @@ class KollaWorkerTest(base.TestCase):
image.status = None
image_child = FAKE_IMAGE_CHILD.copy()
image_child.status = None
+ image_child.parent.status = None
image_unmatched = FAKE_IMAGE_CHILD_UNMATCHED.copy()
image_error = FAKE_IMAGE_CHILD_ERROR.copy()
image_built = FAKE_IMAGE_CHILD_BUILT.copy()
@@ -292,6 +293,15 @@ class KollaWorkerTest(base.TestCase):
return [image for image in images
if image.status == build.STATUS_MATCHED]
+ def test_skip_parents(self):
+ self.conf.set_override('regex', 'image-child')
+ self.conf.set_override('skip_parents', True)
+ kolla = build.KollaWorker(self.conf)
+ kolla.images = self.images
+ kolla.filter_images()
+
+ self.assertEqual(build.STATUS_SKIPPED, kolla.images[1].parent.status)
+
def test_without_profile(self):
kolla = build.KollaWorker(self.conf)
kolla.images = self.images
@@ -361,14 +371,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)
@@ -381,7 +391,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)
@@ -390,3 +400,10 @@ class MainTest(base.TestCase):
def test_run_build(self, mock_sys):
result = build.run_build()
self.assertTrue(result)
+
+ @mock.patch.object(build, 'run_build')
+ def test_skipped_images(self, mock_run_build):
+ image_statuses = ({}, {}, {}, {'img': 'skipped'})
+ mock_run_build.return_value = image_statuses
+ result = build_cmd.main()
+ self.assertEqual(0, result)
diff --git a/releasenotes/notes/build-skip-parents-102a82736935f027.yaml b/releasenotes/notes/build-skip-parents-102a82736935f027.yaml
new file mode 100644
index 000000000..baef7e411
--- /dev/null
+++ b/releasenotes/notes/build-skip-parents-102a82736935f027.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Added a new build argument '--skip-parents', which will result in only
+ the image(s) specified by the regex and their children to be built.
+ Parents are expected to exist either on machine or in a registry.
diff --git a/tests/test_build.py b/tests/test_build.py
index 6eb783f59..01a9dedce 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -47,7 +47,8 @@ class BuildTest(object):
def runTest(self):
with patch.object(sys, 'argv', self.build_args):
LOG.info("Running with args %s", self.build_args)
- bad_results, good_results, unmatched_results = build.run_build()
+ (bad_results, good_results, unmatched_results,
+ skipped_results) = build.run_build()
failures = 0
for image, result in bad_results.items():