container image build: introduce --use-buildah
Support Buildah instead of Docker by calling: $ openstack container image build --use-buildah And it will build TripleO containers with Buildah and not Docker. Co-Authored-By: Alex Schultz <aschultz@redhat.com> Change-Id: I7608136cb213bdca81348a0c3c751b488f48d712
This commit is contained in:
parent
f848e42d93
commit
48525b19bc
|
@ -146,7 +146,7 @@ testscenarios===0.4
|
|||
testtools==2.2.0
|
||||
tooz==1.58.0
|
||||
traceback2==1.4.0
|
||||
tripleo-common==10.2.0
|
||||
tripleo-common==10.4.0
|
||||
ujson==1.35
|
||||
unittest2==1.1.0
|
||||
vine==1.1.4
|
||||
|
|
|
@ -16,5 +16,5 @@ simplejson>=3.5.1 # MIT
|
|||
six>=1.10.0 # MIT
|
||||
osc-lib>=1.8.0 # Apache-2.0
|
||||
websocket-client>=0.44.0 # LGPLv2+
|
||||
tripleo-common>=10.2.0 # Apache-2.0
|
||||
tripleo-common>=10.4.0 # Apache-2.0
|
||||
cryptography>=2.1 # BSD/Apache-2.0
|
||||
|
|
|
@ -20,6 +20,7 @@ import logging
|
|||
import mock
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import socket
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
@ -37,6 +38,7 @@ import yaml
|
|||
from tripleoclient import exceptions
|
||||
from tripleoclient import utils
|
||||
|
||||
from six.moves.configparser import ConfigParser
|
||||
from six.moves.urllib import error as url_error
|
||||
|
||||
|
||||
|
@ -1302,3 +1304,44 @@ class TestCheckEnvForProxy(TestCase):
|
|||
self.assertRaises(RuntimeError,
|
||||
utils.check_env_for_proxy,
|
||||
['foo', 'bar'])
|
||||
|
||||
|
||||
class TestConfigParser(TestCase):
|
||||
def setUp(self):
|
||||
self.tmp_dir = tempfile.mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
if self.tmp_dir:
|
||||
shutil.rmtree(self.tmp_dir)
|
||||
self.tmp_dir = None
|
||||
|
||||
def test_get_config_value(self):
|
||||
cfile, cfile_name = tempfile.mkstemp(dir=self.tmp_dir)
|
||||
cfp = open(cfile_name, 'w')
|
||||
cfg = ConfigParser()
|
||||
cfg.add_section('foo')
|
||||
cfg.set('foo', 'bar', 'baz')
|
||||
cfg.write(cfp)
|
||||
cfp.close()
|
||||
config = utils.get_config_value(cfile_name, 'foo', 'bar')
|
||||
self.assertEqual(config, 'baz')
|
||||
|
||||
def test_get_config_value_multiple_files(self):
|
||||
_, cfile1_name = tempfile.mkstemp(dir=self.tmp_dir, text=True)
|
||||
_, cfile2_name = tempfile.mkstemp(dir=self.tmp_dir, text=True)
|
||||
cfiles = [cfile1_name, cfile2_name]
|
||||
cfg = ConfigParser()
|
||||
cfg.add_section('foo')
|
||||
cfg.set('foo', 'bar', 'baz')
|
||||
with open(cfile1_name, 'w') as fp:
|
||||
cfg.write(fp)
|
||||
cfg.set('foo', 'bar', 'boop')
|
||||
with open(cfile2_name, 'w') as fp:
|
||||
cfg.write(fp)
|
||||
config = utils.get_config_value(cfiles, 'foo', 'bar')
|
||||
self.assertEqual(config, 'boop')
|
||||
|
||||
def test_get_config_value_bad_file(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
utils.get_config_value,
|
||||
'does-not-exist', 'foo', 'bar')
|
||||
|
|
|
@ -500,7 +500,52 @@ class TestContainerImageBuild(TestPluginV1):
|
|||
mock_builder.return_value.build_images.assert_called_once_with([
|
||||
self.default_kolla_conf, '/tmp/kolla.conf',
|
||||
path
|
||||
], [])
|
||||
], [], False, None)
|
||||
|
||||
@mock.patch('os.fdopen', autospec=True)
|
||||
@mock.patch('tempfile.mkdtemp')
|
||||
@mock.patch('tempfile.mkstemp')
|
||||
@mock.patch('tripleoclient.v1.container_image.BuildImage.kolla_cfg')
|
||||
@mock.patch('tripleo_common.image.builder.buildah.BuildahBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('os.remove')
|
||||
def test_container_image_build_with_buildah(self, mock_remove,
|
||||
mock_builder, mock_buildah,
|
||||
mock_kolla_cfg, mock_mkstemp,
|
||||
mock_mkdtemp, mock_fdopen):
|
||||
arglist = [
|
||||
'--config-file',
|
||||
'/tmp/bar.yaml',
|
||||
'--kolla-config-file',
|
||||
'/tmp/kolla.conf',
|
||||
'--use-buildah'
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
deps = '{"base": ["qrouterd"]}'
|
||||
mock_builder.return_value.build_images.return_value = deps
|
||||
|
||||
mock_mkstemp.return_value = (1, '/tmp/whatever_file')
|
||||
mock_mkdtemp.return_value = '/tmp/whatever_dir'
|
||||
|
||||
mock_bb = mock.MagicMock()
|
||||
mock_bb.build_all = mock.MagicMock()
|
||||
mock_buildah.return_value = mock_bb
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
cfg_files = list(parsed_args.kolla_config_files)
|
||||
cfg_files.append('/tmp/whatever_file')
|
||||
cfg_calls = [
|
||||
mock.call(cfg_files, 'base'),
|
||||
mock.call(cfg_files, 'type'),
|
||||
mock.call(cfg_files, 'tag'),
|
||||
mock.call(cfg_files, 'namespace'),
|
||||
mock.call(cfg_files, 'registry'),
|
||||
]
|
||||
mock_kolla_cfg.assert_has_calls(cfg_calls)
|
||||
mock_bb.build_all.assert_called_once()
|
||||
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
|
@ -532,7 +577,7 @@ class TestContainerImageBuild(TestPluginV1):
|
|||
mock_builder.return_value.build_images.assert_called_once_with([
|
||||
self.default_kolla_conf, '/tmp/kolla.conf',
|
||||
path
|
||||
], ['foo', 'bar'])
|
||||
], ['foo', 'bar'], False, None)
|
||||
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
|
|
|
@ -21,6 +21,7 @@ import glob
|
|||
import hashlib
|
||||
import logging
|
||||
import shutil
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
@ -1457,3 +1458,17 @@ def check_env_for_proxy(no_proxy_hosts=None):
|
|||
'addresses "{}" may be missing from the no_proxy '
|
||||
'environment variable').format(','.join(missing_hosts))
|
||||
raise RuntimeError(message)
|
||||
|
||||
|
||||
def get_config_value(cfg, section, option):
|
||||
"""Return the value of an option in ini config file(s)"""
|
||||
config = ConfigParser()
|
||||
config.read(cfg)
|
||||
try:
|
||||
val = config.get(section, option)
|
||||
except Exception:
|
||||
raise exceptions.NotFound(_('Unable to find {section}/{option} in '
|
||||
'{config}').format(section=section,
|
||||
option=option,
|
||||
config=cfg))
|
||||
return val
|
||||
|
|
|
@ -28,6 +28,7 @@ from osc_lib.i18n import _
|
|||
import six
|
||||
import yaml
|
||||
|
||||
from tripleo_common.image.builder import buildah
|
||||
from tripleo_common.image import image_uploader
|
||||
from tripleo_common.image import kolla_builder
|
||||
|
||||
|
@ -170,8 +171,21 @@ class BuildImage(command.Command):
|
|||
"containers to be built to skip. Can be specified multiple "
|
||||
"times."),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--use-buildah',
|
||||
dest='use_buildah',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Use Buildah instead of Docker to build the images '
|
||||
'with Kolla.')
|
||||
)
|
||||
return parser
|
||||
|
||||
@staticmethod
|
||||
def kolla_cfg(cfg, param):
|
||||
"""Return a parameter from Kolla config"""
|
||||
return utils.get_config_value(cfg, 'DEFAULT', param)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
|
@ -182,12 +196,32 @@ class BuildImage(command.Command):
|
|||
tmp.write('list_dependencies=true')
|
||||
kolla_config_files = list(parsed_args.kolla_config_files)
|
||||
kolla_config_files.append(path)
|
||||
kolla_tmp_dir = None
|
||||
if parsed_args.use_buildah:
|
||||
# A temporary directory is needed to let Kolla generates the
|
||||
# Dockerfiles that will be used by Buildah to build the images.
|
||||
kolla_tmp_dir = tempfile.mkdtemp(prefix='kolla-')
|
||||
|
||||
try:
|
||||
builder = kolla_builder.KollaImageBuilder(parsed_args.config_files)
|
||||
result = builder.build_images(kolla_config_files,
|
||||
parsed_args.excludes)
|
||||
if parsed_args.list_dependencies:
|
||||
parsed_args.excludes,
|
||||
parsed_args.use_buildah,
|
||||
kolla_tmp_dir)
|
||||
|
||||
if parsed_args.use_buildah:
|
||||
deps = json.loads(result)
|
||||
cfg = kolla_config_files
|
||||
bb = buildah.BuildahBuilder(kolla_tmp_dir, deps,
|
||||
BuildImage.kolla_cfg(cfg, 'base'),
|
||||
BuildImage.kolla_cfg(cfg, 'type'),
|
||||
BuildImage.kolla_cfg(cfg, 'tag'),
|
||||
BuildImage.kolla_cfg(cfg,
|
||||
'namespace'),
|
||||
BuildImage.kolla_cfg(cfg,
|
||||
'registry'))
|
||||
bb.build_all()
|
||||
elif parsed_args.list_dependencies:
|
||||
deps = json.loads(result)
|
||||
yaml.safe_dump(deps, self.app.stdout, indent=2,
|
||||
default_flow_style=False)
|
||||
|
|
Loading…
Reference in New Issue