fix paths to actually be config file relative (#31533)

* fix paths to actually be config file relative

also allow to unfrack paths for 'not cwd'
only use -i 'localhost,' for adhoc in pull
This commit is contained in:
Brian Coca 2017-10-10 22:17:17 -04:00 committed by Toshio Kuratomi
parent dde2c96d67
commit 3886f80e44
2 changed files with 27 additions and 14 deletions

View file

@ -27,7 +27,7 @@ Setting = namedtuple('Setting', 'name value origin type')
# FIXME: see if we can unify in module_utils with similar function used by argspec # FIXME: see if we can unify in module_utils with similar function used by argspec
def ensure_type(value, value_type): def ensure_type(value, value_type, origin=None):
''' return a configuration variable with casting ''' return a configuration variable with casting
:arg value: The value to ensure correct typing of :arg value: The value to ensure correct typing of
:kwarg value_type: The type of the value. This can be any of the following strings: :kwarg value_type: The type of the value. This can be any of the following strings:
@ -44,6 +44,11 @@ def ensure_type(value, value_type):
means colon separated strings.) Split the value and then expand means colon separated strings.) Split the value and then expand
each part for environment variables and tildes. each part for environment variables and tildes.
''' '''
basedir = None
if origin and os.path.isabs(origin) and os.path.exists(origin):
basedir = origin
if value_type: if value_type:
value_type = value_type.lower() value_type = value_type.lower()
@ -66,10 +71,10 @@ def ensure_type(value, value_type):
value = None value = None
elif value_type == 'path': elif value_type == 'path':
value = resolve_path(value) value = resolve_path(value, basedir=basedir)
elif value_type in ('tmp', 'temppath', 'tmppath'): elif value_type in ('tmp', 'temppath', 'tmppath'):
value = resolve_path(value) value = resolve_path(value, basedir=basedir)
if not os.path.exists(value): if not os.path.exists(value):
makedirs_safe(value, 0o700) makedirs_safe(value, 0o700)
prefix = 'ansible-local-%s' % os.getpid() prefix = 'ansible-local-%s' % os.getpid()
@ -78,12 +83,12 @@ def ensure_type(value, value_type):
elif value_type == 'pathspec': elif value_type == 'pathspec':
if isinstance(value, string_types): if isinstance(value, string_types):
value = value.split(os.pathsep) value = value.split(os.pathsep)
value = [resolve_path(x) for x in value] value = [resolve_path(x, basedir=basedir) for x in value]
elif value_type == 'pathlist': elif value_type == 'pathlist':
if isinstance(value, string_types): if isinstance(value, string_types):
value = value.split(',') value = value.split(',')
value = [resolve_path(x) for x in value] value = [resolve_path(x, basedir=basedir) for x in value]
# defaults to string types # defaults to string types
elif isinstance(value, string_types): elif isinstance(value, string_types):
@ -93,12 +98,12 @@ def ensure_type(value, value_type):
# FIXME: see if this can live in utils/path # FIXME: see if this can live in utils/path
def resolve_path(path): def resolve_path(path, basedir=None):
''' resolve relative or 'varaible' paths ''' ''' resolve relative or 'varaible' paths '''
if '{{CWD}}' in path: # allow users to force CWD using 'magic' {{CWD}} if '{{CWD}}' in path: # allow users to force CWD using 'magic' {{CWD}}
path = path.replace('{{CWD}}', os.getcwd()) path = path.replace('{{CWD}}', os.getcwd())
return unfrackpath(path, follow=False) return unfrackpath(path, follow=False, basedir=basedir)
# FIXME: generic file type? # FIXME: generic file type?
@ -323,7 +328,7 @@ class ConfigManager(object):
# ensure correct type # ensure correct type
try: try:
value = ensure_type(value, defs[config].get('type')) value = ensure_type(value, defs[config].get('type'), origin=origin)
except Exception as e: except Exception as e:
self.UNABLE.append(config) self.UNABLE.append(config)

View file

@ -27,7 +27,7 @@ from ansible.module_utils._text import to_bytes, to_native, to_text
__all__ = ['unfrackpath', 'makedirs_safe'] __all__ = ['unfrackpath', 'makedirs_safe']
def unfrackpath(path, follow=True): def unfrackpath(path, follow=True, basedir=None):
''' '''
Returns a path that is free of symlinks (if follow=True), environment variables, relative path traversals and symbols (~) Returns a path that is free of symlinks (if follow=True), environment variables, relative path traversals and symbols (~)
@ -43,12 +43,20 @@ def unfrackpath(path, follow=True):
'$HOME/../../var/mail' becomes '/var/spool/mail' '$HOME/../../var/mail' becomes '/var/spool/mail'
''' '''
if follow: if basedir is None:
final_path = os.path.normpath(os.path.realpath(os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict'))))) basedir = os.getcwd()
else: elif os.path.isfile(basedir):
final_path = os.path.normpath(os.path.abspath(os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict'))))) basedir = os.path.dirname(basedir)
return to_text(final_path, errors='surrogate_or_strict') final_path = os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict')))
if not os.path.isabs(final_path):
final_path = os.path.join(to_bytes(basedir, errors='surrogate_or_strict'), final_path)
if follow:
final_path = os.path.realpath(final_path)
return to_text(os.path.normpath(final_path), errors='surrogate_or_strict')
def makedirs_safe(path, mode=None): def makedirs_safe(path, mode=None):