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:
Bogdan Dobrelya 2018-05-29 13:17:13 +02:00
parent a33b1499d7
commit 8f1caf7abf
13 changed files with 161 additions and 147 deletions

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

View File

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

View File

@ -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',

View File

@ -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',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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',

View 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

View File

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

View File

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