UC: validate paths for tht templates and env files

The --templates path must match the -e path, e.g:

openstack overcloud upgrade prepare \
  --templates ~/tripleo-heat-templates
  -e ~/tripleo-heat-templates/*.yaml

Though, there are totally valid cases when --templates is
mixed with auto generated -e files residing in either temp
dirs or the user's home dir. For example, heat undercloud
installer generates such files. So we can not blindly
prohibit non matching --templates and -e's.

To adress that UX issue, add additional contstraints for
undercloud tht env files validation:

* "-e" files can not refer external files normally
  processed from jinja2 in t-h-t. Those must come from
  the templates path only.

NOTE: the similar change for overcloud should be done
in follow-ups.

Partial-bug: #1762403

Depends-On: I10d4dffcd3802f62fc824c808728c0b5b4f1002c
Change-Id: Ia9c62c787d6c581a66b2fde030a60499cfa18b82
Signed-off-by: Bogdan Dobrelya <bdobreli@redhat.com>
Bogdan Dobrelya 5 years ago committed by Emilien Macchi
parent 4020387ff0
commit 038ed01058
  1. 52

@ -20,6 +20,8 @@ import os
import subprocess
import sys
from osc_lib.i18n import _
from oslo_utils import netutils
import psutil
@ -63,18 +65,21 @@ def _run_command(args, env=None, name=None):
raise RuntimeError(message)
def _run_live_command(args, env=None, name=None):
"""Run the command defined by args and log its output
def _run_live_command(args, env=None, name=None, cwd=None, wait=True):
"""Run the command defined by args, env and cwd
Takes the same arguments as _run_command, but runs the process
Either returns the process handler or runs the process
asynchronously so the output can be logged while the process is still
if name is None:
name = args[0]
process = subprocess.Popen(args, env=env,
process = subprocess.Popen(args, env=env, cwd=cwd,
if not wait:
return process
while True:
line = process.stdout.readline().decode('utf-8')
if line:
@ -372,6 +377,42 @@ def _validate_passwords_file():
raise FailedValidation(message)
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
# get the list of jinja templates normally rendered for UC installations
LOG.debug("Using roles file %s from %s" % (roles_file, tht_path))
process_templates = os.path.join(tht_path,
p = _run_live_command(
['python', process_templates, '--roles-data', roles_file, '--dry-run'],
name='process-templates-dry-run', cwd=tht_path, wait=False)
# parse the list for the rendered from j2 file names
result = p.communicate()[0]
j2_files_list = []
for line in result.split("\n"):
if ((line.startswith('dry run') or line.startswith('jinja2')) and
bname = os.path.basename(line.split(' ')[-1])
if line.startswith('dry run'):
if line.startswith('jinja2'):
j2_files_list.append(bname.replace('.j2', ''))
for env_file in CONF['custom_env_files']:
env_file_abs = os.path.abspath(env_file)
if (os.path.dirname(env_file_abs) != os.path.abspath(tht_path) and
os.path.basename(env_file) in j2_files_list):
msg = _(
'Heat environment external to the templates dir '
'can not reference j2 processed file %s') % env_file_abs
raise FailedValidation(msg)
def _run_yum_clean_all(instack_env):
args = ['sudo', 'yum', 'clean', 'all']
LOG.info('Running yum clean all')
@ -395,6 +436,9 @@ def check():
# Heat templates validations
if CONF.get('custom_env_files'):
# Networking validations
for subnet in CONF.subnets: