Broham: A simple, global, highly-available, none-too-bright service registry.
Broham always knows where his bros are, bro! Using broham, a newly-created cloud machine can annouce its availability for a certain role (“nfs_server” or “db_slave-2”), allowing any other interested nodes to discover its public_ip, private_ip, etc.
It uses Amazon’s SimpleDB service, so the registry is global, highly-available, secure, accessible from any programming language (or even curl
if you’re clever), and simple. As for Broham himself, he fills out a suit OK but isn’t too bright: there’s no monitoring or logging, for instance.
Broham plays nicely with Chef and indeed was written to coordinate node assignment for a hadoop cluster chef setup.
Examples:
require 'broham'
Settings.access_key_id = 'XXXXXXXXXX'
Settings.secret_access_key = 'XXXXXXXXXX'
# create a context for the 'chad' cluster
class Chad < Broham::Cluster ; end
Chad.establish_connection
Chad.create_domain
# On NFS server start, register an nfs share
Chad.register_nfs_share '/home'
#=> #<Chad @attributes={"timestamp"=>["20100405072638"], "client_path"=>["/home"], "server_path"=>["/home"], "role"=>["nfs_server"], "public_ip"=>["250.249.248.247"], "private_ip"=>["192.168.69.22"], "default_ip"=>["192.168.69.22"]}
# On the nfs clients, get the local IP and server-side path of the share, ready to insert into /etc/fstab
Chad.nfs_device_path
#=> "192.168.69.22:/home"
# Register as one of many nodes with a given role
Chad.register_as_next 'dj'
#=> #<Chad @attributes={"timestamp"=>["20100405072931"], "role"=>["dj-1"], "idx"=>["1"], "default_ip"=>["192.168.69.10"], "public_ip"=>["250.249.248.247"], "private_ip"=>["192.168.69.10"]}
# Find the highest-yet-registered node in the 'dj' role and immediately
# register as the next one. Even if a thundering herd of hosts try to register
# in this role, Broham will ensure that exactly one host claims each index.
Chad.host('dj') ; Chad.register_as_next 'dj'
#=> #<Chad @attributes={"timestamp"=>["20100405073626"], "role"=>["dj"], "idx"=>["2"], "default_ip"=>["192.168.69.14"], "public_ip"=>["250.249.248.247"], "private_ip"=>["192.168.69.14"]}]
#=> #<Chad @attributes={"timestamp"=>["20100405073626"], "role"=>["dj-4"], "idx"=>["4"], "default_ip"=>["192.168.69.22"], "public_ip"=>["250.249.248.247"], "private_ip"=>["192.168.69.22"]}]
Alternate interface:
Chad.yo! 'beer-stand'
#<Chad @attributes={"timestamp"=>["20100405071446"], "role"=>["beer-stand"], "public_ip"=>["250.249.248.247"], "private_ip"=>["10.0.69.69"]}
Chad.sup? 'beer-stand'
#<Chad @attributes={"timestamp"=>["20100405071446"], "role"=>["beer-stand"], "public_ip"=>["250.249.248.247"], "private_ip"=>["10.0.69.69"]}
Commandline Interface
$ broham-register chad nfs_server --set-server_path=/home --set-client_path=/home
Registering as nfs_server in chad cluster, with {:server_path=>"/home", :client_path=>"/home"}
{"timestamp":["20100405093238"],"fqdn":["nfs.infochimps.org"],"client_path":["/home"],"server_path":["/home"],"role":["nfs_server"],"private_ip":["10.123.156.231"],"default_ip":["10.123.156.231"],"public_ip":["104.136.251.50"]}
$ broham-host chad nfs_server
{"timestamp":["20100405093238"],"fqdn":["nfs.infochimps.org"],"client_path":["/home"],"server_path":["/home"],"role":["nfs_server"],"private_ip":["10.123.156.231"],"default_ip":["10.123.156.231"],"public_ip":["104.136.251.50"]}
# Alternative interface works too.
$ broham-sup chad nfs_server
{"timestamp":["20100405093238"],"fqdn":["nfs.infochimps.org"],"client_path":["/home"],"server_path":["/home"],"role":["nfs_server"],"private_ip":["10.123.156.231"],"default_ip":["10.123.156.231"],"public_ip":["104.136.251.50"]}
$ broham-unregister-all chad nfs_server
Removing nfs_server from chad cluster
{"timestamp":["20100405093238"],"fqdn":["nfs.infochimps.org"],"client_path":["/home"],"server_path":["/home"],"role":["nfs_server"],"private_ip":["10.123.156.231"],"default_ip":["10.123.156.231"],"public_ip":["104.136.251.50"]}
# Alternative interface:
broham-sup host # show host
broham-sup_yall hosts # show all hosts matching the given (start-of-string-anchored) regex
broham-yo host # register as given host
broham-diss host # unregister given host
broham-fuck_all_yall hosts_re # unregister all hosts matching the given (start-of-string-anchored) regex
IRB Usage
require 'configliere'
Settings.read('broham.yaml')
require 'broham'
require 'broham/script'
Broham.establish_connection
Broham.unregister_like 'gibbon-slave'
Setup
For setup, we recommend configliere
require 'configliere'
Configliere.use :config_file
Settings.read 'broham.yaml'; Settings.resolve!
Like Broseph Stalin, you are leading the way to the dictatorship of the broletariate. It is truly revbrolutionary. Like the Bro v. Wade of our generation. You brobliterate the enemy from the very peak of Mt. Brolympus. That’s some shit. That’s brolific. But that’s the kind of bro you are. — Zach Caldwell
Warnings!
Make sure you are using a recent (>= 1.11,0) version of right_aws, and set the SDB_API_VERSION environment variable to ‘2009-04-15’:
export SDB_API_VERSION='2009-04-15'
For register_as_next
, you’ll need a version of right_aws that supports conditional puts: http://github.com/mrflip/right_aws
Note on Patches/Pull Requests
- Fork the project.
- Make your feature addition or bug fix.
- Add tests for it. This is important so I don’t break it in a future version unintentionally.
- Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
- Send me a pull request. Bonus points for topic branches.
Copyright
Copyright © 2010 Philip (flip) Kromer. See LICENSE for details.