make copy & template module take key/value parameters so we're consistent. Only the command

module works differently now

starter manpage for modules

allow template file location to be passed into template & setup modules
This commit is contained in:
Michael DeHaan 2012-02-26 19:21:44 -05:00
parent 77a7ddeebc
commit e5f62f20b1
7 changed files with 79 additions and 35 deletions

View file

@ -40,8 +40,9 @@ This module does not support change hooks.
Returns the return code from the program as well as timing information. Returns the return code from the program as well as timing information.
Async command running and command execution time limits are in plan. Async command running and command execution time limits are in plan. These will probably
be special keyvalue parameters expressed on the end of the command line, like ANSTIMEOUT=1
and ANS_ASYNC=1 or similar.
copy copy
---- ----
@ -128,10 +129,8 @@ first step in your playbook.
*metadata=*:: *metadata=*::
Optionally overrides the default JSON file location of /etc/ansible/setup. Optionally overrides the default JSON file location of /etc/ansible/setup.
If used, also supply the metadata parameter to 'template'. If used, also supply the metadata parameter to 'template'. Change if
running as a non-root remote user who does not have permissions on /etc/ansible.
Does not support change hooks yet, but in plan.
template template
@ -152,7 +151,8 @@ location to render the template on the remote server
*metadata*:: *metadata*::
location of a JSON file to use to supply template data. Default is /etc/ansible/setup location of a JSON file to use to supply template data. Default is /etc/ansible/setup
which can be easily created using the 'setup' module. which is the same as the default for the setup module. Change if running as a non-root
remote user who does not have permissions on /etc/ansible.
This module also returns md5sum information about the resultant file. This module also returns md5sum information about the resultant file.

View file

@ -2,21 +2,27 @@
hosts: '/etc/ansible/hosts' hosts: '/etc/ansible/hosts'
tasks: tasks:
- do: - do:
- configure template & module variables - configure template & module variables for future template calls
- setup a=2 b=3 c=4 - setup a=2 b=3 c=4
- do: - do:
- copy a file - copy a file from the local disk to the remote
- copy /srv/a /srv/b - copy src=/srv/a dest=/srv/b
notify: notify:
- restart apache - restart apache
- do: - do:
- template from local file template.j2 to remote location /srv/file.out - template from local file template.j2 to remote location /srv/file.out
- template /srv/template.j2 /srv/file.out - template src=/srv/template.j2 dest=/srv/file.out
notify: notify:
- restart apache - restart apache
- quack like a duck - quack like a duck
- do: - do:
- something that will fail - if running as non-root whne you template, you should specify the MD file (1)
- setup a=3 b=4 c=5 metadata=/tmp/metadata.json
- do:
- if running as non-root when you template, you should specify the MD file (2)
- template src=/srv/template.j2 dest=/srv/file2.out metadata=/tmp/metadata.json
- do:
- call something that will fail just to demo failure counts and such
- command /bin/false - command /bin/false
handlers: handlers:
- do: - do:

View file

@ -1,3 +1,4 @@
# control side (aka 'overlord')
DEFAULT_HOST_LIST = '/etc/ansible/hosts' DEFAULT_HOST_LIST = '/etc/ansible/hosts'
DEFAULT_MODULE_PATH = '/usr/share/ansible' DEFAULT_MODULE_PATH = '/usr/share/ansible'
DEFAULT_MODULE_NAME = 'ping' DEFAULT_MODULE_NAME = 'ping'

View file

@ -139,12 +139,21 @@ class Runner(object):
result = self._execute_module(conn, module) result = self._execute_module(conn, module)
return self._return_from_module(conn, host, result) return self._return_from_module(conn, host, result)
def _parse_kv(self, args):
options = {}
for x in args:
if x.find("=") != -1:
k, v = x.split("=")
options[k]=v
return options
def _execute_copy(self, conn, host): def _execute_copy(self, conn, host):
''' handler for file transfer operations ''' ''' handler for file transfer operations '''
# transfer the file to a remote tmp location # transfer the file to a remote tmp location
source = self.module_args[0] options = self._parse_kv(self.module_args)
dest = self.module_args[1] source = options['src']
dest = options['dest']
tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1]) tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1])
self._transfer_file(conn, source, tmp_dest) self._transfer_file(conn, source, tmp_dest)
@ -161,9 +170,10 @@ class Runner(object):
def _execute_template(self, conn, host): def _execute_template(self, conn, host):
''' handler for template operations ''' ''' handler for template operations '''
source = self.module_args[0] options = self._parse_kv(self.module_args)
dest = self.module_args[1] source = options['src']
metadata = '/etc/ansible/setup' dest = options['dest']
metadata = options.get('metadata', '/etc/ansible/setup')
# first copy the source template over # first copy the source template over
tempname = os.path.split(source)[-1] tempname = os.path.split(source)[-1]

View file

@ -8,14 +8,27 @@ try:
except ImportError: except ImportError:
import simplejson as json import simplejson as json
source = sys.argv[1] # ===========================================
dest = sys.argv[2] # convert arguments of form ensure=running name=foo
# to a dictionary
# FIXME: make more idiomatic
# raise an error if there is no source file args = " ".join(sys.argv[1:])
if not os.path.exists(source): items = shlex.split(args)
params = {}
for x in items:
(k, v) = x.split("=")
params[k] = v
src = params['src']
dest = params['dest']
# raise an error if there is no src file
if not os.path.exists(src):
print json.dumps({ print json.dumps({
"failed" : 1, "failed" : 1,
"msg" : "Source %s failed to transfer" % source "msg" : "Source %s failed to transfer" % src
}) })
sys.exit(1) sys.exit(1)
@ -24,7 +37,7 @@ changed = False
if os.path.exists(dest): if os.path.exists(dest):
md5sum = os.popen("md5sum %s" % dest).read().split()[0] md5sum = os.popen("md5sum %s" % dest).read().split()[0]
os.system("cp %s %s" % (source, dest)) os.system("cp %s %s" % (src, dest))
md5sum2 = os.popen("md5sum %s" % dest).read().split()[0] md5sum2 = os.popen("md5sum %s" % dest).read().split()[0]

View file

@ -1,7 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
ANSIBLE_DIR = "/etc/ansible" DEFAULT_ANSIBLE_SETUP = "/etc/ansible/setup"
ANSIBLE_SETUP = "/etc/ansible/setup"
import sys import sys
import os import os
@ -15,28 +14,30 @@ except ImportError:
# load config & template variables # load config & template variables
input_data = sys.argv[1:] input_data = sys.argv[1:]
new_options = dict([ x.split("=") for x in input_data ]) new_options = dict([ x.split('=') for x in input_data ])
ansible_file = new_options.get('metadata', DEFAULT_ANSIBLE_SETUP)
ansible_dir = os.path.dirname(metadata)
# create the config dir if it doesn't exist # create the config dir if it doesn't exist
if not os.path.exists(ANSIBLE_DIR): if not os.path.exists(ansible_dir):
os.makedirs(ANSIBLE_DIR) os.makedirs(ansible_dir)
changed = False changed = False
if not os.path.exists(ANSIBLE_SETUP): if not os.path.exists(ansible_file):
changed = True changed = True
else: else:
md5sum = os.popen("md5sum %s" % ANSIBLE_SETUP).read() md5sum = os.popen("md5sum %s" % ansible_file).read()
# write the template/settings file using # write the template/settings file using
# instructions from server # instructions from server
f = open(ANSIBLE_SETUP, "w+") f = open(ansible_file, "w+")
reformat = json.dumps(new_options) reformat = json.dumps(new_options)
f.write(reformat) f.write(reformat)
f.close() f.close()
md5sum2 = os.popen("md5sum %s" % ANSIBLE_SETUP).read() md5sum2 = os.popen("md5sum %s" % ansible_file).read()
if md5sum != md5sum2: if md5sum != md5sum2:
changed = True changed = True

View file

@ -8,9 +8,22 @@ try:
except ImportError: except ImportError:
import simplejson as json import simplejson as json
source = sys.argv[1] # ===========================================
dest = sys.argv[2] # convert arguments of form ensure=running name=foo
metadata = sys.argv[3] # to a dictionary
# FIXME: make more idiomatic
args = " ".join(sys.argv[1:])
items = shlex.split(args)
params = {}
for x in items:
(k, v) = x.split("=")
params[k] = v
source = params['src']
dest = params['dest']
metadata = params.get('metadata', '/etc/ansible/setup')
# raise an error if there is no template metadata # raise an error if there is no template metadata
if not os.path.exists(metadata): if not os.path.exists(metadata):