From dfad94078bede3781ece404f99c707f4967c041d Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Fri, 1 Mar 2013 17:25:25 -0500 Subject: [PATCH 1/2] first_found lookup_plugin - replaces first_available_file - useful in tasks/playbook inclusion - task-specific inclusion allows searching paths and files --- .../runner/lookup_plugins/first_found.py | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 lib/ansible/runner/lookup_plugins/first_found.py diff --git a/lib/ansible/runner/lookup_plugins/first_found.py b/lib/ansible/runner/lookup_plugins/first_found.py new file mode 100644 index 00000000000..c2a8fc9cfb6 --- /dev/null +++ b/lib/ansible/runner/lookup_plugins/first_found.py @@ -0,0 +1,121 @@ +# (c) 2013, seth vidal red hat, inc +# +# 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 . + + +# take a list of files and (optionally) a list of paths +# return the first existing file found in the paths +# [file1, file2, file3], [path1, path2, path3] +# search order is: +# path1/file1 +# path1/file2 +# path1/file3 +# path2/file1 +# path2/file2 +# path2/file3 +# path3/file1 +# path3/file2 +# path3/file3 + +# first file found with os.path.exists() is returned +# no file matches raises ansibleerror +# EXAMPLES +# - name: copy first existing file found to /some/file +# action: copy src=$item dest=/some/file +# with_first_found: +# - files: foo ${inventory_hostname} bar +# paths: /tmp/production /tmp/staging + +# that will look for files in this order: +# /tmp/production/foo +# ${inventory_hostname} +# bar +# /tmp/staging/foo +# ${inventory_hostname} +# bar + +# - name: copy first existing file found to /some/file +# action: copy src=$item dest=/some/file +# with_first_found: +# - files: /some/place/foo ${inventory_hostname} /some/place/else + +# that will look for files in this order: +# /some/place/foo +# $relative_path/${inventory_hostname} +# /some/place/else + +# example - including tasks: +# tasks: +# - include: $item +# with_first_found: +# - files: generic +# paths: tasks/staging tasks/production + +# this will include the tasks in the file generic where it is found first (staging or production) + + + + + +from ansible import utils, errors +import os + +class LookupModule(object): + + def __init__(self, basedir=None, **kwargs): + self.basedir = basedir + + def run(self, terms, **kwargs): + result = None + for term in terms: + files = term.get('files', []) + paths = term.get('paths', []) + + filelist = files + if isinstance(files, basestring): + files = files.replace(',', ' ') + files = files.replace(';', ' ') + filelist = files.split(' ') + + pathlist = paths + if paths: + if isinstance(paths, basestring): + paths = paths.replace(',', ' ') + paths = paths.replace(':', ' ') + paths = paths.replace(';', ' ') + pathlist = paths.split(' ') + + total_search = [] + + + if not pathlist: + total_search = filelist + else: + for path in pathlist: + for fn in filelist: + f = path + '/' + fn + total_search.append(f) + + + result = None + for fn in total_search: + path = utils.path_dwim(self.basedir, fn) + if os.path.exists(path): + return [path] + + + if not result: + raise errors.AnsibleError("no match found: %s, %s" % (pathlist, filelist)) From 804b1302887881a92a2a6b0a7b8f32218b4aca47 Mon Sep 17 00:00:00 2001 From: Seth Vidal Date: Fri, 1 Mar 2013 18:18:56 -0500 Subject: [PATCH 2/2] check if the term is a dict so we can take a simple list of files (like first_available_file) takes --- .../runner/lookup_plugins/first_found.py | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/lib/ansible/runner/lookup_plugins/first_found.py b/lib/ansible/runner/lookup_plugins/first_found.py index c2a8fc9cfb6..09f6cc27f10 100644 --- a/lib/ansible/runner/lookup_plugins/first_found.py +++ b/lib/ansible/runner/lookup_plugins/first_found.py @@ -81,34 +81,36 @@ class LookupModule(object): def run(self, terms, **kwargs): result = None for term in terms: - files = term.get('files', []) - paths = term.get('paths', []) - - filelist = files - if isinstance(files, basestring): - files = files.replace(',', ' ') - files = files.replace(';', ' ') - filelist = files.split(' ') - - pathlist = paths - if paths: - if isinstance(paths, basestring): - paths = paths.replace(',', ' ') - paths = paths.replace(':', ' ') - paths = paths.replace(';', ' ') - pathlist = paths.split(' ') - - total_search = [] - - - if not pathlist: - total_search = filelist + if isinstance(term, dict): + files = term.get('files', []) + paths = term.get('paths', []) + + filelist = files + if isinstance(files, basestring): + files = files.replace(',', ' ') + files = files.replace(';', ' ') + filelist = files.split(' ') + + pathlist = paths + if paths: + if isinstance(paths, basestring): + paths = paths.replace(',', ' ') + paths = paths.replace(':', ' ') + paths = paths.replace(';', ' ') + pathlist = paths.split(' ') + + total_search = [] + + + if not pathlist: + total_search = filelist + else: + for path in pathlist: + for fn in filelist: + f = path + '/' + fn + total_search.append(f) else: - for path in pathlist: - for fn in filelist: - f = path + '/' + fn - total_search.append(f) - + total_search = [term] result = None for fn in total_search: