Skip to content

Instantly share code, notes, and snippets.

@cuibonobo
Last active March 25, 2016 07:57
Show Gist options
  • Save cuibonobo/fc950a37f6102c8e4e5c to your computer and use it in GitHub Desktop.
Save cuibonobo/fc950a37f6102c8e4e5c to your computer and use it in GitHub Desktop.
Running daemons in Python

Once a daemon is running, I need some way of communicating with it. That's where Pyro comes in. (I briefly considered running an HTTP server, but the HTTP protocol was designed to handle resources, not remote procedure calls (RPC). Plus, the overhead of an HTTP server, URL handling, and JSON parsing compared to a lightweight Pyro daemon was too much to justify if my plans were to only interact with the daemon over SSH.)

Example Pyro daemon

Example taken from http://stackoverflow.com/questions/24461167/how-can-i-cleanly-exit-a-pyro-daemon-by-client-request. (My test did not demonstrate the hangs that the OP was experiencing.)

server.py:

import Pyro4

class TestAPI:
    def __init__(self, daemon):
        self.daemon = daemon
    def hello(self, msg):
        print 'client said {}'.format(msg)
        return 'hola'
    def shutdown(self):
        print 'shutting down...'
        self.daemon.shutdown()

if __name__ == '__main__':
    daemon = Pyro4.Daemon(port=9999)
    tapi = TestAPI(daemon)
    uri = daemon.register(tapi, objectId='TestAPI')
    daemon.requestLoop()
    print 'exited requestLoop'
    daemon.close()
    print 'daemon closed'

client.py:

import Pyro4

if __name__ == '__main__':
        uri = 'PYRO:TestAPI@localhost:9999'
        remote = Pyro4.Proxy(uri)
        response = remote.hello('hello')
        print 'server said {}'.format(response)
        try:
            remote.shutdown()
        except Pyro4.errors.ConnectionClosedError:
            pass
        print 'client exiting'
@cuibonobo
Copy link
Author

For authentication purposes, you could possibly verify that the current session is being run via SSH with who am i and even extract and verify the hostname with who am i | sed 's/.*(\(.*\))/\1/g'.

@cuibonobo
Copy link
Author

Determine whether the parent process is sshd with cat /proc/$PPID/status | head -1 | cut -f2.

@cuibonobo
Copy link
Author

The server.py application should be owned by root and have -rwxr-x--x permissions. It will be launched as a daemon by system processes, so it will never be invoked by users. The client.py process will be owned by the SSH user and have -rwx------ permissions. It can only be launched by the SSH user and it will only establish communication with the server daemon if the application was launched via SSH.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment