From 096607eea454070eaf00f0816e80c77515044a7a Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Wed, 14 Nov 2012 18:37:17 -0500 Subject: [PATCH] Allow fireball to transfer binary files, fixup fireball docs, make fetch work with fireball. --- docsite/rst/playbooks2.rst | 3 +-- .../runner/connection_plugins/fireball.py | 8 ++++++-- library/fireball | 16 +++++++++++----- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/docsite/rst/playbooks2.rst b/docsite/rst/playbooks2.rst index e2872b9b7fd..cb8a7c6af61 100644 --- a/docsite/rst/playbooks2.rst +++ b/docsite/rst/playbooks2.rst @@ -623,7 +623,7 @@ if you have a large number of hosts:: # set up the fireball transport - hosts: all gather_facts: False - connection: ssh + connection: ssh # or paramiko sudo: True tasks: - action: fireball @@ -631,7 +631,6 @@ if you have a large number of hosts:: # these operations will occur over the fireball transport - hosts: all connection: fireball - sudo: True tasks: - action: shell echo "Hello ${item}" with_items: diff --git a/lib/ansible/runner/connection_plugins/fireball.py b/lib/ansible/runner/connection_plugins/fireball.py index 1159814bf49..5e88ce285f0 100644 --- a/lib/ansible/runner/connection_plugins/fireball.py +++ b/lib/ansible/runner/connection_plugins/fireball.py @@ -17,6 +17,7 @@ import json import os +import base64 from ansible.callbacks import vvv from ansible import utils from ansible import errors @@ -97,8 +98,10 @@ class Connection(object): if not os.path.exists(in_path): raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) data = file(in_path).read() - + data = base64.b64encode(data) + data = dict(mode='put', data=data, out_path=out_path) + # TODO: support chunked file transfer data = utils.jsonify(data) data = utils.encrypt(self.key, data) self.socket.send(data) @@ -113,7 +116,7 @@ class Connection(object): ''' save a remote file to the specified path ''' vvv("FETCH %s TO %s" % (in_path, out_path), host=self.host) - data = dict(mode='fetch', file=in_path) + data = dict(mode='fetch', in_path=in_path) data = utils.jsonify(data) data = utils.encrypt(self.key, data) self.socket.send(data) @@ -122,6 +125,7 @@ class Connection(object): response = utils.decrypt(self.key, response) response = utils.parse_json(response) response = response['data'] + response = base64.b64decode(response) fh = open(out_path, "w") fh.write(response) diff --git a/library/fireball b/library/fireball index e3a627915ea..d8cbc4c150a 100755 --- a/library/fireball +++ b/library/fireball @@ -162,13 +162,15 @@ def command(data): return dict(stdout=stdout, stderr=stderr) def fetch(data): - if 'data' not in data: - return dict(failed=True, msg='internal error: data is required') if 'in_path' not in data: - return dict(failed=True, msg='internal error: out_path is required') + return dict(failed=True, msg='internal error: in_path is required') + + # FIXME: should probably support chunked file transfer for binary files + # at some point. For now, just base64 encodes the file + # so don't use it to move ISOs, use rsync. fh = open(data['in_path']) - data = fh.read() + data = base64.b64encode(fh.read()) return dict(data=data) def put(data): @@ -177,9 +179,13 @@ def put(data): return dict(failed=True, msg='internal error: data is required') if 'out_path' not in data: return dict(failed=True, msg='internal error: out_path is required') + + # FIXME: should probably support chunked file transfer for binary files + # at some point. For now, just base64 encodes the file + # so don't use it to move ISOs, use rsync. fh = open(data['out_path'], 'w') - fh.write(data['data']) + fh.write(base64.b64decode(data['data'])) fh.close() return dict()