From 09a7119e74e82a6973625c16030bc7c778c415a1 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Tue, 13 Mar 2012 19:19:54 -0400 Subject: [PATCH] Annotate more files, fix missing imports messing with playbooks. Hey Tim, please test your stuff :) --- bin/ansible-playbook | 3 +- examples/base.yml | 19 +++++++- examples/foo.j2 | 4 ++ examples/handlers.yml | 5 ++ examples/playbook2.yml | 103 ++++++++++++++++++++++++++++++++-------- lib/ansible/playbook.py | 3 ++ lib/ansible/runner.py | 5 +- 7 files changed, 119 insertions(+), 23 deletions(-) create mode 100644 examples/foo.j2 diff --git a/bin/ansible-playbook b/bin/ansible-playbook index 6e2a65b9ef3..94ae968d83b 100755 --- a/bin/ansible-playbook +++ b/bin/ansible-playbook @@ -22,6 +22,7 @@ import sys import ansible.playbook import ansible.constants as C from ansible.utils import * +from ansible.errors import * import getpass from optparse import OptionParser @@ -99,7 +100,7 @@ def main(args): try: pb.run() except AnsibleError as e: - print e + print >>sys.stderr, "ERROR: %s" % e return 1 return 0 diff --git a/examples/base.yml b/examples/base.yml index 888613b2f29..3cdc1d00b28 100644 --- a/examples/base.yml +++ b/examples/base.yml @@ -1,7 +1,22 @@ --- + +# this is the example of an included tasks file. It contains a flat list of tasks +# they can notify other tasks, and have full access to variables from 'vars' +# or 'vars_files' directives. Further, if ohai or facter were installed on +# the remote machines, variables from those tools can be accessed on the 'action' +# line or in templates. Just prefix with 'facter_' or 'ohai_' before the particular +# variable. + +# possible uses for a included yaml file might be to represent a 'class' of a system +# like defining what makes up a webserver, or you might have a common 'base.yml' +# (like this) that might be applied to all your systems as well. + - name: no selinux action: command /usr/sbin/setenforce 0 + - name: no iptables action: service name=iptables state=stopped -- name: this is just to show variables work here, favcolor={{ favcolor }} - action: command /bin/true + +- name: made up task just to show variables work here + action: command /bin/echo release is {{ release }} + diff --git a/examples/foo.j2 b/examples/foo.j2 new file mode 100644 index 00000000000..ceaa5b2f1d1 --- /dev/null +++ b/examples/foo.j2 @@ -0,0 +1,4 @@ +# This is a very simple Jinja2 template representing an imaginary configuration file +# for an imaginary app. + +http_port={{ http_port }} diff --git a/examples/handlers.yml b/examples/handlers.yml index 44b2b3d8953..b9a25d9edea 100644 --- a/examples/handlers.yml +++ b/examples/handlers.yml @@ -1,4 +1,9 @@ --- + +# this is an example to show that handlers can be included from yaml files, +# to promote reuse between different plays or even playbooks. They work +# just like normal handlers. + - name: restart apache action: service name=httpd state=restarted - name: restart memcached diff --git a/examples/playbook2.yml b/examples/playbook2.yml index 494d1089a13..3aea97026dc 100644 --- a/examples/playbook2.yml +++ b/examples/playbook2.yml @@ -1,24 +1,89 @@ --- -- hosts: '*' +# see examples.yml first! +# This file explains some more advanced features of playbooks. +# because of the comments it's less concise than it normally is. But feel +# free to comment your playbooks if you like. + +- hosts: dbservers + + # we can define variables the normal way... + vars: - a: 2 - b: 3 - c: 4 + release: 2.0 + + # but they can also come from other files. This can be a relative + # or absolute path. This is a good way to store 'secret' variable + # files but still keep the playbook in public source control + + vars_files: + - external_vars.yml + + # as with before, every play has a list of tasks in it + tasks: - - name: copy comand - action: copy src=/srv/a dest=/srv/b - notify: - - restart apache - - name: template step - action: template src=/srv/template.j2 dest=/srv/file.out - notify: - - restart apache - - name: execute bin false - comment: call something that will fail just to demo failure counts and such - action: command /bin/false - - name: execute bin true - comment: this will never be executed because previous will fail + + # tasks can be written the normal way... + + - name: arbitrary command action: command /bin/true + + # or we can promote reuse and simplicity by including tasks + # from other files, for instance, to reuse common tasks + + - include: base.yml + + # we could also have done something like: + # - include: wordpress.yml user=timmy + # and had access to the template variable {{ user }} in the + # included file, if we wanted to. Variables from vars + # and vars_files are also available inside include files + handlers: - - name: restart apache - action: service name=httpd state=restarted + + # handlers can also be included from files, to promote reuse + # and simpler recipes, you may wish to only have one + # handler file for all your plays and playbooks + + - include: handlers.yml + + # you can mix things that are directly in the file with things + # that are included. Order is executed as written, but only + # handlers that have been notified get executed + + - name: restart foo + action: service name=foo state=restarted + +# =============================================================== + +# Here's a second play in the same playbook. This will be run +# after the first playbook completes on all hosts. You may want +# a different play for each class of systems, or may want a different +# play for each stage in a complex multi-node deployment push +# process. How you use them are up to you. + +# any play in a playbook can be executed by a user other than root +# if you want. sudo support is coming too. + +- hosts: webservers + user: mdehaan + + # vars must be specified again for the next play in the playbook + # but can be reused by including from vars_files if you want + # you can use vars, vars_files, or both. vars_files overrides + # those set in vars. + + vars: + release: 2.0 + vars_files: + - external_vars.yml + + + # these all runs as the user 'mdehaan'. If there were any handlers + # they would as well. + + tasks: + + - name: some random command + action: command /bin/true + + diff --git a/lib/ansible/playbook.py b/lib/ansible/playbook.py index aa553539f21..dc94e634f7a 100755 --- a/lib/ansible/playbook.py +++ b/lib/ansible/playbook.py @@ -20,6 +20,7 @@ import ansible.runner import ansible.constants as C from ansible.utils import * +from ansible.errors import * import yaml import shlex import os @@ -87,6 +88,8 @@ class PlayBook(object): def _get_vars(self, play, dirname): vars = play.get('vars', {}) + if type(vars) != dict: + raise AnsibleError("'vars' section must contain only key/value pairs") vars_files = play.get('vars_files', []) for f in vars_files: path = path_dwim(dirname, f) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index f0cabc30584..aea6994ef4b 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -429,7 +429,10 @@ class Runner(object): # find hosts that match the pattern hosts = self.match_hosts(self.pattern) if len(hosts) == 0: - return None + return { + 'contacted' : {}, + 'dark' : {} + } # attack pool of hosts in N forks # _executor_hook does all of the work