Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed lookup search path #16630

Merged
merged 7 commits into from Jul 13, 2016
Merged

fixed lookup search path #16630

merged 7 commits into from Jul 13, 2016

Conversation

bcoca
Copy link
Member

@bcoca bcoca commented Jul 7, 2016

ISSUE TYPE
  • Bugfix Pull Request
ANSIBLE VERSION
2.2
SUMMARY

added ansible_search_path var that contains the proper list and in order
removed roledir var which was only used by first_found, rest used role_path
added needle function for lookups that mirrors the action plugin one, now
both types of plugins use same pathing.

Also fixes first_found in particular, to be 'aware' of task subdir requirements, this info is now available to all with_<lookup>.

fixes #16630

@bcoca bcoca added this to the 2.2.0 milestone Jul 7, 2016
@@ -101,3 +102,19 @@ def run(self, terms, variables=None, **kwargs):
result_string = to_unicode(result_string)
"""
pass

def find_needle(self, myvars, subdir, needle):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe 'def find_file_in_expected_search_path()' or 'find_file_in_search_path()' ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And maybe a

def find_file_in_search_paths(self, myvars, subdirs, target_name):
    results = []
    for subdir in subdirs:
          try:
               result.append(self.find_file_in_search_path(myvars, subdir, target_name))
          # could use a more specific exception here. Or let find_needle/find_file_in_search_path() return results as []
         except AnsibleError:
              continue
   return results

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And/or, throw some variety of IGotTooManyAnswersException if find_file_in_search_paths end up with len(result) > 1

something like:

def find_file_in_search_paths(self, myvars, subdirs, target_name):
    results = []
    for subdir in subdirs:
          try:
               result.append(self.find_file_in_search_path(myvars, subdir, target_name))
          # could use a more specific exception here. Or let find_needle/find_file_in_search_path() return results as []
         except AnsibleError:
              continue
   if  not results:
       raise NoFilesFoundInSearchPathException(target_file=target_name, subdir=subdir)

  if len(results) > 1:
      raise TooManyFilesException(target_file=target_name, subdir=subdir, results=results)
   return results

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it cannot, as it always returns the first one found

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to rephrase, we don't care that multiple files can match, it MUST return the first one it finds, that is why search path order matters.

added ansible_search_path var that contains the proper list and in order
removed roledir var which was only used by first_found, rest used role_path
added needle function for lookups that mirrors the action plugin one, now
both types of plugins use same pathing.
@bcoca bcoca merged commit 3c39bb5 into ansible:devel Jul 13, 2016
mylookup = self._shared_loader_obj.lookup_loader.get(self._task.loop, loader=self._loader, templar=templar)

# give lookup task 'context' for subdir (mostly needed for first_found)
for subdir in ['tempalte', 'var', 'file']: #TODO: move this to constants?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template is misspelled.

jfefe referenced this pull request in debops/ansible-apt Jul 14, 2016
'with_first_found' lookup into {files,templates} directory so we must use relative path for vars/* 
(See See ansible/ansible#14454)

$ ansible --version
ansible 2.2.0
@Nosmoht
Copy link
Contributor

Nosmoht commented Jul 19, 2016

Hi,

with this change no files in role/vars are looked up anymore. I've to rename the vars directory inside each role to files. Is this expected or a bug?

s-hertel pushed a commit to s-hertel/ansible that referenced this pull request Jul 25, 2016
* fixed lookup search path

added ansible_search_path var that contains the proper list and in order
removed roledir var which was only used by first_found, rest used role_path
added needle function for lookups that mirrors the action plugin one, now
both types of plugins use same pathing.

* added missing os import

* renamed as per feedback

* fixed missing rename in first_found

* also fixed first_found

* fixed import to match new error class

* fixed getattr ref
luto pushed a commit to Uberspace/ansible that referenced this pull request Mar 15, 2017
PR ansible#16630 broke globbing in with_fileglob for globbed path components
by changing from path_dwim_relative to path_dwim_relative_stack. While
the former does something like this (for a path specification like
"/tmp/*/some.conf", see Issue ansible#17136 for an example playbook)

search = ["/tmp/*"]
for candidate in search:
    if os.path.exists(candidate):
        break
return candidate

the check inside path_dwim_relative_stack works slightly differently:

result = None
if os.path.exists("/tmp/*"):
    result = "/tmp/*"
return result

The way the loop in the former example works makes path_dwim_relative
return the last element from the 'search' list even if os.path.exists
never returned True, while path_dwim_relative_stack returns None in
the same case. This ultimately makes the fileglob plugin fail because
find_file_in_search_path returns None now.

To allow asterisks in paths again, this change breaks the search for
potential targets out of path_dwim_relative_stack. This function can
then be called from the fileglob plugin to find all potential target
directories without checking if these dirs (like "/tmp/*") actually
exist. fileglob will now apply globbing first and check for the actual
existence of the files _after_ globbing.
rupran added a commit to rupran/ansible that referenced this pull request Mar 29, 2017
PR ansible#16630 broke globbing in with_fileglob for globbed path components
by changing from path_dwim_relative to path_dwim_relative_stack. While
the former does something like this (for a path specification like
"/tmp/*/some.conf", see Issue ansible#17136 for an example playbook)

search = ["/tmp/*"]
for candidate in search:
    if os.path.exists(candidate):
        break
return candidate

the check inside path_dwim_relative_stack works slightly differently:

result = None
if os.path.exists("/tmp/*"):
    result = "/tmp/*"
return result

The way the loop in the former example works makes path_dwim_relative
return the last element from the 'search' list even if os.path.exists
never returned True, while path_dwim_relative_stack returns None in
the same case. This ultimately makes the fileglob plugin fail because
find_file_in_search_path returns None now.

To allow asterisks in paths again, this change breaks the search for
potential targets out of path_dwim_relative_stack. This function can
then be called from the fileglob plugin to find all potential target
directories without checking if these dirs (like "/tmp/*") actually
exist. fileglob will now apply globbing first and check for the actual
existence of the files _after_ globbing.

Additionally, fileglob now calls os.path.normpath() on the results of
glob.glob and eliminates duplicate results.
@ansibot ansibot added bug This issue/PR relates to a bug. and removed bugfix_pull_request labels Mar 5, 2018
@ansible ansible locked and limited conversation to collaborators Apr 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue/PR relates to a bug.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants