Blame mqtt/listen-on-dbus-for-mqtt-signals.py

0b0750
#!/usr/bin/env python3.6
0b0750
#pylint: disable=line-too-long
0b0750
#
0b0750
#  Copyright (2019).  Fermi Research Alliance, LLC.
0b0750
#  Initial Author: Pat Riehecky <riehecky@fnal.gov>
0b0750
#
0b0750
'''
0b0750
    Listen to dbus events
0b0750
'''
0b0750
0b0750
## Uncomment these for python2 support
0b0750
#from __future__ import unicode_literals
0b0750
#from __future__ import absolute_import
0b0750
#from __future__ import print_function
0b0750
0b0750
import json
0b0750
import logging
0b0750
import os.path
0b0750
import sys
0b0750
import textwrap
0b0750
0b0750
from subprocess import Popen, PIPE
0b0750
0b0750
DBUS_INTERFACE = 'org.centos.git.mqtt'
0b0750
0b0750
try:
0b0750
    from pydbus import SystemBus, SessionBus
0b0750
    from pydbus.generic import signal
0b0750
except ImportError:  # pragma: no cover
0b0750
    print("Please install pydbus - rpm: python-pydbus", file=sys.stderr)
0b0750
    raise
0b0750
0b0750
try:
0b0750
    from gi.repository.GLib import MainLoop
0b0750
except ImportError:  # pragma: no cover
0b0750
    print("Please install pygobject - rpm: python-gobject", file=sys.stderr)
0b0750
    raise
0b0750
0b0750
try:
0b0750
    from argparse import ArgumentParser
0b0750
except ImportError:  # pragma: no cover
0b0750
    print("Please install argparse - rpm: python-argparse", file=sys.stderr)
0b0750
    raise
0b0750
0b0750
##########################################
0b0750
def setup_args():
0b0750
    '''
0b0750
        Setup the argparse object.
0b0750
0b0750
        Make sure all fields have defaults so we could use this as an object
0b0750
    '''
0b0750
    parser = ArgumentParser(description=textwrap.dedent(__doc__))
0b0750
0b0750
    parser.add_argument('--debug',action='store_true',
0b0750
                        help='Print out all debugging actions',
0b0750
                        default=False)
0b0750
    parser.add_argument('--dbus-use-system-bus',action='store_true',
0b0750
                        help='Should we use the global SystemBus or the user SessionBus. The SystemBus requires settings in /etc/dbus-1/system.d/myservice.conf',
0b0750
                        default=False)
0b0750
    parser.add_argument('--run-command', metavar='<ABSOLUTE_PATH>',
0b0750
                        help='Command to run with message payload. sys.argv[1] will be the DBUS signal name, STDIN will be the payload as json. If no run command, simply print the results to STDOUT.',
0b0750
                        default='', type=str)
0b0750
0b0750
    return parser
0b0750
0b0750
##########################################
0b0750
0b0750
##########################################
0b0750
##########################################
0b0750
if __name__ == '__main__':
0b0750
0b0750
    PARSER = setup_args()
0b0750
    ARGS = PARSER.parse_args()
0b0750
0b0750
    if ARGS.run_command != '':
0b0750
        if not os.path.exists(ARGS.run_command):
0b0750
            raise ValueError('No such file %s', ARGS.run_command)
0b0750
0b0750
    MYLOGGER = logging.getLogger()
0b0750
0b0750
    if ARGS.debug:
0b0750
        MYLOGGER.setLevel(logging.DEBUG)
0b0750
    else:
0b0750
        MYLOGGER.setLevel(logging.WARNING)
0b0750
0b0750
    handler = logging.StreamHandler(sys.stderr)
0b0750
    handler.setLevel(logging.DEBUG)
0b0750
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
0b0750
    handler.setFormatter(formatter)
0b0750
    MYLOGGER.addHandler(handler)
0b0750
0b0750
    PROGRAM_NAME = os.path.basename(sys.argv[0])
0b0750
    MYLOGGER.debug('Running:%s args:%s', PROGRAM_NAME, sys.argv[1:])
0b0750
0b0750
    if ARGS.dbus_use_system_bus:
0b0750
        BUS = SystemBus()
0b0750
    else:
0b0750
        BUS = SessionBus()
0b0750
0b0750
    def signal_recieved(sender, obj, iface, signal, params):
0b0750
        ''' Define in scope so I can read ARGS '''
0b0750
        # sanitize all my single quotes
0b0750
        signal_msg = json.dumps(json.loads(params[0]))
0b0750
0b0750
        logging.debug("sender:%s object:%s iface:%s signal:%s all_params:%s signal_msg=%s", sender, obj, iface, signal, params, signal_msg)
0b0750
0b0750
        logging.debug("Running %s %s < %s", ARGS.run_command, signal, signal_msg)
0b0750
        if ARGS.run_command == '':
0b0750
            print("signal:%s signal_msg:%s" % (signal, signal_msg), file=sys.stderr)
0b0750
        else:
0b0750
            # Or you can customize this to fit your needs
0b0750
            proc = Popen([ARGS.run_command, signal], stdin=PIPE, cwd='/tmp', start_new_session=True, universal_newlines=True)
0b0750
            proc.communicate(input=signal_msg)
0b0750
            proc.wait(timeout=300)
0b0750
0b0750
    if ARGS.dbus_use_system_bus:
0b0750
        MYLOGGER.debug('Subscribing to system bus %s', DBUS_INTERFACE)
0b0750
    else:
0b0750
        MYLOGGER.debug('Subscribing to session bus %s', DBUS_INTERFACE)
0b0750
0b0750
    BUS.subscribe(iface=DBUS_INTERFACE, signal_fired=signal_recieved)
0b0750
0b0750
    # loop forever, until CTRL+C, or something goes wrong
0b0750
    try:
0b0750
        MainLoop().run()
0b0750
    except KeyboardInterrupt:
0b0750
        logging.debug('Got CTRL+C, exiting cleanly')
0b0750
        raise SystemExit