Library wrapper around kolla-build tool
This adds a python library which allows container images to be created using the kolla-build tool. The yaml format used by contrib/overcloud_containers.yaml is used to specify which images to build. It is also possible to specify the path to kolla conf files. Every kolla option can be set by a conf file, so this is sufficient to modify kolla-build behaviour. The namespace and the tag in overcloud_containers.yaml is ignored since this is driven by the kolla configuration. The image prefixes like 'centos-binary-' are removed before passing the remaining image name to kolla as a regex match. This will be used by the new command "overcloud container image build" Change-Id: I061f626fdb3d71613aa23436bf6c53cf4de62213
This commit is contained in:
parent
75754c4658
commit
b04c4d90cd
76
tripleo_common/image/kolla_builder.py
Normal file
76
tripleo_common/image/kolla_builder.py
Normal file
@ -0,0 +1,76 @@
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from tripleo_common.image import base
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
import codecs
|
||||
_open = open
|
||||
open = codecs.open
|
||||
|
||||
|
||||
class KollaImageBuilder(base.BaseImageManager):
|
||||
"""Build images using kolla-build"""
|
||||
|
||||
logger = logging.getLogger(__name__ + '.KollaImageBuilder')
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
|
||||
@staticmethod
|
||||
def imagename_to_regex(imagename):
|
||||
if not imagename:
|
||||
return
|
||||
# remove any namespace from the start
|
||||
imagename = imagename.split('/')[-1]
|
||||
|
||||
# remove any tag from the end
|
||||
imagename = imagename.split(':')[0]
|
||||
|
||||
# remove supported base names from the start
|
||||
imagename = re.sub(r'^(centos|rhel)-', '', imagename)
|
||||
|
||||
# remove install_type from the start
|
||||
imagename = re.sub(r'^(binary|source|rdo|rhos)-', '', imagename)
|
||||
|
||||
# what results should be acceptable as a regex to build one image
|
||||
return imagename
|
||||
|
||||
def build_images(self, kolla_config_files=None):
|
||||
|
||||
cmd = ['kolla-build']
|
||||
if kolla_config_files:
|
||||
for f in kolla_config_files:
|
||||
cmd.append('--config-file')
|
||||
cmd.append(f)
|
||||
|
||||
container_images = self.load_config_files(self.CONTAINER_IMAGES) or []
|
||||
container_images.sort(key=lambda i: i.get('imagename'))
|
||||
for i in container_images:
|
||||
image = self.imagename_to_regex(i.get('imagename'))
|
||||
if image:
|
||||
cmd.append(image)
|
||||
|
||||
self.logger.info('Running %s' % ' '.join(cmd))
|
||||
env = os.environ.copy()
|
||||
process = subprocess.Popen(cmd, env=env)
|
||||
process.wait()
|
||||
if process.returncode != 0:
|
||||
raise subprocess.CalledProcessError(process.returncode, cmd)
|
107
tripleo_common/tests/image/test_kolla_builder.py
Normal file
107
tripleo_common/tests/image/test_kolla_builder.py
Normal file
@ -0,0 +1,107 @@
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
import mock
|
||||
import os
|
||||
import six
|
||||
import subprocess
|
||||
|
||||
from tripleo_common.image import kolla_builder as kb
|
||||
from tripleo_common.tests import base
|
||||
|
||||
|
||||
filedata = six.u(
|
||||
"""container_images:
|
||||
- imagename: tripleoupstream/heat-docker-agents-centos:latest
|
||||
push_destination: localhost:8787
|
||||
- imagename: tripleoupstream/centos-binary-nova-compute:liberty
|
||||
uploader: docker
|
||||
pull_source: docker.io
|
||||
push_destination: localhost:8787
|
||||
- imagename: tripleoupstream/centos-binary-nova-libvirt:liberty
|
||||
uploader: docker
|
||||
pull_source: docker.io
|
||||
""")
|
||||
|
||||
|
||||
class TestKollaImageBuilder(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestKollaImageBuilder, self).setUp()
|
||||
files = []
|
||||
files.append('testfile')
|
||||
self.filelist = files
|
||||
|
||||
def test_imagename_to_regex(self):
|
||||
itr = kb.KollaImageBuilder.imagename_to_regex
|
||||
self.assertIsNone(itr(''))
|
||||
self.assertIsNone(itr(None))
|
||||
self.assertEqual('foo', itr('foo'))
|
||||
self.assertEqual('foo', itr('foo:latest'))
|
||||
self.assertEqual('foo', itr('tripleo/foo:latest'))
|
||||
self.assertEqual('foo', itr('tripleo/foo'))
|
||||
self.assertEqual('foo', itr('tripleo/centos-binary-foo:latest'))
|
||||
self.assertEqual('foo', itr('centos-binary-foo:latest'))
|
||||
self.assertEqual('foo', itr('centos-binary-foo'))
|
||||
|
||||
@mock.patch('tripleo_common.image.base.open',
|
||||
mock.mock_open(read_data=filedata), create=True)
|
||||
@mock.patch('os.path.isfile', return_value=True)
|
||||
@mock.patch('subprocess.Popen')
|
||||
def test_build_images(self, mock_popen, mock_path):
|
||||
process = mock.Mock()
|
||||
process.returncode = 0
|
||||
mock_popen.return_value = process
|
||||
|
||||
builder = kb.KollaImageBuilder(self.filelist)
|
||||
builder.build_images(['kolla-config.conf'])
|
||||
env = os.environ.copy()
|
||||
mock_popen.assert_called_once_with([
|
||||
'kolla-build',
|
||||
'--config-file',
|
||||
'kolla-config.conf',
|
||||
'nova-compute',
|
||||
'nova-libvirt',
|
||||
'heat-docker-agents-centos',
|
||||
], env=env)
|
||||
|
||||
@mock.patch('subprocess.Popen')
|
||||
def test_build_images_no_conf(self, mock_popen):
|
||||
process = mock.Mock()
|
||||
process.returncode = 0
|
||||
mock_popen.return_value = process
|
||||
|
||||
builder = kb.KollaImageBuilder([])
|
||||
builder.build_images([])
|
||||
env = os.environ.copy()
|
||||
mock_popen.assert_called_once_with([
|
||||
'kolla-build',
|
||||
], env=env)
|
||||
|
||||
@mock.patch('subprocess.Popen')
|
||||
def test_build_images_fail(self, mock_popen):
|
||||
process = mock.Mock()
|
||||
process.returncode = 1
|
||||
mock_popen.return_value = process
|
||||
|
||||
builder = kb.KollaImageBuilder([])
|
||||
self.assertRaises(subprocess.CalledProcessError,
|
||||
builder.build_images,
|
||||
[])
|
||||
env = os.environ.copy()
|
||||
mock_popen.assert_called_once_with([
|
||||
'kolla-build',
|
||||
], env=env)
|
Loading…
x
Reference in New Issue
Block a user