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

FreeBSD portinstall module resubmit #3390

Closed
wants to merge 75 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
bdf72f9
Module to install software on FreeBSD using portinstall
berenddeboer Jun 24, 2013
602d643
Updated written by section.
berenddeboer Jun 24, 2013
f5ee9fd
Very dirty hack to improve check if mysql55-client is installed.
berenddeboer Jun 24, 2013
9f9d301
Delete now works.
berenddeboer Jun 24, 2013
4263be0
Python likes to compare integers with integers.
berenddeboer Jun 24, 2013
701d37c
Always removing digits doesn't really work well.
berenddeboer Jun 25, 2013
10b7246
Merge remote-tracking branch 'upstream/devel' into devel
berenddeboer Jun 25, 2013
e257984
Merge remote-tracking branch 'upstream/devel' into devel
berenddeboer Jun 27, 2013
df9ace7
Enable negated patterns
madduck Jun 20, 2013
f26ab19
Remove shebang line
madduck Jun 14, 2013
c302543
Replace external command with shell construct
madduck Jun 14, 2013
d44f50a
added force parameter to symlink invocation, in order to force the cr…
rhaido May 30, 2013
ac73a78
added possibility to force symlinks to none-existent destination (whi…
rhaido May 30, 2013
ffc1166
Updated documentaion for the file module
rhaido Jun 4, 2013
b43e069
Fixed typo
rhaido Jun 12, 2013
28fc030
Reference major_release, not major_version
jlaska Jun 20, 2013
245fcaa
Add submodule support to git module
sfromm Jun 20, 2013
ce3d48a
Adds termination support to the ec2 module
Jun 21, 2013
82aa690
Added flexible filename handling for main files
ninetythirty Jun 21, 2013
66acc37
Add linode cloud provider.
zbal Jun 21, 2013
dd13a55
Update documentation
zbal Jun 21, 2013
1976abd
Fix last bugs, complete all tests.
zbal Jun 21, 2013
c21890f
Consistent wait_timeout between doc and module
zbal Jun 21, 2013
f2901a3
Don't turn on sudo for all tasks when setting the sudo_user or ask_su…
markmandel Jun 21, 2013
751d920
Improve error messages on missing required variables.
zbal Jun 21, 2013
7b7db72
using instance_ids and state=absent for removing instances
Jun 21, 2013
72ec892
typo
Jun 21, 2013
55bb168
Let update-rc.d set changed flag properly
madduck Jun 22, 2013
7d6cf2a
expanduser on each component of plug-in paths
dsedivec Jun 20, 2013
e885ef9
Expand usage of Python 2.6 if statement
madduck Jun 23, 2013
e9edb30
Add htpasswd module
Jun 24, 2013
645e49a
add more support for different size formats
srgvg Jun 24, 2013
81ea18a
Add GPL header and copyright
Jun 25, 2013
5a57568
Better error for fireball + sudo mode.
arturaz Jun 25, 2013
a590998
get file/path facts via 'stat'
brucep-care Jun 25, 2013
f43aaea
Fixed stat of symlinked dirs
brucep-care Jun 25, 2013
6e67bc9
added a provision for passing a server password to IRC
Jun 26, 2013
14bc4eb
don't fail if the file doesn't exist. Just set 'exists' to true/fals…
brucep-care Jun 26, 2013
3720926
Updates to Ansible command options
jlund Jun 27, 2013
e707b52
initial arista module import
privateip Jun 27, 2013
0a5d7e1
Add DigitalOcean inventory plugin
neomantra Jun 27, 2013
47ddf77
Include identity_type required by Pyrax 1.4
Jun 27, 2013
abac7fa
digital_ocean: add --env to inventory script
neomantra Jun 27, 2013
42e223e
Elapsed time should account for the delay
Jun 28, 2013
af451a0
add description about host parameters in a inventory file.
shirou Jun 28, 2013
fb5eb05
Add doc example of attaching tags to a role
Jun 28, 2013
56b8aa2
Added linode plugin
danslimmon Jun 28, 2013
89f96c3
Added notes about hostname resolution.
danslimmon Jun 28, 2013
afdf463
Add a mandatory jinja2 filter for use in templates.
jhoekx Jun 29, 2013
e4299e1
Fix the issue of easy_install ignoring virtualenv_site_packages=yes.
Jun 29, 2013
eaa6ae5
moved modules to net_infrastructure
privateip Jun 29, 2013
0527583
Remove redundant call to _get_path() in PluginLoader.find_plugin()
stoned Jun 30, 2013
8d22d7b
Fixed bug in module_fail. Consistent error handling. Adding comments.…
Jun 28, 2013
1350611
Slight message tweak.
Jun 30, 2013
9e532de
Some minor doc tweaks
Jun 30, 2013
15c10d4
update changelog
Jun 30, 2013
f17908b
Semicolons must die
Jun 30, 2013
745e0e5
Styling: indentation
Jun 30, 2013
85242f6
Styling: misc pep8
Jun 30, 2013
9cd3e09
Styling: spacing
Jun 30, 2013
c45bdf0
Styling: indentation
Jun 30, 2013
c0aa90a
pep8: deprecation
Jun 30, 2013
82d565c
Styling: deprecation
Jun 30, 2013
065d00a
Styling: blank lines
Jun 30, 2013
ea0ecea
Styling: trailing spaces
Jun 30, 2013
51acdbf
Styling: semicolon
Jun 30, 2013
1dc635f
Styling: indentation
Jun 30, 2013
d00d07e
Styling: misc pep8
Jun 30, 2013
567ade8
Styling: deprecation
Jun 30, 2013
dab0d33
Styling: deprecation
Jun 30, 2013
97969a4
Styling: semicolon
Jun 30, 2013
9948685
Fixup documentation YAML
Jun 30, 2013
c42dd1c
Fix RST formatting in documentation (underline too short)
Jun 30, 2013
8f72fe5
Changelog update.
Jun 30, 2013
c668410
Changelog updates
Jun 30, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 24 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ Major new features:
New modules:

* notifications: datadog_event -- send data to datadog
* cloud: digital_ocean -- module for digital ocean provisioning
* cloud: digital_ocean -- module for digital ocean provisioning, also includes inventory module
* cloud: rds -- Amazon relational database service
* cloud: linode -- also included, an inventory module
* net_infrastructure: arista_
* system: stat -- reports on stat(istics) of remote files, for use with 'register'
* htpasswd -- manipulate htpasswd files

Misc changes:

Expand All @@ -38,6 +42,25 @@ Misc changes:
* fixes for device facts with multiple PCI domains
* added "with_inventory_hostnames" lookup plugin, which can take a pattern and loop over hostnames matching the pattern and is great for use with delegate_to and so on.
* ec2 module supports adding to multiple security groups
* cloudformation module fix down the error path, removed 'wait_for' parameter
* added --only-if-changed to ansible-pull, which runs only if the repo has changes (not default)
* added 'mandatory', a Jinja2 filter that checks if a variable is defined: {{ foo|mandatory }}
* added support for multiple size formats to the lvol module
* timing reporting on wait_for module now includes the delay time
* IRC module can now send a server password
* "~" now expanded on each component of configured plugin paths
* fix for easy_install module when dealing with virtualenv
* rackspace module now explicitly indicates rackspace vs vanilla openstack
* add_host module does not report changed=True any longer
* explanatory error message when using fireball with sudo message has been improved
* git module now automatically pulls down git submodules
* negated patterns don't require "all:!foo", you can just say "!foo" now to select all not foos.
* fix for Debian services always reporting changed when toggling enablement bit
* roles files now tolerate files named 'main.yaml' and 'main' in addition to main.yaml
* some help cleanup to command line flags on scripts
* force option reinstated for file module, can create symlinks to non-existant files, etc
* added termination support to ec2 module
* --ask-sudo-pass or --sudo-user does not enable all options to use sudo in ansible-playbook

1.2 "Right Now" -- June 10, 2013

Expand Down
2 changes: 0 additions & 2 deletions bin/ansible
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ class Cli(object):
parser.add_option('-m', '--module-name', dest='module_name',
help="module name to execute (default=%s)" % C.DEFAULT_MODULE_NAME,
default=C.DEFAULT_MODULE_NAME)
parser.add_option('--list-hosts', dest='listhosts', action='store_true',
help="dump out a list of hosts matching input pattern, does not execute any modules!")

options, args = parser.parse_args()
self.callbacks.options = options
Expand Down
14 changes: 4 additions & 10 deletions bin/ansible-playbook
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ def main(args):
''' run ansible-playbook operations '''

# create parser for CLI options
usage = "%prog playbook.yml"
parser = utils.base_parser(
constants=C,
usage=usage,
usage = "%prog playbook.yml",
connect_opts=True,
runas_opts=True,
subset_opts=True,
Expand All @@ -66,17 +65,14 @@ def main(args):
help="set additional key=value variables from the CLI")
parser.add_option('-t', '--tags', dest='tags', default='all',
help="only run plays and tasks tagged with these values")
# FIXME: list hosts is a common option and can be moved to utils/__init__.py
parser.add_option('--list-hosts', dest='listhosts', action='store_true',
help="dump out a list of hosts, each play will run against, does not run playbook!")
parser.add_option('--syntax-check', dest='syntax', action='store_true',
help="do a playbook syntax check on the playbook, do not execute the playbook")
help="perform a syntax check on the playbook, but do not execute it")
parser.add_option('--list-tasks', dest='listtasks', action='store_true',
help="do list all tasks that would be executed")
help="list all tasks that would be executed")
parser.add_option('--step', dest='step', action='store_true',
help="one-step-at-a-time: confirm each task before running")
parser.add_option('--start-at-task', dest='start_at',
help="start the playbook with a task matching this name")
help="start the playbook at the task matching this name")

options, args = parser.parse_args(args)

Expand All @@ -95,8 +91,6 @@ def main(args):
options.ask_pass = options.ask_pass or C.DEFAULT_ASK_PASS
options.ask_sudo_pass = options.ask_sudo_pass or C.DEFAULT_ASK_SUDO_PASS
( sshpass, sudopass ) = utils.ask_passwords(ask_pass=options.ask_pass, ask_sudo_pass=options.ask_sudo_pass)
if options.sudo_user or options.ask_sudo_pass:
options.sudo = True
options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
if options.extra_vars and options.extra_vars[0] in '[{':
extra_vars = utils.json_loads(options.extra_vars)
Expand Down
10 changes: 5 additions & 5 deletions bin/ansible-pull
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ def main(args):
usage = "%prog [options] [playbook.yml]"
parser = OptionParser(usage=usage)
parser.add_option('--purge', default=False, action='store_true',
help='Purge git checkout after playbook run')
help='purge git checkout after playbook run')
parser.add_option('-d', '--directory', dest='dest', default=None,
help='Directory to clone git repository to')
help='directory to clone the git repository to')
parser.add_option('-U', '--url', dest='url', default=None,
help='URL of git repository')
help='URL of the git repository')
parser.add_option('-C', '--checkout', dest='checkout',
default="HEAD",
help='Branch/Tag/Commit to checkout. Defaults to HEAD.')
help='branch/tag/commit to checkout; defaults to HEAD')
parser.add_option('-i', '--inventory-file', dest='inventory',
help="specify inventory host file")
help="location of the inventory host file")
options, args = parser.parse_args(args)

if not options.dest:
Expand Down
36 changes: 36 additions & 0 deletions docsite/latest/rst/patterns.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,42 @@ In 1.1 and later, you can also select the connection type and user on a per host
All of these variables can of course also be set outside of the inventory file, in 'host_vars' if you wish
to keep your inventory file simple.

List of Reserved Inventory Parameters
+++++++++++++++++++++++++++++++++++++

As a summary, you can set these parameters as host inventory variables. (Some we have already
mentioned).

ansible_ssh_host
The name of the host to connect to, if different from the alias you wish to give to it.
ansible_ssh_port
The ssh port number, if not 22
ansible_ssh_user
The default ssh user name to use.
ansible_ssh_pass
The ssh password to use (this is insecure, we strongly recommend using --ask-pass or SSH keys)
ansible_connection
Connection type of the host. Candidates are local, ssh or paramiko. Default is paramiko
ansible_ssh_private_key_file
Private key file used by ssh. Useful if using multiple keys and you don't want to use SSH agent.
ansible_syslog_facility
The syslog facility to log to.
ansible_python_interpreter
The target host python path. This is userful for systems with more
than one Python or not located at "/usr/bin/python" such as \*BSD, or where /usr/bin/python
is not a 2.X series Python.
ansible\_\*\_interpreter
Works for anything such as ruby or perl and works just like ansible_python_interpreter.
This replaces shebang of modules which will run on that host.

Examples from a host file::

some_host ansible_ssh_port=2222 ansible_ssh_user=manager
aws_host ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host ansible_python_interpreter=/usr/local/bin/python
ruby_module_host ansible_ruby_interpreter=/usr/bin/ruby.1.9.3


Selecting Targets
+++++++++++++++++

Expand Down
8 changes: 8 additions & 0 deletions docsite/latest/rst/playbooks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,14 @@ While it's probably not something you should do often, you can also conditionall
This works by applying the conditional to every task in the role. Conditionals are covered later on in
the documentation.

Finally, you may wish to assign tags to the roles you specify. You can do so inline:::

---
- hosts: webservers
roles:
- { role: foo, tags: ["bar", "baz"] }


If the play still has a 'tasks' section, those tasks are executed after roles are applied.

If you want to define certain tasks to happen before AND after roles are applied, you can do this::
Expand Down
2 changes: 1 addition & 1 deletion docsite/latest/rst/playbooks2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ Tip: Sometimes you'll get back a variable that's a string and you'll want to do

tasks:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_os_family == "RedHat" and ansible_lsb.major_version|int >= 6
when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

Variables defined in the playbooks or inventory can also be used.

Expand Down
3 changes: 1 addition & 2 deletions hacking/env-setup
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/bin/bash
# usage: source env-setup [-q]
# source hacking/env-setup [-q]
# . ./env-setup [-q]
Expand All @@ -15,7 +14,7 @@ esac
# The below is an alternative to readlink -fn which doesn't exist on OS X
# Source: http://stackoverflow.com/a/1678636
FULL_PATH=`python -c "import os; print(os.path.realpath('$HACKING_DIR'))"`
ANSIBLE_HOME=`dirname "$FULL_PATH"`
ANSIBLE_HOME=${FULL_PATH%/*}

PREFIX_PYTHONPATH="$ANSIBLE_HOME/lib"
PREFIX_PATH="$ANSIBLE_HOME/bin"
Expand Down
14 changes: 7 additions & 7 deletions lib/ansible/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def shell_expand_path(path):

# configurable things
DEFAULT_HOST_LIST = shell_expand_path(get_config(p, DEFAULTS, 'hostfile', 'ANSIBLE_HOSTS', '/etc/ansible/hosts'))
DEFAULT_MODULE_PATH = shell_expand_path(get_config(p, DEFAULTS, 'library', 'ANSIBLE_LIBRARY', DIST_MODULE_PATH))
DEFAULT_MODULE_PATH = get_config(p, DEFAULTS, 'library', 'ANSIBLE_LIBRARY', DIST_MODULE_PATH)
DEFAULT_REMOTE_TMP = shell_expand_path(get_config(p, DEFAULTS, 'remote_tmp', 'ANSIBLE_REMOTE_TEMP', '$HOME/.ansible/tmp'))
DEFAULT_MODULE_NAME = get_config(p, DEFAULTS, 'module_name', None, 'command')
DEFAULT_PATTERN = get_config(p, DEFAULTS, 'pattern', None, '*')
Expand All @@ -98,12 +98,12 @@ def shell_expand_path(path):
DEFAULT_JINJA2_EXTENSIONS = get_config(p, DEFAULTS, 'jinja2_extensions', 'ANSIBLE_JINJA2_EXTENSIONS', None)
DEFAULT_EXECUTABLE = get_config(p, DEFAULTS, 'executable', 'ANSIBLE_EXECUTABLE', '/bin/sh')

DEFAULT_ACTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'action_plugins', 'ANSIBLE_ACTION_PLUGINS', '/usr/share/ansible_plugins/action_plugins'))
DEFAULT_CALLBACK_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'callback_plugins', 'ANSIBLE_CALLBACK_PLUGINS', '/usr/share/ansible_plugins/callback_plugins'))
DEFAULT_CONNECTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'connection_plugins', 'ANSIBLE_CONNECTION_PLUGINS', '/usr/share/ansible_plugins/connection_plugins'))
DEFAULT_LOOKUP_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'lookup_plugins', 'ANSIBLE_LOOKUP_PLUGINS', '/usr/share/ansible_plugins/lookup_plugins'))
DEFAULT_VARS_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'vars_plugins', 'ANSIBLE_VARS_PLUGINS', '/usr/share/ansible_plugins/vars_plugins'))
DEFAULT_FILTER_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'filter_plugins', 'ANSIBLE_FILTER_PLUGINS', '/usr/share/ansible_plugins/filter_plugins'))
DEFAULT_ACTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'action_plugins', 'ANSIBLE_ACTION_PLUGINS', '/usr/share/ansible_plugins/action_plugins')
DEFAULT_CALLBACK_PLUGIN_PATH = get_config(p, DEFAULTS, 'callback_plugins', 'ANSIBLE_CALLBACK_PLUGINS', '/usr/share/ansible_plugins/callback_plugins')
DEFAULT_CONNECTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'connection_plugins', 'ANSIBLE_CONNECTION_PLUGINS', '/usr/share/ansible_plugins/connection_plugins')
DEFAULT_LOOKUP_PLUGIN_PATH = get_config(p, DEFAULTS, 'lookup_plugins', 'ANSIBLE_LOOKUP_PLUGINS', '/usr/share/ansible_plugins/lookup_plugins')
DEFAULT_VARS_PLUGIN_PATH = get_config(p, DEFAULTS, 'vars_plugins', 'ANSIBLE_VARS_PLUGINS', '/usr/share/ansible_plugins/vars_plugins')
DEFAULT_FILTER_PLUGIN_PATH = get_config(p, DEFAULTS, 'filter_plugins', 'ANSIBLE_FILTER_PLUGINS', '/usr/share/ansible_plugins/filter_plugins')
DEFAULT_LOG_PATH = shell_expand_path(get_config(p, DEFAULTS, 'log_path', 'ANSIBLE_LOG_PATH', ''))

ANSIBLE_NOCOWS = get_config(p, DEFAULTS, 'nocows', 'ANSIBLE_NOCOWS', None)
Expand Down
5 changes: 5 additions & 0 deletions lib/ansible/inventory/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ def _get_hosts(self, patterns):
finds hosts that match a list of patterns. Handles negative
matches as well as intersection matches.
"""
try:
if patterns[0].startswith("!"):
patterns.insert(0, "all")
except IndexError:
pass

hosts = set()
for p in patterns:
Expand Down
27 changes: 24 additions & 3 deletions lib/ansible/playbook/play.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,12 @@ def _load_roles(self, roles, ds):
path = path2
elif not os.path.isdir(path):
raise errors.AnsibleError("cannot find role in %s" % (path))
task = utils.path_dwim(self.basedir, os.path.join(path, 'tasks', 'main.yml'))
handler = utils.path_dwim(self.basedir, os.path.join(path, 'handlers', 'main.yml'))
vars_file = utils.path_dwim(self.basedir, os.path.join(path, 'vars', 'main.yml'))
task_basepath = utils.path_dwim(self.basedir, os.path.join(path, 'tasks'))
handler_basepath = utils.path_dwim(self.basedir, os.path.join(path, 'handlers'))
vars_basepath = utils.path_dwim(self.basedir, os.path.join(path, 'vars'))
task = self._resolve_main(task_basepath)
handler = self._resolve_main(handler_basepath)
vars_file = self._resolve_main(vars_basepath)
library = utils.path_dwim(self.basedir, os.path.join(path, 'library'))
if not os.path.isfile(task) and not os.path.isfile(handler) and not os.path.isfile(vars_file) and not os.path.isdir(library):
raise errors.AnsibleError("found role at %s, but cannot find %s or %s or %s or %s" % (path, task, handler, vars_file, library))
Expand Down Expand Up @@ -226,6 +229,24 @@ def _load_roles(self, roles, ds):

# *************************************************

def _resolve_main(self, basepath):
''' flexibly handle variations in main filenames '''
# these filenames are acceptable:
mains = (
os.path.join(basepath, 'main'),
os.path.join(basepath, 'main.yml'),
os.path.join(basepath, 'main.yaml'),
)
if sum([os.path.isfile(x) for x in mains]) > 1:
raise errors.AnsibleError("found multiple main files at %s, only one allowed" % (basepath))
else:
for m in mains:
if os.path.isfile(m):
return m # exactly one main file
return mains[0] # zero mains (we still need to return something)

# *************************************************

def _load_tasks(self, tasks, vars={}, additional_conditions=[], original_file=None):
''' handle task and handler include statements '''

Expand Down
6 changes: 5 additions & 1 deletion lib/ansible/runner/connection_plugins/fireball.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ def exec_command(self, cmd, tmp_path, sudo_user, sudoable=False, executable='/bi
vvv("EXEC COMMAND %s" % cmd)

if self.runner.sudo and sudoable:
raise errors.AnsibleError("fireball does not use sudo, but runs as whoever it was initiated as. (That itself is where to use sudo).")
raise errors.AnsibleError(
"When using fireball, do not specify sudo to run your tasks. " +
"Instead sudo the fireball action with sudo. " +
"Task will communicate with the fireball already running in sudo mode."
)

data = dict(
mode='command',
Expand Down
14 changes: 11 additions & 3 deletions lib/ansible/runner/filter_plugins/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,23 @@ def to_nice_json(*a, **kw):
def failed(*a, **kw):
item = a[0]
if type(item) != dict:
raise errors.AnsibleError("|failed expects a dictionary")
raise errors.AnsibleError("|failed expects a dictionary")
rc = item.get('rc',0)
failed = item.get('failed',False)
if rc != 0 or failed:
return True
return True
else:
return False
return False

def success(*a, **kw):
return not failed(*a, **kw)

def mandatory(a):
''' Make a variable mandatory '''
if not a:
raise errors.AnsibleError('Mandatory variable not defined.')
return a

class FilterModule(object):
''' Ansible core jinja2 filters '''

Expand Down Expand Up @@ -70,5 +76,7 @@ def filters(self):
'failed' : failed,
'success' : success,

# variable existence
'mandatory': mandatory,
}

6 changes: 4 additions & 2 deletions lib/ansible/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
help='use this file to authenticate the connection')
parser.add_option('-K', '--ask-sudo-pass', default=False, dest='ask_sudo_pass', action='store_true',
help='ask for sudo password')
parser.add_option('--list-hosts', dest='listhosts', action='store_true',
help='outputs a list of matching hosts; does not execute anything else')
parser.add_option('-M', '--module-path', dest='module_path',
help="specify path(s) to module library (default=%s)" % constants.DEFAULT_MODULE_PATH,
default=None)
Expand Down Expand Up @@ -510,12 +512,12 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,

if check_opts:
parser.add_option("-C", "--check", default=False, dest='check', action='store_true',
help="don't make any changes, instead try to predict some of the changes that may occur"
help="don't make any changes; instead, try to predict some of the changes that may occur"
)

if diff_opts:
parser.add_option("-D", "--diff", default=False, dest='diff', action='store_true',
help="when changing (small) files and templates, show the differences in those files, works great with --check"
help="when changing (small) files and templates, show the differences in those files; works great with --check"
)


Expand Down
3 changes: 2 additions & 1 deletion lib/ansible/utils/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.

import os
import os.path
import sys
import glob
import imp
Expand Down Expand Up @@ -108,6 +109,7 @@ def _get_paths(self):
# look in any configured plugin paths, allow one level deep for subcategories
configured_paths = self.config.split(os.pathsep)
for path in configured_paths:
path = os.path.expanduser(path)
contents = glob.glob("%s/*" % path)
for c in contents:
if os.path.isdir(c):
Expand Down Expand Up @@ -141,7 +143,6 @@ def find_plugin(self, name):
suffix = ".py"
if not self.class_name:
suffix = ""
paths = self._get_paths()

for i in self._get_paths():
path = os.path.join(i, "%s%s" % (name, suffix))
Expand Down