Merge "Removed overcloud container commands"
This commit is contained in:
commit
d63f84c6d9
@ -12,9 +12,6 @@ Container Commands
|
||||
.. autoprogram-cliff:: openstack.tripleoclient.v2
|
||||
:command: tripleo container *
|
||||
|
||||
.. autoprogram-cliff:: openstack.tripleoclient.v2
|
||||
:command: overcloud container image [!prep]*
|
||||
|
||||
===================
|
||||
Undercloud Commands
|
||||
===================
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
Removed `overcloud container image upload`, `overcloud container image build`,
|
||||
`overcloud container image prepare` and `overcloud container image tag`
|
||||
commands as the `tripleo container` command replaced those in Train and
|
||||
they no longer work.
|
@ -46,10 +46,6 @@ openstack.tripleoclient.v2 =
|
||||
overcloud_ceph_user_disable = tripleoclient.v2.overcloud_ceph:OvercloudCephUserDisable
|
||||
overcloud_ceph_user_enable = tripleoclient.v2.overcloud_ceph:OvercloudCephUserEnable
|
||||
overcloud_config_download = tripleoclient.v1.overcloud_config:DownloadConfig
|
||||
overcloud_container_image_upload = tripleoclient.v1.container_image:UploadImage
|
||||
overcloud_container_image_build = tripleoclient.v1.container_image:BuildImage
|
||||
overcloud_container_image_prepare = tripleoclient.v1.container_image:PrepareImageFiles
|
||||
overcloud_container_image_tag_discover = tripleoclient.v1.container_image:DiscoverImageTag
|
||||
overcloud_delete = tripleoclient.v2.overcloud_delete:DeleteOvercloud
|
||||
overcloud_credentials = tripleoclient.v1.overcloud_credentials:OvercloudCredentials
|
||||
overcloud_deploy = tripleoclient.v1.overcloud_deploy:DeployOvercloud
|
||||
|
@ -13,76 +13,20 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import fixtures
|
||||
from io import StringIO
|
||||
import os
|
||||
import requests
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from urllib import parse
|
||||
import uuid
|
||||
import yaml
|
||||
from unittest import mock
|
||||
|
||||
from osc_lib import exceptions as oscexc
|
||||
from tripleo_common.image import kolla_builder
|
||||
from tripleoclient import constants
|
||||
from tripleoclient.tests.v1.test_plugin import TestPluginV1
|
||||
from tripleoclient.v1 import container_image
|
||||
|
||||
|
||||
class TestContainerImageUpload(TestPluginV1):
|
||||
|
||||
def setUp(self):
|
||||
super(TestContainerImageUpload, self).setUp()
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = container_image.UploadImage(self.app, None)
|
||||
|
||||
@mock.patch('tripleo_common.utils.locks.processlock.'
|
||||
'ProcessLock')
|
||||
@mock.patch('sys.exit')
|
||||
@mock.patch('tripleo_common.image.image_uploader.ImageUploadManager')
|
||||
def test_container_image_upload_noargs(self, mock_manager, exit_mock,
|
||||
mock_lock):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
mock_lockobj = mock.MagicMock()
|
||||
mock_lock.return_value = mock_lockobj
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
# argparse will complain that --config-file is missing and exit with 2
|
||||
exit_mock.assert_called_with(2)
|
||||
|
||||
@mock.patch('tripleo_common.utils.locks.processlock.'
|
||||
'ProcessLock')
|
||||
@mock.patch('tripleo_common.image.image_uploader.ImageUploadManager')
|
||||
def test_container_image_upload_conf_files(self, mock_manager, mock_lock):
|
||||
arglist = [
|
||||
'--config-file',
|
||||
'/tmp/foo.yaml',
|
||||
'--config-file',
|
||||
'/tmp/bar.yaml'
|
||||
]
|
||||
verifylist = []
|
||||
|
||||
mock_lockobj = mock.MagicMock()
|
||||
mock_lock.return_value = mock_lockobj
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_manager.assert_called_once_with(
|
||||
['/tmp/foo.yaml', '/tmp/bar.yaml'], cleanup='full',
|
||||
lock=mock_lockobj)
|
||||
mock_manager.return_value.upload.assert_called_once_with()
|
||||
|
||||
|
||||
class TestContainerImagePush(TestPluginV1):
|
||||
def setUp(self):
|
||||
super(TestContainerImagePush, self).setUp()
|
||||
@ -535,345 +479,6 @@ class TestContainerImageShow(TestPluginV1):
|
||||
(['Name', 'Layers'], ['foo', 'bar']))
|
||||
|
||||
|
||||
class TestContainerImagePrepare(TestPluginV1):
|
||||
|
||||
def setUp(self):
|
||||
super(TestContainerImagePrepare, self).setUp()
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = container_image.PrepareImageFiles(self.app, None)
|
||||
kolla_builder.DEFAULT_TEMPLATE_FILE = os.path.join(
|
||||
'/tmp/overcloud_containers.yaml.j2'
|
||||
)
|
||||
self.roles_yaml = '''
|
||||
- name: EnabledRole
|
||||
CountDefault: 1
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::AodhEvaluator
|
||||
- name: RoleDisabledViaRolesData
|
||||
CountDefault: 0
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::AodhApi
|
||||
- name: RoleDisabledViaEnvironment
|
||||
CountDefault: 1
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::Disabled
|
||||
- name: RoleOverwrittenViaEnvironment
|
||||
CountDefault: 1
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::Overwritten
|
||||
'''
|
||||
|
||||
@mock.patch('tripleo_common.image.kolla_builder.'
|
||||
'container_images_prepare_defaults', create=True)
|
||||
@mock.patch('tripleo_common.image.kolla_builder.'
|
||||
'container_images_prepare', create=True)
|
||||
@mock.patch('requests.get')
|
||||
@mock.patch('tripleo_common.image.kolla_builder.'
|
||||
'build_service_filter')
|
||||
def test_container_image_prepare_noargs(self, mock_bsf, mock_get, mock_cip,
|
||||
mock_cipd):
|
||||
mock_bsf.return_value = None
|
||||
mock_cipd.return_value = {
|
||||
'neutron_driver': 'ovn',
|
||||
'name_suffix': '',
|
||||
'tag': 'latest',
|
||||
'namespace': 'docker.io/tripleomaster',
|
||||
'name_prefix':
|
||||
'centos-binary-'
|
||||
}
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
mock_cip.return_value = {'container_images.yaml': {}}
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_cip.assert_called_with(
|
||||
excludes=[],
|
||||
includes=[],
|
||||
mapping_args={
|
||||
'neutron_driver': 'ovn',
|
||||
'name_suffix': '',
|
||||
'tag': 'latest',
|
||||
'namespace': 'docker.io/tripleomaster',
|
||||
'name_prefix':
|
||||
'centos-binary-'
|
||||
},
|
||||
output_env_file=None,
|
||||
output_images_file='container_images.yaml',
|
||||
push_destination=None,
|
||||
service_filter=None,
|
||||
tag_from_label=None,
|
||||
modify_role=None,
|
||||
modify_vars=None,
|
||||
append_tag=None,
|
||||
template_file=kolla_builder.DEFAULT_TEMPLATE_FILE
|
||||
)
|
||||
|
||||
@mock.patch('tripleoclient.utils.fetch_roles_file')
|
||||
@mock.patch('tripleo_common.image.kolla_builder.'
|
||||
'container_images_prepare_defaults', create=True)
|
||||
@mock.patch('tripleo_common.image.kolla_builder.'
|
||||
'container_images_prepare', create=True)
|
||||
@mock.patch('heatclient.common.template_utils.'
|
||||
'process_multiple_environments_and_files')
|
||||
@mock.patch('tripleo_common.image.kolla_builder.'
|
||||
'build_service_filter')
|
||||
@mock.patch('requests.get')
|
||||
def test_container_image_prepare(self, mock_get, mock_bsf, pmef, mock_cip,
|
||||
mock_cipd, mock_roles):
|
||||
|
||||
temp = tempfile.mkdtemp()
|
||||
self.addCleanup(shutil.rmtree, temp)
|
||||
images_file = os.path.join(temp, 'overcloud_containers.yaml')
|
||||
env_file = os.path.join(temp, 'containers_env.yaml')
|
||||
tmpl_file = os.path.join(temp, 'overcloud_containers.yaml.j2')
|
||||
aodh_file = os.path.join(temp, 'docker', 'services', 'aodh.yaml')
|
||||
roles_file = os.path.join(temp, 'roles_data.yaml')
|
||||
with open(roles_file, 'w') as f:
|
||||
f.write(self.roles_yaml)
|
||||
modify_vars_file = os.path.join(temp, 'modify_vars.yaml')
|
||||
with open(modify_vars_file, 'w') as f:
|
||||
f.write('foo: bar')
|
||||
mock_get.side_effect = requests.exceptions.SSLError('ouch')
|
||||
mock_bsf.return_value = set(['OS::TripleO::Services::AodhEvaluator'])
|
||||
|
||||
resource_registry = {
|
||||
'parameter_defaults': {
|
||||
'NeutronMechanismDrivers': 'ovn',
|
||||
},
|
||||
'resource_registry': {
|
||||
'OS::TripleO::Services::AodhEvaluator': aodh_file,
|
||||
'OS::TripleO::Services::AodhApi': aodh_file
|
||||
}
|
||||
}
|
||||
pmef.return_value = None, resource_registry
|
||||
|
||||
arglist = [
|
||||
'--template-file',
|
||||
tmpl_file,
|
||||
'--tag',
|
||||
'passed-ci',
|
||||
'--namespace',
|
||||
'192.0.2.0:8787/t',
|
||||
'--prefix',
|
||||
'os-',
|
||||
'--suffix',
|
||||
'foo',
|
||||
'--output-images-file',
|
||||
images_file,
|
||||
'--output-env-file',
|
||||
env_file,
|
||||
'--set',
|
||||
'ceph_namespace=myceph',
|
||||
'--set',
|
||||
'ceph_image=mydaemon',
|
||||
'--set',
|
||||
'ceph_tag=mytag',
|
||||
'-e',
|
||||
'environment/docker-ha.yaml',
|
||||
'--roles-file',
|
||||
roles_file,
|
||||
'--modify-role',
|
||||
'foo-role',
|
||||
'--modify-vars',
|
||||
modify_vars_file
|
||||
]
|
||||
self.cmd.app.command_options = arglist
|
||||
verifylist = []
|
||||
mock_cip.return_value = {images_file: [{
|
||||
'imagename': '192.0.2.0:8787/t/os-aodh-apifoo:passed-ci',
|
||||
}, {
|
||||
'imagename': '192.0.2.0:8787/t/os-aodh-evaluatorfoo:passed-ci',
|
||||
}], env_file: {
|
||||
'DockerAodhApiImage':
|
||||
'192.0.2.0:8787/t/os-aodh-apifoo:passed-ci',
|
||||
'DockerAodhConfigImage':
|
||||
'192.0.2.0:8787/t/os-aodh-apifoo:passed-ci',
|
||||
'DockerAodhEvaluatorImage':
|
||||
'192.0.2.0:8787/t/os-aodh-evaluatorfoo:passed-ci',
|
||||
'DockerInsecureRegistryAddress': ['192.0.2.0:8787']
|
||||
}
|
||||
}
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
pmef.assert_called_once_with(['environment/docker-ha.yaml'],
|
||||
env_path_is_object=mock.ANY,
|
||||
object_request=mock.ANY)
|
||||
mock_cip.assert_called_once_with(
|
||||
excludes=[],
|
||||
includes=[],
|
||||
mapping_args={
|
||||
'namespace': '192.0.2.0:8787/t',
|
||||
'name_suffix': 'foo',
|
||||
'ceph_tag': 'mytag',
|
||||
'ceph_image': 'mydaemon',
|
||||
'tag': 'passed-ci',
|
||||
'neutron_driver': 'ovn',
|
||||
'ceph_namespace': 'myceph',
|
||||
'name_prefix': 'os-'
|
||||
},
|
||||
output_env_file=env_file,
|
||||
output_images_file=images_file,
|
||||
push_destination=None,
|
||||
service_filter=set([
|
||||
'OS::TripleO::Services::AodhEvaluator',
|
||||
]),
|
||||
tag_from_label=None,
|
||||
modify_role='foo-role',
|
||||
modify_vars={'foo': 'bar'},
|
||||
append_tag=mock.ANY,
|
||||
template_file=tmpl_file
|
||||
)
|
||||
ci_data = {
|
||||
'container_images': [{
|
||||
'imagename': '192.0.2.0:8787/t/os-aodh-apifoo:passed-ci',
|
||||
}, {
|
||||
'imagename': '192.0.2.0:8787/t/os-aodh-evaluatorfoo:passed-ci',
|
||||
}]
|
||||
}
|
||||
env_data = {
|
||||
'parameter_defaults': {
|
||||
'DockerAodhApiImage':
|
||||
'192.0.2.0:8787/t/os-aodh-apifoo:passed-ci',
|
||||
'DockerAodhConfigImage':
|
||||
'192.0.2.0:8787/t/os-aodh-apifoo:passed-ci',
|
||||
'DockerAodhEvaluatorImage':
|
||||
'192.0.2.0:8787/t/os-aodh-evaluatorfoo:passed-ci',
|
||||
'DockerInsecureRegistryAddress': ['192.0.2.0:8787']
|
||||
}
|
||||
}
|
||||
with open(images_file) as f:
|
||||
self.assertEqual(ci_data, yaml.safe_load(f))
|
||||
with open(env_file) as f:
|
||||
self.assertEqual(env_data, yaml.safe_load(f))
|
||||
|
||||
|
||||
class TestTripleoImagePrepare(TestPluginV1):
|
||||
|
||||
def setUp(self):
|
||||
super(TestTripleoImagePrepare, self).setUp()
|
||||
# Get the command object to test
|
||||
self.cmd = container_image.TripleOImagePrepare(self.app, None)
|
||||
self.cmd.app_args = mock.Mock()
|
||||
self.cmd.app_args.verbose_level = 3
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.addCleanup(shutil.rmtree, self.temp_dir)
|
||||
self.prepare_default_file = os.path.join(
|
||||
self.temp_dir, 'prepare_env.yaml')
|
||||
default_param = kolla_builder.CONTAINER_IMAGE_PREPARE_PARAM
|
||||
self.default_env = {
|
||||
'parameter_defaults': {
|
||||
'ContainerImagePrepare': default_param
|
||||
}
|
||||
}
|
||||
with open(self.prepare_default_file, 'w') as f:
|
||||
yaml.safe_dump(self.default_env, f)
|
||||
|
||||
self.roles_yaml = '''
|
||||
- name: EnabledRole
|
||||
CountDefault: 1
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::AodhEvaluator
|
||||
- name: RoleDisabledViaRolesData
|
||||
CountDefault: 0
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::AodhApi
|
||||
- name: RoleDisabledViaEnvironment
|
||||
CountDefault: 1
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::Disabled
|
||||
- name: RoleOverwrittenViaEnvironment
|
||||
CountDefault: 1
|
||||
ServicesDefault:
|
||||
- OS::TripleO::Services::Overwritten
|
||||
'''
|
||||
self.roles_data_file = os.path.join(
|
||||
self.temp_dir, 'roles_data.yaml')
|
||||
with open(self.roles_data_file, 'w') as f:
|
||||
f.write(self.roles_yaml)
|
||||
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_tripleo_container_image_prepare(self, mock_playbook):
|
||||
|
||||
env_file = os.path.join(self.temp_dir, 'containers_env.yaml')
|
||||
|
||||
arglist = [
|
||||
'--environment-file', self.prepare_default_file,
|
||||
'--roles-file', self.roles_data_file,
|
||||
'--output-env-file', env_file
|
||||
]
|
||||
verifylist = []
|
||||
|
||||
self.app.command_options = [
|
||||
'tripleo', 'container', 'image', 'prepare'
|
||||
] + arglist
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
e_vars = {'roles_file': self.roles_data_file,
|
||||
'environment_directories': [mock.ANY],
|
||||
'environment_files': [self.temp_dir + '/prepare_env.yaml'],
|
||||
'cleanup': 'full', 'dry_run': False,
|
||||
'log_file': 'container_image_prepare.log', 'debug': True,
|
||||
'output_env_file': self.temp_dir + '/containers_env.yaml'}
|
||||
|
||||
mock_playbook.assert_called_with(
|
||||
extra_vars=e_vars,
|
||||
inventory='localhost,',
|
||||
playbook='cli-container-image-prepare.yaml',
|
||||
playbook_dir='/usr/share/ansible/tripleo-playbooks',
|
||||
verbosity=3, workdir=mock.ANY)
|
||||
|
||||
@mock.patch('tripleoclient.utils.rel_or_abs_path')
|
||||
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
||||
autospec=True)
|
||||
def test_tripleo_container_image_prepare_paths(self, mock_playbook,
|
||||
mock_path):
|
||||
arglist = ['-e', 'foo.yaml',
|
||||
'-e', '/bar.yaml',
|
||||
'--environment-directory', 'foo',
|
||||
'--environment-directory', '/bar',
|
||||
'-r', 'foo.yaml']
|
||||
verifylist = []
|
||||
self.app.command_options = [
|
||||
'tripleo', 'container', 'image', 'prepare'
|
||||
] + arglist
|
||||
|
||||
mock_path.return_value = ('/usr/share/openstack-tripleo-heat-templates'
|
||||
'/foo.yaml')
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
e_vars = {'roles_file': ('/usr/share/'
|
||||
'openstack-tripleo-heat-templates/foo.yaml'),
|
||||
'environment_directories': [
|
||||
os.path.expanduser(constants.DEFAULT_ENV_DIRECTORY),
|
||||
os.getcwd() + '/foo',
|
||||
'/bar'
|
||||
],
|
||||
'environment_files': [
|
||||
os.getcwd() + '/foo.yaml',
|
||||
'/bar.yaml'
|
||||
],
|
||||
'cleanup': 'full', 'dry_run': False,
|
||||
'log_file': 'container_image_prepare.log', 'debug': True}
|
||||
|
||||
mock_playbook.assert_called_with(
|
||||
extra_vars=e_vars,
|
||||
inventory='localhost,',
|
||||
playbook='cli-container-image-prepare.yaml',
|
||||
playbook_dir='/usr/share/ansible/tripleo-playbooks',
|
||||
verbosity=3, workdir=mock.ANY)
|
||||
|
||||
|
||||
class TestTripleoImagePrepareDefault(TestPluginV1):
|
||||
|
||||
def setUp(self):
|
||||
@ -949,279 +554,3 @@ class TestTripleoImagePrepareDefault(TestPluginV1):
|
||||
True,
|
||||
result['parameter_defaults']['ContainerImageRegistryLogin']
|
||||
)
|
||||
|
||||
|
||||
class TestContainerImageBuild(TestPluginV1):
|
||||
|
||||
def setUp(self):
|
||||
super(TestContainerImageBuild, self).setUp()
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = container_image.BuildImage(self.app, None)
|
||||
self.cmd.app.stdout = StringIO()
|
||||
self.uuid = str(uuid.uuid4())
|
||||
self.temp_dir = os.path.join(self.useFixture(
|
||||
fixtures.TempDir()).join())
|
||||
self.temp_dir_uuid = os.path.join(self.temp_dir, self.uuid)
|
||||
|
||||
# Default conf file
|
||||
self.default_kolla_conf = os.path.join(
|
||||
sys.prefix, 'share', 'tripleo-common', 'container-images',
|
||||
'tripleo_kolla_config_overrides.conf')
|
||||
|
||||
@mock.patch('sys.exit')
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('os.makedirs')
|
||||
def test_container_image_build_noargs(self, mock_mkdirs, mock_builder,
|
||||
exit_mock):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
mock_builder.return_value.build_images.return_value = 'done'
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
f, path = tempfile.mkstemp(dir=self.temp_dir)
|
||||
with mock.patch('tempfile.mkstemp') as mock_mkstemp:
|
||||
mock_mkstemp.return_value = f, path
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
# argparse will complain that --config-file is missing and exit with 2
|
||||
exit_mock.assert_called_with(2)
|
||||
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('uuid.uuid4')
|
||||
def test_container_image_build(self, mock_uuid, mock_builder):
|
||||
arglist = [
|
||||
'--config-file',
|
||||
'/tmp/foo.yaml',
|
||||
'--config-file',
|
||||
'/tmp/bar.yaml',
|
||||
'--work-dir',
|
||||
self.temp_dir,
|
||||
'--kolla-config-file',
|
||||
'/tmp/kolla.conf'
|
||||
]
|
||||
verifylist = []
|
||||
mock_builder.return_value.build_images.return_value = 'done'
|
||||
mock_uuid.return_value = self.uuid
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
f, path = tempfile.mkstemp(dir=self.temp_dir)
|
||||
with mock.patch('tempfile.mkstemp') as mock_mkstemp:
|
||||
with mock.patch('os.chdir'):
|
||||
mock_mkstemp.return_value = f, path
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_builder.assert_called_once_with([
|
||||
'/tmp/foo.yaml', '/tmp/bar.yaml'])
|
||||
mock_builder.return_value.build_images.assert_called_once_with([
|
||||
self.default_kolla_conf, '/tmp/kolla.conf',
|
||||
path
|
||||
], [], False, self.temp_dir_uuid)
|
||||
|
||||
@mock.patch('os.chdir')
|
||||
@mock.patch('os.fdopen', autospec=True)
|
||||
@mock.patch('tempfile.mkstemp')
|
||||
@mock.patch(
|
||||
'tripleoclient.utils.get_from_cfg')
|
||||
@mock.patch(
|
||||
'tripleoclient.utils.getboolean_from_cfg')
|
||||
@mock.patch('tripleo_common.image.builder.buildah.BuildahBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('tripleoclient.utils.get_read_config')
|
||||
@mock.patch('os.remove')
|
||||
def test_container_image_build_with_buildah(self, mock_remove,
|
||||
mock_read_conf,
|
||||
mock_builder, mock_buildah,
|
||||
mock_kolla_boolean_cfg,
|
||||
mock_kolla_cfg, mock_mkstemp,
|
||||
mock_fdopen, mock_chdir):
|
||||
arglist = [
|
||||
'--config-file',
|
||||
'/tmp/bar.yaml',
|
||||
'--kolla-config-file',
|
||||
'/tmp/kolla.conf',
|
||||
'--use-buildah',
|
||||
'--work-dir',
|
||||
self.temp_dir,
|
||||
]
|
||||
|
||||
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_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')
|
||||
mock_read_conf.assert_any_call(cfg_files)
|
||||
cfg_calls = [
|
||||
mock.call(mock_read_conf.return_value, 'base'),
|
||||
mock.call(mock_read_conf.return_value, 'type'),
|
||||
mock.call(mock_read_conf.return_value, 'tag'),
|
||||
mock.call(mock_read_conf.return_value, 'namespace'),
|
||||
mock.call(mock_read_conf.return_value, 'registry'),
|
||||
]
|
||||
cfg_boolean_calls = [
|
||||
mock.call(mock_read_conf.return_value, 'push'),
|
||||
]
|
||||
mock_kolla_cfg.assert_has_calls(cfg_calls)
|
||||
mock_kolla_boolean_cfg.assert_has_calls(cfg_boolean_calls)
|
||||
mock_bb.build_all.assert_called_once()
|
||||
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('uuid.uuid4')
|
||||
def test_container_image_build_with_exclude(self, mock_uuid, mock_builder):
|
||||
arglist = [
|
||||
'--config-file',
|
||||
'/tmp/foo.yaml',
|
||||
'--config-file',
|
||||
'/tmp/bar.yaml',
|
||||
'--kolla-config-file',
|
||||
'/tmp/kolla.conf',
|
||||
'--work-dir',
|
||||
'/tmp/testing',
|
||||
'--exclude',
|
||||
'foo',
|
||||
'--exclude',
|
||||
'bar'
|
||||
]
|
||||
verifylist = []
|
||||
mock_builder.return_value.build_images.return_value = 'done'
|
||||
mock_uuid.return_value = '123'
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
f, path = tempfile.mkstemp(dir=self.temp_dir)
|
||||
with mock.patch('tempfile.mkdtemp') as mock_mkd:
|
||||
mock_mkd.return_value = '/tmp/testing'
|
||||
with mock.patch('tempfile.mkstemp') as mock_mkstemp:
|
||||
with mock.patch('os.chdir'):
|
||||
mock_mkstemp.return_value = f, path
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_builder.assert_called_once_with([
|
||||
'/tmp/foo.yaml', '/tmp/bar.yaml'])
|
||||
mock_builder.return_value.build_images.assert_called_once_with([
|
||||
self.default_kolla_conf, '/tmp/kolla.conf',
|
||||
path
|
||||
], ['foo', 'bar'], False, '/tmp/testing/123')
|
||||
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('os.remove')
|
||||
def test_container_image_build_list_images(self, mock_remove,
|
||||
mock_builder):
|
||||
arglist = [
|
||||
'--list-images',
|
||||
'--config-file',
|
||||
'/tmp/bar.yaml',
|
||||
'--work-dir',
|
||||
'/tmp/testing',
|
||||
'--kolla-config-file',
|
||||
'/tmp/kolla.conf'
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
deps = '{"base": ["qrouterd"]}'
|
||||
mock_builder.return_value.build_images.return_value = deps
|
||||
|
||||
f, path = tempfile.mkstemp(dir=self.temp_dir)
|
||||
with mock.patch('tempfile.mkstemp') as mock_mkstemp:
|
||||
mock_mkstemp.return_value = f, path
|
||||
self.cmd.take_action(parsed_args)
|
||||
with open(path, 'r') as conf_file:
|
||||
self.assertEqual(
|
||||
conf_file.readlines(),
|
||||
['[DEFAULT]\n', 'list_dependencies=true'])
|
||||
self.assertEqual('- base\n- qrouterd\n',
|
||||
self.cmd.app.stdout.getvalue())
|
||||
|
||||
@mock.patch('tripleo_common.image.kolla_builder.KollaImageBuilder',
|
||||
autospec=True)
|
||||
@mock.patch('os.remove')
|
||||
@mock.patch('os.makedirs')
|
||||
def test_container_image_build_list_deps(self, mock_mkdirs, mock_remove,
|
||||
mock_builder):
|
||||
arglist = [
|
||||
'--config-file',
|
||||
'/tmp/bar.yaml',
|
||||
'--kolla-config-file',
|
||||
'/tmp/kolla.conf',
|
||||
'--list-dependencies',
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
deps = '{"base": ["qrouterd"]}'
|
||||
mock_builder.return_value.build_images.return_value = deps
|
||||
|
||||
f, path = tempfile.mkstemp(dir=self.temp_dir)
|
||||
with mock.patch('tempfile.mkstemp') as mock_mkstemp:
|
||||
mock_mkstemp.return_value = f, path
|
||||
self.cmd.take_action(parsed_args)
|
||||
with open(path, 'r') as conf_file:
|
||||
self.assertEqual(
|
||||
conf_file.readlines(),
|
||||
['[DEFAULT]\n', 'list_dependencies=true'])
|
||||
self.assertEqual('base:\n- qrouterd\n',
|
||||
self.cmd.app.stdout.getvalue())
|
||||
|
||||
def test_images_from_deps(self):
|
||||
deps = yaml.safe_load('''base:
|
||||
- qdrouterd
|
||||
- cron
|
||||
- ceph-base:
|
||||
- ceph-osd
|
||||
- ceph-rgw
|
||||
- ceph-mon
|
||||
- cephfs-fuse
|
||||
- ceph-mds
|
||||
- redis
|
||||
- etcd
|
||||
- kubernetes-entrypoint
|
||||
- kolla-toolbox
|
||||
- telegraf
|
||||
- openstack-base:
|
||||
- swift-base:
|
||||
- swift-proxy-server
|
||||
- swift-account
|
||||
- swift-container
|
||||
- swift-object-expirer
|
||||
- swift-rsyncd
|
||||
- swift-object''')
|
||||
|
||||
images_yaml = '''- base
|
||||
- qdrouterd
|
||||
- cron
|
||||
- ceph-base
|
||||
- ceph-osd
|
||||
- ceph-rgw
|
||||
- ceph-mon
|
||||
- cephfs-fuse
|
||||
- ceph-mds
|
||||
- redis
|
||||
- etcd
|
||||
- kubernetes-entrypoint
|
||||
- kolla-toolbox
|
||||
- telegraf
|
||||
- openstack-base
|
||||
- swift-base
|
||||
- swift-proxy-server
|
||||
- swift-account
|
||||
- swift-container
|
||||
- swift-object-expirer
|
||||
- swift-rsyncd
|
||||
- swift-object
|
||||
'''
|
||||
images = []
|
||||
self.cmd.images_from_deps(images, deps)
|
||||
self.assertEqual(yaml.safe_load(images_yaml), images)
|
||||
|
@ -17,21 +17,15 @@ import copy
|
||||
import datetime
|
||||
import errno
|
||||
from io import StringIO
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from osc_lib import exceptions as oscexc
|
||||
from osc_lib.i18n import _
|
||||
from urllib import parse
|
||||
import yaml
|
||||
|
||||
from tripleo_common.image.builder import buildah
|
||||
from tripleo_common.image import image_uploader
|
||||
from tripleo_common.image import kolla_builder
|
||||
from tripleo_common.utils.locks import processlock
|
||||
@ -56,501 +50,6 @@ def build_env_file(params, command_options):
|
||||
return f.getvalue()
|
||||
|
||||
|
||||
class UploadImage(command.Command):
|
||||
"""Push overcloud container images to registries."""
|
||||
|
||||
auth_required = False
|
||||
log = logging.getLogger(__name__ + ".UploadImage")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UploadImage, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"--config-file",
|
||||
dest="config_files",
|
||||
metavar='<yaml config file>',
|
||||
default=[],
|
||||
action="append",
|
||||
required=True,
|
||||
help=_("YAML config file specifying the image build. May be "
|
||||
"specified multiple times. Order is preserved, and later "
|
||||
"files will override some options in previous files. "
|
||||
"Other options will append."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cleanup",
|
||||
dest="cleanup",
|
||||
metavar='<full, partial, none>',
|
||||
default=image_uploader.CLEANUP_FULL,
|
||||
help=_("Cleanup behavior for local images left after upload. "
|
||||
"The default 'full' will attempt to delete all local "
|
||||
"images. 'partial' will leave images required for "
|
||||
"deployment on this host. 'none' will do no cleanup.")
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
if parsed_args.cleanup not in image_uploader.CLEANUP:
|
||||
raise oscexc.CommandError('--cleanup must be one of: %s' %
|
||||
', '.join(image_uploader.CLEANUP))
|
||||
lock = processlock.ProcessLock()
|
||||
uploader = image_uploader.ImageUploadManager(
|
||||
parsed_args.config_files, cleanup=parsed_args.cleanup, lock=lock)
|
||||
try:
|
||||
uploader.upload()
|
||||
except KeyboardInterrupt: # ctrl-c
|
||||
self.log.warning('Upload was interrupted by ctrl-c.')
|
||||
|
||||
|
||||
class BuildImage(command.Command):
|
||||
"""Build overcloud container images with kolla-build."""
|
||||
|
||||
auth_required = False
|
||||
log = logging.getLogger(__name__ + ".BuildImage")
|
||||
|
||||
@staticmethod
|
||||
def images_from_deps(images, dep):
|
||||
'''Builds a list from the dependencies depth-first. '''
|
||||
if isinstance(dep, list):
|
||||
for v in dep:
|
||||
BuildImage.images_from_deps(images, v)
|
||||
elif isinstance(dep, dict):
|
||||
for k, v in dep.items():
|
||||
images.append(k)
|
||||
BuildImage.images_from_deps(images, v)
|
||||
else:
|
||||
images.append(dep)
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
default_kolla_conf = os.path.join(
|
||||
sys.prefix, 'share', 'tripleo-common', 'container-images',
|
||||
'tripleo_kolla_config_overrides.conf')
|
||||
parser = super(BuildImage, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"--config-file",
|
||||
dest="config_files",
|
||||
metavar='<yaml config file>',
|
||||
default=[],
|
||||
action="append",
|
||||
help=_("YAML config file specifying the images to build. May be "
|
||||
"specified multiple times. Order is preserved, and later "
|
||||
"files will override some options in previous files. "
|
||||
"Other options will append. If not specified, the default "
|
||||
"set of containers will be built."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--kolla-config-file",
|
||||
dest="kolla_config_files",
|
||||
metavar='<config file>',
|
||||
default=[default_kolla_conf],
|
||||
action="append",
|
||||
required=True,
|
||||
help=_("Path to a Kolla config file to use. Multiple config files "
|
||||
"can be specified, with values in later files taking "
|
||||
"precedence. By default, tripleo kolla conf file {conf} "
|
||||
"is added.").format(conf=default_kolla_conf),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--list-images',
|
||||
dest='list_images',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Show the images which would be built instead of '
|
||||
'building them.')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--list-dependencies',
|
||||
dest='list_dependencies',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Show the image build dependencies instead of '
|
||||
'building them.')
|
||||
)
|
||||
parser.add_argument(
|
||||
"--exclude",
|
||||
dest="excludes",
|
||||
metavar='<container-name>',
|
||||
default=[],
|
||||
action="append",
|
||||
help=_("Name of a container to match against the list of "
|
||||
"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.')
|
||||
)
|
||||
parser.add_argument(
|
||||
"--work-dir",
|
||||
dest="work_dir",
|
||||
default='/tmp/container-builds',
|
||||
metavar='<container builds directory>',
|
||||
help=_("TripleO container builds directory, storing configs and "
|
||||
"logs for each image and its dependencies.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--build-timeout",
|
||||
dest="build_timeout",
|
||||
default=None,
|
||||
type=int,
|
||||
metavar="<build timeout in seconds>",
|
||||
help=_("Build timeout in seconds.")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
self.log.warning('This command is deprecated. Please use "openstack '
|
||||
'tripleo container image build" instead.')
|
||||
|
||||
fd, path = tempfile.mkstemp(prefix='kolla_conf_')
|
||||
with os.fdopen(fd, 'w') as tmp:
|
||||
tmp.write('[DEFAULT]\n')
|
||||
if parsed_args.list_images or parsed_args.list_dependencies:
|
||||
tmp.write('list_dependencies=true')
|
||||
kolla_config_files = list(parsed_args.kolla_config_files)
|
||||
kolla_config_files.append(path)
|
||||
# Generate an unique work directory so we can keep configs and logs
|
||||
# each time we run the command; they'll be stored in work_dir.
|
||||
kolla_work_dir = os.path.join(parsed_args.work_dir, str(uuid.uuid4()))
|
||||
|
||||
# Make sure the unique work directory exists
|
||||
if not os.path.exists(kolla_work_dir):
|
||||
self.log.debug("Creating container builds "
|
||||
"workspace in: %s" % kolla_work_dir)
|
||||
os.makedirs(kolla_work_dir)
|
||||
|
||||
builder = kolla_builder.KollaImageBuilder(parsed_args.config_files)
|
||||
result = builder.build_images(kolla_config_files,
|
||||
parsed_args.excludes,
|
||||
parsed_args.use_buildah,
|
||||
kolla_work_dir)
|
||||
|
||||
if parsed_args.use_buildah:
|
||||
deps = json.loads(result)
|
||||
kolla_cfg = utils.get_read_config(kolla_config_files)
|
||||
bb = buildah.BuildahBuilder(
|
||||
kolla_work_dir, deps,
|
||||
utils.get_from_cfg(kolla_cfg, "base"),
|
||||
utils.get_from_cfg(kolla_cfg, "type"),
|
||||
utils.get_from_cfg(kolla_cfg, "tag"),
|
||||
utils.get_from_cfg(kolla_cfg, "namespace"),
|
||||
utils.get_from_cfg(kolla_cfg, "registry"),
|
||||
utils.getboolean_from_cfg(kolla_cfg, "push"),
|
||||
parsed_args.build_timeout,
|
||||
self.app.options.debug)
|
||||
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
|
||||
)
|
||||
elif parsed_args.list_images:
|
||||
deps = json.loads(result)
|
||||
images = []
|
||||
BuildImage.images_from_deps(images, deps)
|
||||
yaml.safe_dump(
|
||||
images,
|
||||
self.app.stdout,
|
||||
default_flow_style=False
|
||||
)
|
||||
elif result:
|
||||
self.app.stdout.write(result)
|
||||
|
||||
|
||||
class PrepareImageFiles(command.Command):
|
||||
"""Generate files defining the images, tags and registry."""
|
||||
|
||||
auth_required = False
|
||||
log = logging.getLogger(__name__ + ".PrepareImageFiles")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(PrepareImageFiles, self).get_parser(prog_name)
|
||||
try:
|
||||
roles_file = utils.rel_or_abs_path(
|
||||
constants.OVERCLOUD_ROLES_FILE,
|
||||
constants.TRIPLEO_HEAT_TEMPLATES)
|
||||
except exceptions.DeploymentError:
|
||||
roles_file = None
|
||||
defaults = kolla_builder.container_images_prepare_defaults()
|
||||
|
||||
parser.add_argument(
|
||||
"--template-file",
|
||||
dest="template_file",
|
||||
default=kolla_builder.DEFAULT_TEMPLATE_FILE,
|
||||
metavar='<yaml template file>',
|
||||
help=_("YAML template file which the images config file will be "
|
||||
"built from.\n"
|
||||
"Default: %s") % kolla_builder.DEFAULT_TEMPLATE_FILE,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--push-destination",
|
||||
dest="push_destination",
|
||||
metavar='<location>',
|
||||
help=_("Location of image registry to push images to. "
|
||||
"If specified, a push_destination will be set for every "
|
||||
"image entry."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tag",
|
||||
dest="tag",
|
||||
default=defaults['tag'],
|
||||
metavar='<tag>',
|
||||
help=_("Override the default tag substitution. "
|
||||
"If --tag-from-label is specified, "
|
||||
"start discovery with this tag.\n"
|
||||
"Default: %s") % defaults['tag'],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tag-from-label",
|
||||
dest="tag_from_label",
|
||||
metavar='<image label>',
|
||||
help=_("Use the value of the specified label(s) to discover the "
|
||||
"tag. Labels can be combined in a template format, "
|
||||
"for example: {version}-{release}"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--namespace",
|
||||
dest="namespace",
|
||||
default=defaults['namespace'],
|
||||
metavar='<namespace>',
|
||||
help=_("Override the default namespace substitution.\n"
|
||||
"Default: %s") % defaults['namespace'],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--prefix",
|
||||
dest="prefix",
|
||||
default=defaults['name_prefix'],
|
||||
metavar='<prefix>',
|
||||
help=_("Override the default name prefix substitution.\n"
|
||||
"Default: %s") % defaults['name_prefix'],
|
||||
)
|
||||
parser.add_argument(
|
||||
"--suffix",
|
||||
dest="suffix",
|
||||
default=defaults['name_suffix'],
|
||||
metavar='<suffix>',
|
||||
help=_("Override the default name suffix substitution.\n"
|
||||
"Default: %s") % defaults['name_suffix'],
|
||||
)
|
||||
parser.add_argument(
|
||||
'--set',
|
||||
metavar='<variable=value>',
|
||||
action='append',
|
||||
help=_('Set the value of a variable in the template, even if it '
|
||||
'has no dedicated argument such as "--suffix".')
|
||||
)
|
||||
parser.add_argument(
|
||||
"--exclude",
|
||||
dest="excludes",
|
||||
metavar='<regex>',
|
||||
default=[],
|
||||
action="append",
|
||||
help=_("Pattern to match against resulting imagename entries to "
|
||||
"exclude from the final output. Can be specified multiple "
|
||||
"times."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--include",
|
||||
dest="includes",
|
||||
metavar='<regex>',
|
||||
default=[],
|
||||
action="append",
|
||||
help=_("Pattern to match against resulting imagename entries to "
|
||||
"include in final output. Can be specified multiple "
|
||||
"times, entries not matching any --include will be "
|
||||
"excluded. --exclude is ignored if --include is used."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output-images-file",
|
||||
dest="output_images_file",
|
||||
metavar='<file path>',
|
||||
help=_("File to write resulting image entries to, as well as "
|
||||
"stdout. Any existing file will be overwritten."),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--environment-file', '-e', metavar='<file path>',
|
||||
action='append', dest='environment_files',
|
||||
help=_('Environment files specifying which services are '
|
||||
'containerized. Entries will be filtered to only contain '
|
||||
'images used by containerized services. (Can be specified '
|
||||
'more than once.)')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--environment-directory', metavar='<HEAT ENVIRONMENT DIRECTORY>',
|
||||
action='append', dest='environment_directories',
|
||||
default=[os.path.expanduser(constants.DEFAULT_ENV_DIRECTORY)],
|
||||
help=_('Environment file directories that are automatically '
|
||||
'added to the update command. Entries will be filtered '
|
||||
'to only contain images used by containerized services. '
|
||||
'Can be specified more than once. Files in directories are '
|
||||
'loaded in ascending sort order.')
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output-env-file",
|
||||
dest="output_env_file",
|
||||
metavar='<file path>',
|
||||
help=_("File to write heat environment file which specifies all "
|
||||
"image parameters. Any existing file will be overwritten."),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--roles-file', '-r', dest='roles_file',
|
||||
default=roles_file,
|
||||
help=_(
|
||||
'Roles file, overrides the default %s in the t-h-t templates '
|
||||
'directory used for deployment. May be an '
|
||||
'absolute path or the path relative to the templates dir.'
|
||||
) % constants.OVERCLOUD_ROLES_FILE
|
||||
)
|
||||
parser.add_argument(
|
||||
'--modify-role',
|
||||
dest='modify_role',
|
||||
help=_('Name of ansible role to run between every image upload '
|
||||
'pull and push.')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--modify-vars',
|
||||
dest='modify_vars',
|
||||
help=_('Ansible variable file containing variables to use when '
|
||||
'invoking the role --modify-role.')
|
||||
)
|
||||
return parser
|
||||
|
||||
def parse_set_values(self, subs, set_values):
|
||||
if not set_values:
|
||||
return
|
||||
for s in set_values:
|
||||
try:
|
||||
(n, v) = s.split(('='), 1)
|
||||
subs[n] = v
|
||||
except ValueError:
|
||||
msg = _('Malformed --set(%s). '
|
||||
'Use the variable=value format.') % s
|
||||
raise oscexc.CommandError(msg)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
self.log.warning("[DEPRECATED] This command has been deprecated and "
|
||||
"replaced by the 'openstack tripleo container image "
|
||||
"prepare' command.")
|
||||
|
||||
roles_data = utils.fetch_roles_file(parsed_args.roles_file) or set()
|
||||
|
||||
env = utils.build_prepare_env(
|
||||
parsed_args.environment_files,
|
||||
parsed_args.environment_directories
|
||||
)
|
||||
|
||||
if roles_data:
|
||||
service_filter = kolla_builder.build_service_filter(
|
||||
env, roles_data)
|
||||
else:
|
||||
service_filter = None
|
||||
mapping_args = {
|
||||
'tag': parsed_args.tag,
|
||||
'namespace': parsed_args.namespace,
|
||||
'name_prefix': parsed_args.prefix,
|
||||
'name_suffix': parsed_args.suffix,
|
||||
}
|
||||
self.parse_set_values(mapping_args, parsed_args.set)
|
||||
pd = env.get('parameter_defaults', {})
|
||||
kolla_builder.set_neutron_driver(pd, mapping_args)
|
||||
|
||||
output_images_file = (parsed_args.output_images_file
|
||||
or 'container_images.yaml')
|
||||
modify_role = None
|
||||
modify_vars = None
|
||||
append_tag = None
|
||||
if parsed_args.modify_role:
|
||||
modify_role = parsed_args.modify_role
|
||||
append_tag = time.strftime('-modified-%Y%m%d%H%M%S')
|
||||
if parsed_args.modify_vars:
|
||||
with open(parsed_args.modify_vars) as m:
|
||||
modify_vars = yaml.safe_load(m.read())
|
||||
|
||||
prepare_data = kolla_builder.container_images_prepare(
|
||||
excludes=parsed_args.excludes,
|
||||
includes=parsed_args.includes,
|
||||
service_filter=service_filter,
|
||||
push_destination=parsed_args.push_destination,
|
||||
mapping_args=mapping_args,
|
||||
output_env_file=parsed_args.output_env_file,
|
||||
output_images_file=output_images_file,
|
||||
tag_from_label=parsed_args.tag_from_label,
|
||||
modify_role=modify_role,
|
||||
modify_vars=modify_vars,
|
||||
append_tag=append_tag,
|
||||
template_file=parsed_args.template_file
|
||||
)
|
||||
if parsed_args.output_env_file:
|
||||
params = prepare_data[parsed_args.output_env_file]
|
||||
output_env_file_expanded = os.path.expanduser(
|
||||
parsed_args.output_env_file)
|
||||
if os.path.exists(output_env_file_expanded):
|
||||
self.log.warning("Output env file exists, "
|
||||
"moving it to backup.")
|
||||
shutil.move(output_env_file_expanded,
|
||||
output_env_file_expanded + ".backup")
|
||||
utils.safe_write(output_env_file_expanded,
|
||||
build_env_file(params, self.app.command_options))
|
||||
|
||||
result = prepare_data[output_images_file]
|
||||
result_str = yaml.safe_dump({'container_images': result},
|
||||
default_flow_style=False)
|
||||
sys.stdout.write(result_str)
|
||||
|
||||
if parsed_args.output_images_file:
|
||||
utils.safe_write(parsed_args.output_images_file, result_str)
|
||||
|
||||
|
||||
class DiscoverImageTag(command.Command):
|
||||
"""Discover the versioned tag for an image."""
|
||||
|
||||
auth_required = False
|
||||
log = logging.getLogger(__name__ + ".DiscoverImageTag")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DiscoverImageTag, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"--image",
|
||||
dest="image",
|
||||
metavar='<container image>',
|
||||
required=True,
|
||||
help=_("Fully qualified name of the image to discover the tag for "
|
||||
"(Including registry and stable tag)."),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tag-from-label",
|
||||
dest="tag_from_label",
|
||||
metavar='<image label>',
|
||||
help=_("Use the value of the specified label(s) to discover the "
|
||||
"tag. Labels can be combined in a template format, "
|
||||
"for example: {version}-{release}"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
self.log.warning("[DEPRECATED] This command has been deprecated and "
|
||||
"replaced by the 'openstack tripleo container image "
|
||||
"prepare' command.")
|
||||
|
||||
lock = processlock.ProcessLock()
|
||||
uploader = image_uploader.ImageUploadManager([], lock=lock)
|
||||
print(uploader.discover_image_tag(
|
||||
image=parsed_args.image,
|
||||
tag_from_label=parsed_args.tag_from_label
|
||||
))
|
||||
|
||||
|
||||
class TripleOContainerImagePush(command.Command):
|
||||
"""Push specified image to registry."""
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user