Align roles file to become a normalized path
Extend the tripleo client Command class to fetch heat roles data from a role file. That new class method is shared by many derived classes afterwards and used for containers images preparations, containerized overcloud, undercloud and standalone deployments. Apply normalization to the roles_file in plan management and preflight checks as well. Change-Id: I7b35e117b9d12f1e5a51e2ee0465244692d33e33 Signed-off-by: Bogdan Dobrelya <bdobreli@redhat.com>
This commit is contained in:
parent
a33b1499d7
commit
8f1caf7abf
6
releasenotes/notes/roles_file-8adea5990682504d.yaml
Normal file
6
releasenotes/notes/roles_file-8adea5990682504d.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
other:
|
||||
- |
|
||||
The roles data file may take either an absolute path or the path relative
|
||||
to the tripleo heat templates directory. This is now applicable for all
|
||||
of the commands involving roles data files.
|
@ -151,8 +151,9 @@ class StandaloneConfig(BaseConfig):
|
||||
),
|
||||
cfg.StrOpt('roles_file',
|
||||
default=None,
|
||||
help=_('Roles file to override for heat. '
|
||||
'The file path is related to the templates path')
|
||||
help=_('Roles file to override for heat. May be an '
|
||||
'absolute path or the path relative to the '
|
||||
't-h-t templates directory used for deployment')
|
||||
),
|
||||
cfg.BoolOpt('heat_native',
|
||||
default=True,
|
||||
|
@ -770,6 +770,33 @@ class GetTripleoAnsibleInventory(TestCase):
|
||||
)
|
||||
|
||||
|
||||
class TestNormalizeFilePath(TestCase):
|
||||
|
||||
@mock.patch('os.path.isfile', return_value=True)
|
||||
def test_norm_path_abs(self, mock_exists):
|
||||
self.assertEqual(
|
||||
utils.rel_or_abs_path('/foobar.yaml', '/tmp'),
|
||||
'/foobar.yaml')
|
||||
|
||||
@mock.patch('os.path.isfile', side_effect=[False, True])
|
||||
def test_norm_path_rel(self, mock_exists):
|
||||
self.assertEqual(
|
||||
utils.rel_or_abs_path('baz/foobar.yaml', '/bar'),
|
||||
'/bar/baz/foobar.yaml')
|
||||
|
||||
|
||||
class TestFetchRolesFile(TestCase):
|
||||
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
def test_fetch_roles_file(self, mock_exists):
|
||||
with tempfile.NamedTemporaryFile(mode='w') as roles_file:
|
||||
yaml.dump([{'name': 'Foobar'}], roles_file)
|
||||
with mock.patch('tripleoclient.utils.rel_or_abs_path') as mock_rf:
|
||||
mock_rf.return_value = roles_file.name
|
||||
self.assertEqual(utils.fetch_roles_file(roles_file.name),
|
||||
[{'name': 'Foobar'}])
|
||||
|
||||
|
||||
class TestOvercloudNameScenarios(TestWithScenarios):
|
||||
scenarios = [
|
||||
('kernel_default',
|
||||
|
@ -1338,8 +1338,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||
mock_create_tempest_deployer_input.assert_called_with()
|
||||
|
||||
def test_get_default_role_counts_defaults(self):
|
||||
parsed_args = mock.Mock()
|
||||
parsed_args.roles_file = None
|
||||
parsed_args = self.check_parser(self.cmd, [], [])
|
||||
defaults = {
|
||||
'ControllerCount': 1,
|
||||
'ComputeCount': 1,
|
||||
@ -1351,11 +1350,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||
defaults,
|
||||
self.cmd._get_default_role_counts(parsed_args))
|
||||
|
||||
@mock.patch("yaml.safe_load")
|
||||
@mock.patch("six.moves.builtins.open")
|
||||
def test_get_default_role_counts_custom_roles(self, mock_open,
|
||||
mock_safe_load):
|
||||
parsed_args = mock.Mock()
|
||||
@mock.patch("tripleoclient.utils.fetch_roles_file")
|
||||
def test_get_default_role_counts_custom_roles(self, mock_roles):
|
||||
roles_data = [
|
||||
{'name': 'ControllerApi', 'CountDefault': 3},
|
||||
{'name': 'ControllerPcmk', 'CountDefault': 3},
|
||||
@ -1363,7 +1359,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||
{'name': 'ObjectStorage', 'CountDefault': 0},
|
||||
{'name': 'BlockStorage'}
|
||||
]
|
||||
mock_safe_load.return_value = roles_data
|
||||
mock_roles.return_value = roles_data
|
||||
role_counts = {
|
||||
'ControllerApiCount': 3,
|
||||
'ControllerPcmkCount': 3,
|
||||
@ -1373,7 +1369,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
||||
}
|
||||
self.assertEqual(
|
||||
role_counts,
|
||||
self.cmd._get_default_role_counts(parsed_args))
|
||||
self.cmd._get_default_role_counts(mock.Mock()))
|
||||
|
||||
@mock.patch(
|
||||
'tripleoclient.workflows.plan_management.list_deployment_plans',
|
||||
|
@ -157,6 +157,7 @@ class TestContainerImagePrepare(TestPluginV1):
|
||||
append_tag=None,
|
||||
)
|
||||
|
||||
@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.'
|
||||
@ -167,7 +168,7 @@ class TestContainerImagePrepare(TestPluginV1):
|
||||
'build_service_filter')
|
||||
@mock.patch('requests.get')
|
||||
def test_container_image_prepare(self, mock_get, mock_bsf, pmef, mock_cip,
|
||||
mock_cipd):
|
||||
mock_cipd, mock_roles):
|
||||
|
||||
temp = tempfile.mkdtemp()
|
||||
self.addCleanup(shutil.rmtree, temp)
|
||||
|
@ -22,7 +22,6 @@ import yaml
|
||||
from heatclient import exc as hc_exc
|
||||
from tripleo_common.image import kolla_builder
|
||||
|
||||
from tripleoclient import constants
|
||||
from tripleoclient import exceptions
|
||||
from tripleoclient.tests.v1.test_plugin import TestPluginV1
|
||||
|
||||
@ -59,53 +58,26 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
self.orc.stacks.create = mock.MagicMock(
|
||||
return_value={'stack': {'id': 'foo'}})
|
||||
|
||||
@mock.patch('os.path.exists', return_value=True)
|
||||
def test_set_roles_file(self, mock_exists):
|
||||
self.cmd._set_roles_file('/foobar.yaml')
|
||||
self.assertEqual(self.cmd.roles_file, '/foobar.yaml')
|
||||
|
||||
@mock.patch('os.path.exists', return_value=False)
|
||||
def test_set_roles_file_relative(self, mock_exists):
|
||||
self.cmd._set_roles_file('foobar.yaml',
|
||||
constants.TRIPLEO_HEAT_TEMPLATES)
|
||||
self.assertEqual(self.cmd.roles_file,
|
||||
'/usr/share/openstack-tripleo-heat-templates/'
|
||||
'foobar.yaml')
|
||||
|
||||
def test_get_roles_data(self):
|
||||
self.cmd.roles_data = [{'name': 'Foobar'}]
|
||||
self.assertEqual(self.cmd._get_roles_data(),
|
||||
[{'name': 'Foobar'}])
|
||||
|
||||
def test_get_roles_data_from_file(self):
|
||||
with tempfile.NamedTemporaryFile(mode='w') as roles_file:
|
||||
yaml.dump([{'name': 'Foobar'}], roles_file)
|
||||
self.cmd.roles_file = roles_file.name
|
||||
self.assertEqual(self.cmd._get_roles_data(),
|
||||
[{'name': 'Foobar'}])
|
||||
|
||||
@mock.patch('os.path.exists', return_value=False)
|
||||
def test_get_roles_data_missing(self, mock_exists):
|
||||
self.cmd.roles_file = '/tmp/foo.yaml'
|
||||
self.cmd.roles_data = None
|
||||
self.assertEqual(self.cmd._get_roles_data(), None)
|
||||
|
||||
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
|
||||
'_get_roles_data')
|
||||
def test_get_primary_role_name(self, mock_data):
|
||||
@mock.patch('os.path.exists')
|
||||
@mock.patch('tripleoclient.utils.fetch_roles_file')
|
||||
def test_get_primary_role_name(self, mock_data, mock_exists):
|
||||
parsed_args = mock.Mock()
|
||||
mock_data.return_value = [
|
||||
{'name': 'Bar'}, {'name': 'Foo', 'tags': ['primary']}
|
||||
]
|
||||
self.assertEqual(self.cmd._get_primary_role_name(), 'Foo')
|
||||
self.assertEqual(self.cmd._get_primary_role_name(parsed_args), 'Foo')
|
||||
|
||||
def test_get_primary_role_name_none_defined(self):
|
||||
self.assertEqual(self.cmd._get_primary_role_name(), 'Controller')
|
||||
@mock.patch('tripleoclient.utils.fetch_roles_file', return_value=None)
|
||||
def test_get_primary_role_name_none_defined(self, mock_data):
|
||||
parsed_args = self.check_parser(self.cmd, [], [])
|
||||
self.assertEqual(self.cmd._get_primary_role_name(parsed_args),
|
||||
'Controller')
|
||||
|
||||
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
|
||||
'_get_roles_data')
|
||||
@mock.patch('tripleoclient.utils.fetch_roles_file')
|
||||
def test_get_primary_role_name_no_primary(self, mock_data):
|
||||
parsed_args = mock.Mock()
|
||||
mock_data.return_value = [{'name': 'Bar'}, {'name': 'Foo'}]
|
||||
self.assertEqual(self.cmd._get_primary_role_name(), 'Bar')
|
||||
self.assertEqual(self.cmd._get_primary_role_name(parsed_args), 'Bar')
|
||||
|
||||
@mock.patch('os.path.exists', side_effect=[True, False])
|
||||
@mock.patch('shutil.copytree')
|
||||
@ -237,6 +209,7 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
mock.call(env_path='/tmp/thtroot42/notouch.yaml'),
|
||||
mock.call(env_path='../outside.yaml')])
|
||||
|
||||
@mock.patch('tripleoclient.utils.rel_or_abs_path')
|
||||
@mock.patch('heatclient.common.template_utils.'
|
||||
'process_environment_and_files', return_value=({}, {}),
|
||||
autospec=True)
|
||||
@ -264,7 +237,8 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
mock_hc_templ_parse,
|
||||
mock_hc_env_parse,
|
||||
mock_hc_get_templ_cont,
|
||||
mock_hc_process):
|
||||
mock_hc_process,
|
||||
mock_norm_path):
|
||||
def hc_process(*args, **kwargs):
|
||||
if 'abs.yaml' in kwargs['env_path']:
|
||||
raise hc_exc.CommandError
|
||||
@ -408,7 +382,6 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
found_dropin = True
|
||||
self.assertTrue(found_dropin)
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
@mock.patch('heatclient.common.template_utils.'
|
||||
'process_environment_and_files', return_value=({}, {}),
|
||||
autospec=True)
|
||||
@ -424,10 +397,12 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
'_update_passwords_env', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.'
|
||||
'run_command_and_log', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
|
||||
'_get_primary_role_name', autospec=True)
|
||||
def test_setup_heat_environments_default_plan_env(
|
||||
self, mock_run, mock_update_pass_env, mock_process_hiera,
|
||||
mock_process_multiple_environments, mock_hc_get_templ_cont,
|
||||
mock_hc_process, mock_os):
|
||||
self, mock_prim, mock_run, mock_update_pass_env,
|
||||
mock_process_hiera, mock_process_multiple_environments,
|
||||
mock_hc_get_templ_cont, mock_hc_process):
|
||||
|
||||
tmpdir = self.useFixture(fixtures.TempDir()).path
|
||||
tht_from = os.path.join(tmpdir, 'tht-from')
|
||||
@ -439,7 +414,6 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
self._setup_heat_environments(tmpdir, tht_from, plan_env_path,
|
||||
mock_update_pass_env, mock_run)
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
@mock.patch('heatclient.common.template_utils.'
|
||||
'process_environment_and_files', return_value=({}, {}),
|
||||
autospec=True)
|
||||
@ -455,10 +429,12 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
'_update_passwords_env', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.'
|
||||
'run_command_and_log', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
|
||||
'_get_primary_role_name', autospec=True)
|
||||
def test_setup_heat_environments_non_default_plan_env(
|
||||
self, mock_run, mock_update_pass_env, mock_process_hiera,
|
||||
mock_process_multiple_environments, mock_hc_get_templ_cont,
|
||||
mock_hc_process, mock_os):
|
||||
self, mock_prim, mock_run, mock_update_pass_env,
|
||||
mock_process_hiera, mock_process_multiple_environments,
|
||||
mock_hc_get_templ_cont, mock_hc_process):
|
||||
|
||||
tmpdir = self.useFixture(fixtures.TempDir()).path
|
||||
tht_from = os.path.join(tmpdir, 'tht-from')
|
||||
@ -502,6 +478,18 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
mock_update_pass_env.return_value = os.path.join(
|
||||
tht_render, 'passwords.yaml')
|
||||
mock_run.return_value = 0
|
||||
original_abs = os.path.abspath
|
||||
|
||||
# Stub abspath for default plan and envs to return the tht_render base
|
||||
def abs_path_stub(*args, **kwargs):
|
||||
if 'plan-environment.yaml' in args:
|
||||
return plan_env_path
|
||||
elif 'notenv.yaml' in args:
|
||||
return os.path.join(tht_render, 'notenv.yaml')
|
||||
elif 'env.yaml' in args:
|
||||
return os.path.join(tht_render, 'env.yaml')
|
||||
else:
|
||||
return original_abs(*args, **kwargs)
|
||||
|
||||
# logic handled in _standalone_deploy
|
||||
self.cmd.output_dir = tht_to
|
||||
@ -535,6 +523,7 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
os.path.join(tht_render, 'foo.yaml'),
|
||||
os.path.join(tht_render, 'outside.yaml')]
|
||||
|
||||
with mock.patch('os.path.abspath', side_effect=abs_path_stub):
|
||||
with mock.patch('os.path.isfile'):
|
||||
environment = self.cmd._setup_heat_environments(parsed_args)
|
||||
|
||||
@ -578,16 +567,16 @@ class TestDeployUndercloud(TestPluginV1):
|
||||
'ansible-playbook', '-i', '/tmp/inventory.yaml',
|
||||
'deploy_steps_playbook.yaml'])
|
||||
|
||||
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
|
||||
'_get_roles_data')
|
||||
@mock.patch('tripleoclient.utils.fetch_roles_file')
|
||||
@mock.patch('tripleo_common.image.kolla_builder.'
|
||||
'container_images_prepare_multi')
|
||||
def test_prepare_container_images(self, mock_cipm, rolesdata_mock):
|
||||
parsed_args = mock.Mock()
|
||||
env = {'parameter_defaults': {}}
|
||||
mock_cipm.return_value = {'FooImage': 'foo/bar:baz'}
|
||||
rolesdata_mock.return_value = [{'name': 'Compute'}]
|
||||
|
||||
self.cmd._prepare_container_images(env)
|
||||
self.cmd._prepare_container_images(env, parsed_args)
|
||||
|
||||
mock_cipm.assert_called_once_with(
|
||||
env,
|
||||
|
@ -81,9 +81,11 @@ class TestPlanCreationWorkflows(utils.TestCommand):
|
||||
|
||||
self.workflow.executions.create.assert_not_called()
|
||||
|
||||
@mock.patch('tripleoclient.utils.rel_or_abs_path')
|
||||
@mock.patch('tripleoclient.workflows.plan_management.tarball',
|
||||
autospec=True)
|
||||
def test_create_plan_from_templates_roles_data(self, mock_tarball):
|
||||
def test_create_plan_from_templates_roles_data(self, mock_tarball,
|
||||
mock_norm_path):
|
||||
output = mock.Mock(output='{"result": ""}')
|
||||
self.workflow.action_executions.create.return_value = output
|
||||
self.websocket.wait_for_messages.return_value = self.message_success
|
||||
@ -106,8 +108,8 @@ class TestPlanCreationWorkflows(utils.TestCommand):
|
||||
workflow_input={'container': 'test-overcloud',
|
||||
'generate_passwords': True})
|
||||
|
||||
mock_open_context.assert_has_calls(
|
||||
[mock.call('the_roles_file.yaml')])
|
||||
self.assertIn(mock.call('the_roles_file.yaml', '/tht-root/'),
|
||||
mock_norm_path.call_args_list)
|
||||
|
||||
self.tripleoclient.object_store.put_object.assert_called_once_with(
|
||||
'test-overcloud', 'roles_data.yaml', mock_open_context())
|
||||
|
@ -45,7 +45,7 @@ from heatclient import exc as hc_exc
|
||||
from six.moves.urllib import error as url_error
|
||||
from six.moves.urllib import request
|
||||
|
||||
|
||||
from tripleoclient import constants
|
||||
from tripleoclient import exceptions
|
||||
|
||||
|
||||
@ -1141,17 +1141,27 @@ def build_prepare_env(environment_files, environment_directories):
|
||||
return env
|
||||
|
||||
|
||||
def rel_or_abs_path(tht_root, file_path):
|
||||
def rel_or_abs_path(file_path, tht_root):
|
||||
'''Find a file, either absolute path or relative to the t-h-t dir'''
|
||||
if not file_path:
|
||||
return None
|
||||
path = os.path.abspath(file_path)
|
||||
if not os.path.exists(path):
|
||||
if not os.path.isfile(path):
|
||||
path = os.path.abspath(os.path.join(tht_root, file_path))
|
||||
if not os.path.exists(path):
|
||||
if not os.path.isfile(path):
|
||||
raise exceptions.DeploymentError(
|
||||
"Can't find path %s %s" % (file_path, path))
|
||||
return path
|
||||
|
||||
|
||||
def fetch_roles_file(roles_file, tht_path=constants.TRIPLEO_HEAT_TEMPLATES):
|
||||
'''Fetch t-h-t roles data fromm roles_file abs path or rel to tht_path.'''
|
||||
if not roles_file:
|
||||
return None
|
||||
with open(rel_or_abs_path(roles_file, tht_path)) as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
|
||||
def load_config(osloconf, path):
|
||||
'''Load oslo config from a file path. '''
|
||||
log = logging.getLogger(__name__ + ".load_config")
|
||||
|
@ -32,6 +32,7 @@ from tripleo_common.image import kolla_builder
|
||||
|
||||
from tripleoclient import command
|
||||
from tripleoclient import constants
|
||||
from tripleoclient import exceptions
|
||||
from tripleoclient import utils
|
||||
|
||||
|
||||
@ -198,9 +199,11 @@ class PrepareImageFiles(command.Command):
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(PrepareImageFiles, self).get_parser(prog_name)
|
||||
roles_file = os.path.join(constants.TRIPLEO_HEAT_TEMPLATES,
|
||||
constants.OVERCLOUD_ROLES_FILE)
|
||||
if not os.path.isfile(roles_file):
|
||||
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()
|
||||
|
||||
@ -358,7 +361,10 @@ class PrepareImageFiles(command.Command):
|
||||
parser.add_argument(
|
||||
'--roles-file', '-r', dest='roles_file',
|
||||
default=roles_file,
|
||||
help=_('Roles file, overrides the default %s'
|
||||
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(
|
||||
@ -390,10 +396,7 @@ class PrepareImageFiles(command.Command):
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
if parsed_args.roles_file:
|
||||
roles_data = yaml.safe_load(open(parsed_args.roles_file).read())
|
||||
else:
|
||||
roles_data = set()
|
||||
roles_data = utils.fetch_roles_file(parsed_args.roles_file) or set()
|
||||
|
||||
env = utils.build_prepare_env(
|
||||
parsed_args.environment_files,
|
||||
@ -546,9 +549,11 @@ class TripleOImagePrepare(command.Command):
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(TripleOImagePrepare, self).get_parser(prog_name)
|
||||
roles_file = os.path.join(constants.TRIPLEO_HEAT_TEMPLATES,
|
||||
constants.OVERCLOUD_ROLES_FILE)
|
||||
if not os.path.isfile(roles_file):
|
||||
try:
|
||||
roles_file = utils.rel_or_abs_path(
|
||||
constants.OVERCLOUD_ROLES_FILE,
|
||||
constants.TRIPLEO_HEAT_TEMPLATES)
|
||||
except exceptions.DeploymentError:
|
||||
roles_file = None
|
||||
parser.add_argument(
|
||||
'--environment-file', '-e', metavar='<file path>',
|
||||
@ -572,7 +577,10 @@ class TripleOImagePrepare(command.Command):
|
||||
parser.add_argument(
|
||||
'--roles-file', '-r', dest='roles_file',
|
||||
default=roles_file,
|
||||
help=_('Roles file to filter images by, overrides the default %s'
|
||||
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(
|
||||
@ -610,10 +618,7 @@ class TripleOImagePrepare(command.Command):
|
||||
raise oscexc.CommandError('--cleanup must be one of: %s' %
|
||||
', '.join(image_uploader.CLEANUP))
|
||||
|
||||
if parsed_args.roles_file:
|
||||
roles_data = yaml.safe_load(open(parsed_args.roles_file).read())
|
||||
else:
|
||||
roles_data = None
|
||||
roles_data = utils.fetch_roles_file(parsed_args.roles_file)
|
||||
|
||||
env = utils.build_prepare_env(
|
||||
parsed_args.environment_files,
|
||||
|
@ -550,7 +550,8 @@ class DeployOvercloud(command.Command):
|
||||
def _get_default_role_counts(self, parsed_args):
|
||||
|
||||
if parsed_args.roles_file:
|
||||
roles_data = yaml.safe_load(open(parsed_args.roles_file).read())
|
||||
roles_data = utils.fetch_roles_file(parsed_args.roles_file,
|
||||
parsed_args.templates)
|
||||
else:
|
||||
# Assume default role counts
|
||||
return {
|
||||
@ -634,7 +635,8 @@ class DeployOvercloud(command.Command):
|
||||
parser.add_argument(
|
||||
'--roles-file', '-r', dest='roles_file',
|
||||
help=_('Roles file, overrides the default %s in the --templates '
|
||||
'directory') % constants.OVERCLOUD_ROLES_FILE
|
||||
'directory. May be an absolute path or the path relative '
|
||||
' to --templates') % constants.OVERCLOUD_ROLES_FILE
|
||||
)
|
||||
parser.add_argument(
|
||||
'--networks-file', '-n', dest='networks_file',
|
||||
|
@ -85,8 +85,6 @@ class Deploy(command.Command):
|
||||
tht_render = None
|
||||
output_dir = None
|
||||
tmp_ansible_dir = None
|
||||
roles_file = None
|
||||
roles_data = None
|
||||
stack_update_mark = None
|
||||
stack_action = 'CREATE'
|
||||
deployment_user = None
|
||||
@ -123,22 +121,6 @@ class Deploy(command.Command):
|
||||
else:
|
||||
os.chmod(file_name, mode)
|
||||
|
||||
def _set_roles_file(self, file_name=None, templates_dir=None):
|
||||
"""Set the roles file for the deployment
|
||||
|
||||
If the file_name is a full path, it will be used. If the file name
|
||||
passed in is not a full path, we will join it with the templates
|
||||
dir and use that instead.
|
||||
|
||||
:param file_name: (String) role file name to use, can be relative to
|
||||
templates directory
|
||||
:param templates_dir:
|
||||
"""
|
||||
if os.path.exists(file_name):
|
||||
self.roles_file = file_name
|
||||
else:
|
||||
self.roles_file = os.path.join(templates_dir, file_name)
|
||||
|
||||
def _set_stack_action(self, parsed_args):
|
||||
"""Set the stack action for deployment"""
|
||||
# Prepare the heat stack action we want to start deployment with
|
||||
@ -151,23 +133,10 @@ class Deploy(command.Command):
|
||||
_('The heat stack {0} action is {1}').format(
|
||||
parsed_args.stack, self.stack_action))
|
||||
|
||||
def _get_roles_data(self):
|
||||
"""Load the roles data for deployment"""
|
||||
# only load once
|
||||
if self.roles_data:
|
||||
return self.roles_data
|
||||
|
||||
if self.roles_file and os.path.exists(self.roles_file):
|
||||
with open(self.roles_file) as f:
|
||||
self.roles_data = yaml.safe_load(f)
|
||||
elif self.roles_file:
|
||||
self.log.warning("roles_data '%s' is not found" % self.roles_file)
|
||||
|
||||
return self.roles_data
|
||||
|
||||
def _get_primary_role_name(self):
|
||||
def _get_primary_role_name(self, parsed_args):
|
||||
"""Return the primary role name"""
|
||||
roles_data = self._get_roles_data()
|
||||
roles_data = utils.fetch_roles_file(parsed_args.roles_file,
|
||||
parsed_args.templates)
|
||||
if not roles_data:
|
||||
# TODO(aschultz): should this be Undercloud instead?
|
||||
return 'Controller'
|
||||
@ -564,11 +533,11 @@ class Deploy(command.Command):
|
||||
parsed_args.templates, self.tht_render, env_files)
|
||||
|
||||
# generate jinja templates by its work dir location
|
||||
self.log.debug(_("Using roles file %s") % self.roles_file)
|
||||
self.log.debug(_("Using roles file %s") % parsed_args.roles_file)
|
||||
process_templates = os.path.join(parsed_args.templates,
|
||||
'tools/process-templates.py')
|
||||
args = ['python', process_templates, '--roles-data',
|
||||
self.roles_file, '--output-dir', self.tht_render]
|
||||
parsed_args.roles_file, '--output-dir', self.tht_render]
|
||||
if utils.run_command_and_log(self.log, args, cwd=self.tht_render) != 0:
|
||||
# TODO(aschultz): improve error messaging
|
||||
msg = _("Problems generating templates.")
|
||||
@ -581,10 +550,10 @@ class Deploy(command.Command):
|
||||
|
||||
# Include any environments from the plan-environment.yaml
|
||||
plan_env_path = utils.rel_or_abs_path(
|
||||
self.tht_render, parsed_args.plan_environment_file)
|
||||
parsed_args.plan_environment_file, self.tht_render)
|
||||
with open(plan_env_path, 'r') as f:
|
||||
plan_env_data = yaml.safe_load(f)
|
||||
environments = [utils.rel_or_abs_path(self.tht_render, e.get('path'))
|
||||
environments = [utils.rel_or_abs_path(e.get('path'), self.tht_render)
|
||||
for e in plan_env_data.get('environments', {})]
|
||||
|
||||
# this will allow the user to overwrite passwords with custom envs
|
||||
@ -626,7 +595,7 @@ class Deploy(command.Command):
|
||||
tmp_env.update(self._generate_portmap_parameters(
|
||||
ip, ip_nw, c_ip, p_ip,
|
||||
stack_name=parsed_args.stack,
|
||||
role_name=self._get_primary_role_name()))
|
||||
role_name=self._get_primary_role_name(parsed_args)))
|
||||
|
||||
with open(maps_file, 'w') as env_file:
|
||||
yaml.safe_dump({'parameter_defaults': tmp_env}, env_file,
|
||||
@ -653,8 +622,9 @@ class Deploy(command.Command):
|
||||
|
||||
return environments + user_environments
|
||||
|
||||
def _prepare_container_images(self, env):
|
||||
roles_data = self._get_roles_data()
|
||||
def _prepare_container_images(self, env, parsed_args):
|
||||
roles_data = utils.fetch_roles_file(parsed_args.roles_file,
|
||||
parsed_args.templates)
|
||||
image_params = kolla_builder.container_images_prepare_multi(
|
||||
env, roles_data, dry_run=True)
|
||||
|
||||
@ -678,7 +648,7 @@ class Deploy(command.Command):
|
||||
environments, self.tht_render, parsed_args.templates,
|
||||
cleanup=parsed_args.cleanup)
|
||||
|
||||
self._prepare_container_images(env)
|
||||
self._prepare_container_images(env, parsed_args)
|
||||
|
||||
self.log.debug(_("Getting template contents"))
|
||||
template_path = os.path.join(self.tht_render, 'overcloud.yaml')
|
||||
@ -805,8 +775,11 @@ class Deploy(command.Command):
|
||||
)
|
||||
parser.add_argument(
|
||||
'--roles-file', '-r', dest='roles_file',
|
||||
help=_('Roles file, overrides the default %s in the --templates '
|
||||
'directory') % constants.UNDERCLOUD_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.UNDERCLOUD_ROLES_FILE,
|
||||
default=constants.UNDERCLOUD_ROLES_FILE
|
||||
)
|
||||
parser.add_argument(
|
||||
@ -1038,10 +1011,6 @@ class Deploy(command.Command):
|
||||
# Set default plan if not specified by user
|
||||
self._set_default_plan()
|
||||
|
||||
# configure our roles data
|
||||
self._set_roles_file(parsed_args.roles_file, self.tht_render)
|
||||
self._get_roles_data()
|
||||
|
||||
rc = 1
|
||||
try:
|
||||
# NOTE(bogdando): Look for the unique virtual update mark matching
|
||||
|
@ -382,7 +382,9 @@ def _validate_passwords_file():
|
||||
def _validate_env_files_paths():
|
||||
"""Verify the non-matching templates path vs env files paths"""
|
||||
tht_path = CONF.get('templates') or constants.TRIPLEO_HEAT_TEMPLATES
|
||||
roles_file = CONF.get('roles_file') or constants.UNDERCLOUD_ROLES_FILE
|
||||
roles_file = utils.rel_or_abs_path(
|
||||
CONF.get('roles_file') or constants.UNDERCLOUD_ROLES_FILE,
|
||||
tht_path)
|
||||
|
||||
# get the list of jinja templates normally rendered for UC installations
|
||||
LOG.debug(_("Using roles file {0} from {1}").format(roles_file, tht_path))
|
||||
|
@ -20,6 +20,7 @@ from tripleo_common.utils import tarball
|
||||
|
||||
from tripleoclient import constants
|
||||
from tripleoclient import exceptions
|
||||
from tripleoclient import utils
|
||||
from tripleoclient.workflows import base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -42,7 +43,8 @@ def _upload_templates(swift_client, container_name, tht_root, roles_file=None,
|
||||
# Optional override of the roles_data.yaml file
|
||||
if roles_file:
|
||||
_upload_file(swift_client, container_name,
|
||||
constants.OVERCLOUD_ROLES_FILE, roles_file)
|
||||
constants.OVERCLOUD_ROLES_FILE,
|
||||
utils.rel_or_abs_path(roles_file, tht_root))
|
||||
|
||||
# Optional override of the network_data.yaml file
|
||||
if networks_file:
|
||||
@ -157,8 +159,9 @@ def create_plan_from_templates(clients, name, tht_root, roles_file=None,
|
||||
"Unable to create plan. {}".format(result))
|
||||
|
||||
print("Creating plan from template files in: {}".format(tht_root))
|
||||
_upload_templates(swift_client, name, tht_root, roles_file, plan_env_file,
|
||||
networks_file)
|
||||
_upload_templates(swift_client, name, tht_root,
|
||||
utils.rel_or_abs_path(roles_file, tht_root),
|
||||
plan_env_file, networks_file)
|
||||
|
||||
try:
|
||||
create_deployment_plan(clients, container=name,
|
||||
@ -174,6 +177,7 @@ def update_plan_from_templates(clients, name, tht_root, roles_file=None,
|
||||
swift_client = clients.tripleoclient.object_store
|
||||
passwords = None
|
||||
keep_file_contents = {}
|
||||
roles_file = utils.rel_or_abs_path(roles_file, tht_root)
|
||||
|
||||
if keep_env:
|
||||
# Dict items are (remote_name, local_name). local_name may be
|
||||
|
Loading…
Reference in New Issue
Block a user