summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael DeHaan <michael.dehaan@gmail.com>2012-04-18 22:43:17 -0400
committerMichael DeHaan <michael.dehaan@gmail.com>2012-04-18 22:43:17 -0400
commit9cd492befea21be4df1865a36076dfaf1e446c74 (patch)
tree4ce1fc0c0f57eb75d49deeb0a8c384966e709a36
parent30d06dbceaf3a240d80bae60a60a72936f59ed4f (diff)
downloadansible-9cd492befea21be4df1865a36076dfaf1e446c74.tar.gz
make all templating happen locally, so no jinja2 deps are ever required
-rwxr-xr-xlib/ansible/runner.py89
-rwxr-xr-xlibrary/template120
2 files changed, 42 insertions, 167 deletions
diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py
index 883c18860d..0b6ede1004 100755
--- a/lib/ansible/runner.py
+++ b/lib/ansible/runner.py
@@ -28,6 +28,7 @@ import traceback
import tempfile
import subprocess
import getpass
+import base64
import ansible.constants as C
import ansible.connection
@@ -456,13 +457,7 @@ class Runner(object):
if source is None or dest is None:
return (host, True, dict(failed=True, msg="src and dest are required"), '')
- if metadata is None:
- if self.remote_user == 'root':
- metadata = '/etc/ansible/setup'
- else:
- metadata = '~/.ansible/setup'
-
- # apply templating to source argument
+ # apply templating to source argument so vars can be used in the path
inject = self.setup_cache.get(conn.host,{})
source = utils.template(source, inject)
@@ -470,53 +465,45 @@ class Runner(object):
if not self.is_playbook:
- # templating remotely, since we don't have the benefit of SETUP_CACHE
- # TODO: maybe just fetch the setup file to a tempfile
-
- # first copy the source template over
- temppath = tmp + os.path.split(source)[-1]
- conn.put_file(utils.path_dwim(self.basedir, source), temppath)
-
- # install the template module
- template_module = self._transfer_module(conn, tmp, 'template')
-
- # transfer module vars
- if self.module_vars:
- vars = utils.bigjson(self.module_vars)
- vars_path = self._transfer_str(conn, tmp, 'module_vars', vars)
- vars_arg=" vars=%s"%(vars_path)
- else:
- vars_arg=""
-
- # run the template module
- args = "src=%s dest=%s metadata=%s%s" % (temppath, dest, metadata, vars_arg)
- (result1, err, executed) = self._execute_module(conn, tmp, template_module, args)
- (host, ok, data, err) = self._return_from_module(conn, host, result1, err, executed)
-
- else:
- # templating LOCALLY to avoid Jinja2 dependency on nodes inside playbook runs
- # non-playbook path can be moved to use this IF it is willing to fetch
- # the metadata file first
-
+ # not running from a playbook so we have to fetch the remote
+ # setup file contents before proceeding...
+ if metadata is None:
+ if self.remote_user == 'root':
+ metadata = '/etc/ansible/setup'
+ else:
+ metadata = '~/.ansible/setup'
+
# install the template module
- copy_module = self._transfer_module(conn, tmp, 'copy')
-
- # playbooks can template locally to avoid the jinja2 dependency
- source_data = file(utils.path_dwim(self.basedir, source)).read()
-
- resultant = ''
- try:
- resultant = utils.template(source_data, inject)
- except Exception, e:
- return (host, False, dict(failed=True, msg=str(e)), '')
- xfered = self._transfer_str(conn, tmp, 'source', resultant)
+ slurp_module = self._transfer_module(conn, tmp, 'slurp')
+
+ # run the slurp module to get the metadata file
+ args = "src=%s" % metadata
+ (result1, err, executed) = self._execute_module(conn, tmp, slurp_module, args)
+ result1 = utils.json_loads(result1)
+ if not 'content' in result1 or result1.get('encoding','base64') != 'base64':
+ result1['failed'] = True
+ return self._return_from_module(conn, host, result1, err, executed)
+ content = base64.b64decode(result1['content'])
+ inject = utils.json_loads(content)
+
+ # install the template module
+ copy_module = self._transfer_module(conn, tmp, 'copy')
+
+ # template the source data locally
+ source_data = file(utils.path_dwim(self.basedir, source)).read()
+ resultant = ''
+ try:
+ resultant = utils.template(source_data, inject)
+ except Exception, e:
+ return (host, False, dict(failed=True, msg=str(e)), '')
+ xfered = self._transfer_str(conn, tmp, 'source', resultant)
- # run the COPY module
- args = "src=%s dest=%s" % (xfered, dest)
- (result1, err, executed) = self._execute_module(conn, tmp, copy_module, args)
- (host, ok, data, err) = self._return_from_module(conn, host, result1, err, executed)
+ # run the COPY module
+ args = "src=%s dest=%s" % (xfered, dest)
+ (result1, err, executed) = self._execute_module(conn, tmp, copy_module, args)
+ (host, ok, data, err) = self._return_from_module(conn, host, result1, err, executed)
-
+ # modify file attribs if needed
if ok:
return self._chain_file_module(conn, tmp, data, err, options, executed)
else:
diff --git a/library/template b/library/template
index 31a2095e50..a290899c5c 100755
--- a/library/template
+++ b/library/template
@@ -17,120 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-import sys
-import os
-import jinja2
-import shlex
-try:
- import json
-except ImportError:
- import simplejson as json
-
-environment = jinja2.Environment()
-
-# ===========================================
-# convert arguments of form a=b c=d
-# to a dictionary
-# FIXME: make more idiomatic
-
-if len(sys.argv) == 1:
- sys.exit(1)
-argfile = sys.argv[1]
-if not os.path.exists(argfile):
- sys.exit(1)
-items = shlex.split(open(argfile, 'r').read())
-
-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')
-metadata = os.path.expanduser(metadata)
-module_vars = params.get('vars')
-
-# raise an error if there is no template metadata
-if not os.path.exists(metadata):
- print json.dumps({
- "failed" : 1,
- "msg" : "Missing %s, did you run the setup module yet?" % metadata
- })
- sys.exit(1)
-
-# raise an error if we can't parse the template metadata
-#data = {}
-try:
- f = open(metadata)
- data = json.loads(f.read())
- f.close()
-except:
- print json.dumps({
- "failed" : 1,
- "msg" : "Failed to parse/load %s, rerun the setup module?" % metadata
- })
- sys.exit(1)
-
-if module_vars:
- try:
- f = open(module_vars)
- vars = json.loads(f.read())
- data.update(vars)
- f.close()
- except:
- print json.dumps({
- "failed" : 1,
- "msg" : "Failed to parse/load %s." % module_vars
- })
- sys.exit(1)
-
-if not os.path.exists(source):
- print json.dumps({
- "failed" : 1,
- "msg" : "Source template could not be read: %s" % source
- })
- sys.exit(1)
-
-source = file(source).read()
-
-if os.path.isdir(dest):
- print json.dumps({
- "failed" : 1,
- "msg" : "Destination is a directory"
- })
- sys.exit(1)
-
-# record md5sum of original source file so we can report if it changed
-changed = False
-md5sum = None
-if os.path.exists(dest):
- md5sum = os.popen("md5sum %s" % dest).read().split()[0]
-
-try:
- # call Jinja2 here and save the new template file
- template = environment.from_string(source)
- data_out = template.render(data)
-except jinja2.TemplateError, e:
- print json.dumps({
- "failed": True,
- "msg" : e.message
- })
- sys.exit(1)
-f = open(dest, "w+")
-f.write(data_out)
-f.close()
-
-# record m5sum and return success and whether things have changed
-md5sum2 = os.popen("md5sum %s" % dest).read().split()[0]
-
-if md5sum != md5sum2:
- changed = True
-
-# mission accomplished
-print json.dumps({
- "md5sum" : md5sum2,
- "changed" : changed
-})
-
+# hey the Ansible template module isn't really a remote transferred
+# module. All the magic happens in Runner.py making use of the
+# copy module, and if not running from a playbook, also the 'slurp'
+# module.