From 2c3a85902cec39a508ba106f468021de7e0a3333 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Thu, 4 Feb 2016 07:33:34 -0800 Subject: [PATCH] Fireball was removed in 2.0 (action plugin is gone). This commit removes the helper module that wouldn't work without the action module and tells users what to use instead. --- utilities/helper/_fireball.py | 38 +++++ utilities/helper/fireball.py | 282 ---------------------------------- 2 files changed, 38 insertions(+), 282 deletions(-) create mode 100644 utilities/helper/_fireball.py delete mode 100644 utilities/helper/fireball.py diff --git a/utilities/helper/_fireball.py b/utilities/helper/_fireball.py new file mode 100644 index 00000000000..ad405d57544 --- /dev/null +++ b/utilities/helper/_fireball.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2012, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +DOCUMENTATION = ''' +--- +module: fireball +short_description: Enable fireball mode on remote node +deprecated: "in favor of SSH with ControlPersist" +description: + - Modern SSH clients support ControlPersist which is just as fast as + fireball was. Please enable that in ansible.cfg as a replacement + for fireball. + - Removed in ansible 2.0. +author: + - "Ansible Core Team" + - "Michael DeHaan" +''' + +EXAMPLES = ''' +''' + diff --git a/utilities/helper/fireball.py b/utilities/helper/fireball.py deleted file mode 100644 index 97b4acc85a0..00000000000 --- a/utilities/helper/fireball.py +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2012, Michael DeHaan -# -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -DOCUMENTATION = ''' ---- -module: fireball -short_description: Enable fireball mode on remote node -description: - - This modules launches an ephemeral I(fireball) ZeroMQ message bus daemon on the remote node which - Ansible can use to communicate with nodes at high speed. - - The daemon listens on a configurable port for a configurable amount of time. - - Starting a new fireball as a given user terminates any existing user fireballs. - - Fireball mode is AES encrypted -version_added: "0.9" -options: - port: - description: - - TCP port for ZeroMQ - required: false - default: 5099 - aliases: [] - minutes: - description: - - The I(fireball) listener daemon is started on nodes and will stay around for - this number of minutes before turning itself off. - required: false - default: 30 -notes: - - See the advanced playbooks chapter for more about using fireball mode. -requirements: [ "zmq", "keyczar" ] -author: - - "Ansible Core Team" - - "Michael DeHaan" -''' - -EXAMPLES = ''' -# This example playbook has two plays: the first launches 'fireball' mode on all hosts via SSH, and -# the second actually starts using it for subsequent management over the fireball connection - -- hosts: devservers - gather_facts: false - connection: ssh - sudo: yes - tasks: - - action: fireball - -- hosts: devservers - connection: fireball - tasks: - - command: /usr/bin/anything -''' - -import os -import sys -import shutil -import time -import base64 -import syslog -import signal -import time -import signal -import traceback - -syslog.openlog('ansible-%s' % os.path.basename(__file__)) -PIDFILE = os.path.expanduser("~/.fireball.pid") - -def log(msg): - syslog.syslog(syslog.LOG_NOTICE, msg) - -if os.path.exists(PIDFILE): - try: - data = int(open(PIDFILE).read()) - try: - os.kill(data, signal.SIGKILL) - except OSError: - pass - except ValueError: - pass - os.unlink(PIDFILE) - -HAS_ZMQ = False -try: - import zmq - HAS_ZMQ = True -except ImportError: - pass - -HAS_KEYCZAR = False -try: - from keyczar.keys import AesKey - HAS_KEYCZAR = True -except ImportError: - pass - -# NOTE: this shares a fair amount of code in common with async_wrapper, if async_wrapper were a new module we could move -# this into utils.module_common and probably should anyway - -def daemonize_self(module, password, port, minutes): - # daemonizing code: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 - try: - pid = os.fork() - if pid > 0: - log("exiting pid %s" % pid) - # exit first parent - module.exit_json(msg="daemonized fireball on port %s for %s minutes" % (port, minutes)) - except OSError, e: - log("fork #1 failed: %d (%s)" % (e.errno, e.strerror)) - sys.exit(1) - - # decouple from parent environment - os.chdir("/") - os.setsid() - os.umask(022) - - # do second fork - try: - pid = os.fork() - if pid > 0: - log("daemon pid %s, writing %s" % (pid, PIDFILE)) - pid_file = open(PIDFILE, "w") - pid_file.write("%s" % pid) - pid_file.close() - log("pidfile written") - sys.exit(0) - except OSError, e: - log("fork #2 failed: %d (%s)" % (e.errno, e.strerror)) - sys.exit(1) - - dev_null = file('/dev/null','rw') - os.dup2(dev_null.fileno(), sys.stdin.fileno()) - os.dup2(dev_null.fileno(), sys.stdout.fileno()) - os.dup2(dev_null.fileno(), sys.stderr.fileno()) - log("daemonizing successful (%s,%s)" % (password, port)) - -def command(module, data): - if 'cmd' not in data: - return dict(failed=True, msg='internal error: cmd is required') - if 'tmp_path' not in data: - return dict(failed=True, msg='internal error: tmp_path is required') - if 'executable' not in data: - return dict(failed=True, msg='internal error: executable is required') - - log("executing: %s" % data['cmd']) - rc, stdout, stderr = module.run_command(data['cmd'], executable=data['executable'], close_fds=True) - if stdout is None: - stdout = '' - if stderr is None: - stderr = '' - log("got stdout: %s" % stdout) - - return dict(rc=rc, stdout=stdout, stderr=stderr) - -def fetch(data): - if 'in_path' not in data: - 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 = base64.b64encode(fh.read()) - return dict(data=data) - -def put(data): - - if 'data' not in 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(base64.b64decode(data['data'])) - fh.close() - - return dict() - -def serve(module, password, port, minutes): - - - log("serving") - context = zmq.Context() - socket = context.socket(zmq.REP) - addr = "tcp://*:%s" % port - log("zmq serving on %s" % addr) - socket.bind(addr) - - # password isn't so much a password but a serialized AesKey object that we xferred over SSH - # password as a variable in ansible is never logged though, so it serves well - - key = AesKey.Read(password) - - while True: - - data = socket.recv() - - try: - data = key.Decrypt(data) - except: - continue - - data = json.loads(data) - - mode = data['mode'] - response = {} - - if mode == 'command': - response = command(module, data) - elif mode == 'put': - response = put(data) - elif mode == 'fetch': - response = fetch(data) - - data2 = json.dumps(response) - data2 = key.Encrypt(data2) - socket.send(data2) - -def daemonize(module, password, port, minutes): - - try: - daemonize_self(module, password, port, minutes) - - def catcher(signum, _): - module.exit_json(msg='timer expired') - - signal.signal(signal.SIGALRM, catcher) - signal.setitimer(signal.ITIMER_REAL, 60 * minutes) - - - serve(module, password, port, minutes) - except Exception, e: - tb = traceback.format_exc() - log("exception caught, exiting fireball mode: %s\n%s" % (e, tb)) - sys.exit(0) - -def main(): - - module = AnsibleModule( - argument_spec = dict( - port=dict(required=False, default=5099), - password=dict(required=True), - minutes=dict(required=False, default=30), - ), - supports_check_mode=True - ) - - password = base64.b64decode(module.params['password']) - port = module.params['port'] - minutes = int(module.params['minutes']) - - if not HAS_ZMQ: - module.fail_json(msg="zmq is not installed") - if not HAS_KEYCZAR: - module.fail_json(msg="keyczar is not installed") - - daemonize(module, password, port, minutes) - - -# import module snippets -from ansible.module_utils.basic import * -main()