{ "info": { "author": "Gareth Rushgrove", "author_email": "gareth@morethanseven.net", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Topic :: System :: Systems Administration" ], "description": "# Serf Master\n\n[![Build\nStatus](https://secure.travis-ci.org/garethr/serf-master.png)](http://travis-ci.org/garethr/serf-master)\n[![Coverage\nStatus](https://coveralls.io/repos/garethr/serf-master/badge.png?branch=master)](https://coveralls.io/r/garethr/serf-master?branch=master)\n[![Code\nHealth](https://landscape.io/github/garethr/serf-master/master/landscape.png)](https://landscape.io/github/garethr/serf-master/master)\n\n[Serf](http://www.serfdom.io/) is a very nice service discovery and\norchestration framework which allows you to write scripts to react to\ndifferent events across your infrastructure. However most of the\nexamples are simple shell scripts with lots of logic embedded in them.\nCombine that with per host configuration around registering event\nhandlers and it's easy to build a fiddly, hard to reason about\nenviroment. It doesn't have to be that way.\n\nSerf is the framework, what you built on top of it matters. I wanted\nsomething with the following properties:\n\n* Testable. I should be able to unit test the entire configuration.\n* Single package. All hosts should get the same code, with the code\n deciding what runs where.\n* Single event handler. I'd rather deal with logic about user events or\n roles within my code, rather than parameters to serf.\n* Make handlers sharable. You can simply extend `SerfHandler` and\n package up your own handlers, say `serf_master_haproxy`.\n\nSerf Master tries to do this, presented as a very small Python framework\nwith no dependencies. Here's an example:\n\n## An example\n\nImagine a cluster with a number of database servers and web servers. The\ndatabase servers have the Serf role of `db` and the web servers the Serf\nrole of `web`. We want the web servers to react whenever a new server is\nadded to the cluster (maybe to tell a load balancer to reload?) and we\nwant to be able to trigger a deploy. For the database servers we want to\nbe able to trigger a backup custom event.\n\n```python\n#!/usr/bin/env python \nfrom serf_master import SerfHandler, SerfHandlerProxy\n\nclass WebHandler(SerfHandler):\n def deploy(self):\n # run commands here to do with deployment\n\n def member_join(self):\n # maybe rebalance the load balancer\n\n\nclass DatabaseHandler(SerfHandler):\n def backup(self):\n # run commands here to do with backups\n\n\nif __name__ == '__main__':\n handler = SerfHandlerProxy()\n handler.register('web', WebHandler())\n handler.register('db', DatabaseHandler())\n handler.run()\n```\n\nThe important parts are:\n\n```python\nhandler.register('web', WebHandler())\n```\n\nThis says if the Serf role is `web` then use the `WebHandler` class for\nany events.\n\n```python\ndef member_join(self):\n```\n\nThis says for the `member-join` serf event we should execute the code\nwe write here.\n\nSee the unit tests for examples of now this can be tested.\n\n## Configuration\n\nUsing this with Serf is simple, just wire up all the event handlers to\nyour script like so:\n\n```bash\nserf agent -event-handler /opt/your/script.py\n```\n\nAlthough you could restrict the events which are managed by this handler\nthe whole point of serf-master is to move the handler definition into\ncode and away from command line flags.\n\n## Installation\n\nSerf Master is available on\n[PyPi](https://pypi.python.org/pypi/serf_master) and can be installed\nwith:\n\n pip install serf_master\n\n", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/garethr/serf-master", "keywords": "serf", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "serf_master", "package_url": "https://pypi.org/project/serf_master/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/serf_master/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/garethr/serf-master" }, "release_url": "https://pypi.org/project/serf_master/0.4/", "requires_dist": null, "requires_python": null, "summary": "helpers for writing manageable Serf handlers", "version": "0.4" }, "last_serial": 1268281, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "89c964afc361cfc2f542549271bddf96", "sha256": "a1d5918700b3dee9dd892fed75e8ead6c39dc76b00571a38e67d67749cbbd5f2" }, "downloads": -1, "filename": "serf_master-0.1.tar.gz", "has_sig": false, "md5_digest": "89c964afc361cfc2f542549271bddf96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1561, "upload_time": "2013-12-23T13:47:20", "url": "https://files.pythonhosted.org/packages/c2/be/d079d61b2d1310f0ee7c700261cde6519b083cdbdd852972c527b090e1f8/serf_master-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "1e1ab2fcd94cf3a4b0cf456d9677b1c6", "sha256": "2fbff5862c7c70158e6a076138b7b398ffef9a2b9442b17f2da8c03ff53f44f6" }, "downloads": -1, "filename": "serf_master-0.2.tar.gz", "has_sig": false, "md5_digest": "1e1ab2fcd94cf3a4b0cf456d9677b1c6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1503, "upload_time": "2013-12-23T18:58:08", "url": "https://files.pythonhosted.org/packages/00/9c/03002fad4a58e5405aa3d8f75638488e0908252d55f673e2d7a7d5ef6153/serf_master-0.2.tar.gz" } ], "0.3": [ { "comment_text": "built for Linux-3.8.0-33-generic-x86_64-with-glibc2.7", "digests": { "md5": "117d35a7c7f2c49b55fc70f82ac46887", "sha256": "1bb0bb438b55be9375212da7f944fc9ffb15c842c372aa6b962763f7bf0ae418" }, "downloads": -1, "filename": "serf_master-0.3.linux-x86_64.tar.gz", "has_sig": false, "md5_digest": "117d35a7c7f2c49b55fc70f82ac46887", "packagetype": "bdist_dumb", "python_version": "any", "requires_python": null, "size": 2218, "upload_time": "2014-03-17T22:10:35", "url": "https://files.pythonhosted.org/packages/7e/cd/8c9ac16bc8832494bf82c549d7c61a8856d7a78f6b2637fd2c35893ef564/serf_master-0.3.linux-x86_64.tar.gz" }, { "comment_text": "", "digests": { "md5": "82819e9d02f333861d3231a8e2c05dcc", "sha256": "d73de3b5bd65bfa98c3274788ff816ed59622237b73201216fd43cca5577f89b" }, "downloads": -1, "filename": "serf_master-0.3.tar.gz", "has_sig": false, "md5_digest": "82819e9d02f333861d3231a8e2c05dcc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1559, "upload_time": "2014-03-17T22:10:38", "url": "https://files.pythonhosted.org/packages/38/ea/cf0bbb74241826c0d712c0593f08d9d2ae4381f492d31ed1642633b56163/serf_master-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "5270e32e1641f76fd9406c56bd855659", "sha256": "4fc893a26a3b18722436bcfd4386cac867e8ea01cff03269bb1a6bf636df233f" }, "downloads": -1, "filename": "serf_master-0.4-py2.7.egg", "has_sig": false, "md5_digest": "5270e32e1641f76fd9406c56bd855659", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 2827, "upload_time": "2014-10-13T07:54:37", "url": "https://files.pythonhosted.org/packages/db/ef/b3bc14768c04244aeeed89edba55f156107cd56610cf21a29cf2c6f924b5/serf_master-0.4-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "e5fb1187b11a6cd7e301b5e2a38145cb", "sha256": "dd796760642dc7a6aa8e2878dad92c68a28ec8c7fe6467e0cadd00528171bc57" }, "downloads": -1, "filename": "serf_master-0.4.tar.gz", "has_sig": false, "md5_digest": "e5fb1187b11a6cd7e301b5e2a38145cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3717, "upload_time": "2014-10-13T07:54:40", "url": "https://files.pythonhosted.org/packages/26/dd/28079c454406f27ef761ca9d14be407fe9e3195d248980439181c6b33390/serf_master-0.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5270e32e1641f76fd9406c56bd855659", "sha256": "4fc893a26a3b18722436bcfd4386cac867e8ea01cff03269bb1a6bf636df233f" }, "downloads": -1, "filename": "serf_master-0.4-py2.7.egg", "has_sig": false, "md5_digest": "5270e32e1641f76fd9406c56bd855659", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 2827, "upload_time": "2014-10-13T07:54:37", "url": "https://files.pythonhosted.org/packages/db/ef/b3bc14768c04244aeeed89edba55f156107cd56610cf21a29cf2c6f924b5/serf_master-0.4-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "e5fb1187b11a6cd7e301b5e2a38145cb", "sha256": "dd796760642dc7a6aa8e2878dad92c68a28ec8c7fe6467e0cadd00528171bc57" }, "downloads": -1, "filename": "serf_master-0.4.tar.gz", "has_sig": false, "md5_digest": "e5fb1187b11a6cd7e301b5e2a38145cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3717, "upload_time": "2014-10-13T07:54:40", "url": "https://files.pythonhosted.org/packages/26/dd/28079c454406f27ef761ca9d14be407fe9e3195d248980439181c6b33390/serf_master-0.4.tar.gz" } ] }