diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 41033bd19de..22a3bbfcbba 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -23,12 +23,6 @@ import yaml import copy import optparse import operator -from ansible import errors -from ansible import __version__ -from ansible.utils.plugins import * -from ansible.utils import template -from ansible.callbacks import display -import ansible.constants as C import time import StringIO import stat @@ -43,6 +37,15 @@ import getpass import sys import textwrap +# ansible +from ansible import errors +from ansible import __version__ +from ansible.utils.plugins import * +from ansible.utils import template +from ansible.callbacks import display +import ansible.constants as C +import filesystem + VERBOSITY=0 # list of all deprecation messages to prevent duplicate display @@ -224,7 +227,7 @@ def unfrackpath(path): example: '$HOME/../../var/mail' becomes '/var/spool/mail' ''' - return os.path.normpath(os.path.realpath(os.path.expandvars(os.path.expanduser(path)))) + return filesystem.unfrackpath(path) def prepare_writeable_dir(tree,mode=0777): ''' make sure a directory exists and is writeable ''' @@ -250,33 +253,11 @@ def path_dwim(basedir, given): ''' make relative paths work like folks expect. ''' - - if given.startswith("/"): - return os.path.abspath(given) - elif given.startswith("~"): - return os.path.abspath(os.path.expanduser(given)) - else: - return os.path.abspath(os.path.join(basedir, given)) + return filesystem.path_dwim(basedir, given) def path_dwim_relative(original, dirname, source, playbook_base, check=True): ''' find one file in a directory one level up in a dir named dirname relative to current ''' - # (used by roles code) - - basedir = os.path.dirname(original) - if os.path.islink(basedir): - basedir = unfrackpath(basedir) - template2 = os.path.join(basedir, dirname, source) - else: - template2 = os.path.join(basedir, '..', dirname, source) - source2 = path_dwim(basedir, template2) - if os.path.exists(source2): - return source2 - obvious_local_path = path_dwim(playbook_base, source) - if os.path.exists(obvious_local_path): - return obvious_local_path - if check: - raise errors.AnsibleError("input file not found at %s or %s" % (source2, obvious_local_path)) - return source2 # which does not exist + return filesystem.path_dwim_relative(original, dirname, source, playbook_base, check=True) def json_loads(data): ''' parse a JSON string and return a data structure ''' diff --git a/lib/ansible/utils/filesystem.py b/lib/ansible/utils/filesystem.py new file mode 100644 index 00000000000..db83c546cfc --- /dev/null +++ b/lib/ansible/utils/filesystem.py @@ -0,0 +1,64 @@ +# (c) 2012, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +import sys +import os +from ansible import errors +from ansible import __version__ +import ansible.constants as C + +def path_dwim(basedir, given): + ''' + make relative paths work like folks expect. + ''' + + if given.startswith("/"): + return os.path.abspath(given) + elif given.startswith("~"): + return os.path.abspath(os.path.expanduser(given)) + else: + return os.path.abspath(os.path.join(basedir, given)) + +def path_dwim_relative(original, dirname, source, playbook_base, check=True): + ''' find one file in a directory one level up in a dir named dirname relative to current ''' + # (used by roles code) + + basedir = os.path.dirname(original) + if os.path.islink(basedir): + basedir = unfrackpath(basedir) + template2 = os.path.join(basedir, dirname, source) + else: + template2 = os.path.join(basedir, '..', dirname, source) + source2 = path_dwim(basedir, template2) + if os.path.exists(source2): + return source2 + obvious_local_path = path_dwim(playbook_base, source) + if os.path.exists(obvious_local_path): + return obvious_local_path + if check: + raise errors.AnsibleError("input file not found at %s or %s" % (source2, obvious_local_path)) + return source2 # which does not exist + +def unfrackpath(path): + ''' + returns a path that is free of symlinks, environment + variables, relative path traversals and symbols (~) + example: + '$HOME/../../var/mail' becomes '/var/spool/mail' + ''' + return os.path.normpath(os.path.realpath(os.path.expandvars(os.path.expanduser(path)))) + diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py index b83650738f1..8ca285c7933 100644 --- a/lib/ansible/utils/template.py +++ b/lib/ansible/utils/template.py @@ -27,6 +27,8 @@ import time import datetime import pwd import ast +import plugins +import filesystem FILTER_PLUGINS = None _LISTRE = re.compile(r"(\w+)\[(\d+)\]") @@ -45,10 +47,9 @@ def _get_filters(): if Globals.FILTERS is not None: return Globals.FILTERS - from ansible import utils - plugins = [ x for x in utils.plugins.filter_loader.all()] + my_plugins = [ x for x in plugins.filter_loader.all()] filters = {} - for fp in plugins: + for fp in my_plugins: filters.update(fp.filters()) Globals.FILTERS = filters @@ -66,8 +67,7 @@ def _get_extensions(): return jinja_exts def lookup(name, *args, **kwargs): - from ansible import utils - instance = utils.plugins.lookup_loader.get(name.lower(), basedir=kwargs.get('basedir',None)) + instance = plugins.lookup_loader.get(name.lower(), basedir=kwargs.get('basedir',None)) vars = kwargs.get('vars', None) if instance is not None: @@ -221,7 +221,6 @@ def _legacy_varFind(basedir, text, vars, lookup_fatal, depth, expand_lists): if basedir is None: return {'replacement': None, 'start': start, 'end': end} var_end -= 1 - from ansible import utils args = text[part_start:var_end] if lookup_plugin_name == 'LOOKUP': lookup_plugin_name, args = args.split(",", 1) @@ -233,7 +232,7 @@ def _legacy_varFind(basedir, text, vars, lookup_fatal, depth, expand_lists): return None - instance = utils.plugins.lookup_loader.get(lookup_plugin_name.lower(), basedir=basedir) + instance = plugins.lookup_loader.get(lookup_plugin_name.lower(), basedir=basedir) if instance is not None: try: replacement = instance.run(args, inject=vars) @@ -411,8 +410,7 @@ def template_from_file(basedir, path, vars): fail_on_undefined = C.DEFAULT_UNDEFINED_VAR_BEHAVIOR - from ansible import utils - realpath = utils.path_dwim(basedir, path) + realpath = filesystem.path_dwim(basedir, path) loader=jinja2.FileSystemLoader([basedir,os.path.dirname(realpath)]) def my_lookup(*args, **kwargs):