Removed overcloud container commands

The following commands have been removed:

  overcloud container image upload
  overcloud container image build
  overcloud container image prepare
  overcloud container image tag discover

They were replaced by the tripleo container based commands and no longer
function.

Change-Id: Ic1f4d76c9e7bf3579b7e47d87b0ee2c86251c0d6
This commit is contained in:
Alex Schultz 2021-11-17 08:17:13 -07:00
parent 98e692d00f
commit f321bb4688
5 changed files with 7 additions and 1179 deletions

View File

@ -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
===================

View File

@ -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.

View File

@ -44,10 +44,6 @@ openstack.tripleoclient.v2 =
overcloud_cell_export = tripleoclient.v1.overcloud_cell:ExportCell
overcloud_ceph_deploy = tripleoclient.v2.overcloud_ceph:OvercloudCephDeploy
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

View File

@ -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)

View File

@ -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."""