-
Notifications
You must be signed in to change notification settings - Fork 532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrading generate_yamls.py for easier configuration automation. #506
base: dev
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,52 +9,195 @@ | |
''' | ||
|
||
import yaml, sys | ||
import argparse | ||
import os | ||
|
||
APPNAME='dyn_o_mite' | ||
CLIENT_PORT='8102' | ||
DYN_PEER_PORT=8101 | ||
DEFAULT_CLIENT_PORT='8102' | ||
DYN_PEER_PORT= '8101' | ||
MEMCACHE_PORT='11211' | ||
REDIS_PORT='6379' | ||
MAX_TOKEN = 4294967295 | ||
|
||
DEFAULT_DC = 'default_dc' | ||
|
||
# generate the equidistant tokens for the number of nodes given. max 4294967295 | ||
token_map = dict() | ||
token_item = (MAX_TOKEN // (len(sys.argv) -1)) | ||
for i in range(1, len(sys.argv)): | ||
node = sys.argv[i] | ||
token_value = (token_item * i) | ||
if token_value > MAX_TOKEN: | ||
token_value = MAX_TOKEN | ||
|
||
token_map[node] = token_value | ||
|
||
for k,v in token_map.items(): | ||
# get the peers ready, and yank the current one from the dict | ||
dyn_seeds_map = token_map.copy() | ||
del dyn_seeds_map[k] | ||
dyn_seeds = [] | ||
for y,z in dyn_seeds_map.items(): | ||
key = y.split(':') | ||
dyn_seeds.append(key[0] + ':' + str(DYN_PEER_PORT) + ':' + key[1] + ':' + DEFAULT_DC + ':' + str(z)); | ||
|
||
ip_dc = k.split(':'); | ||
data = { | ||
'listen': '0.0.0.0:' + CLIENT_PORT, | ||
'timeout': 150000, | ||
'servers': ['127.0.0.1:' + MEMCACHE_PORT + ':1'], | ||
'dyn_seed_provider': 'simple_provider', | ||
|
||
'dyn_port': DYN_PEER_PORT, | ||
'dyn_listen': '0.0.0.0:' + str(DYN_PEER_PORT), | ||
'datacenter': DEFAULT_DC, | ||
'rack': ip_dc[1], | ||
'tokens': v, | ||
'dyn_seeds': dyn_seeds, | ||
} | ||
|
||
outer = {APPNAME: data} | ||
|
||
file_name = ip_dc[0] + '.yml' | ||
with open(file_name, 'w') as outfile: | ||
outfile.write( yaml.dump(outer, default_flow_style=False) ) | ||
SECURE_SERVER_OPTION = "datacenter" | ||
READ_CONSISTENCY = "DC_ONE" | ||
|
||
|
||
|
||
if __name__ == '__main__': | ||
|
||
parser = argparse.ArgumentParser(""" | ||
Dynomite Configuration YAML Generator | ||
|
||
Script for generating Dynomite yaml configuration files for distribution with every node. | ||
generated yaml files will be outputted for each node, named as {ipaddress}.yml | ||
so cluster wide can be easily configured | ||
|
||
""") | ||
|
||
parser.add_argument('nodes', type=str, nargs='+', | ||
help=""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we get this help text down to a single line describing how to correctly format a node description? I think some extraneous stuff snuck in here. |
||
Usage: <script> publicIp:rack_name:datacenter publicIp:rack_name:datacenter ... | ||
|
||
outputs one yaml file per input node(for a single rack) | ||
restrict generation of the confs for all hosts per rack and not across rack. | ||
""") | ||
|
||
|
||
parser.add_argument( | ||
'-cp', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we go with two dashes for multi-character arguments? |
||
dest='client_port', | ||
type=str, | ||
default=DEFAULT_CLIENT_PORT, | ||
help=""" | ||
Client port to use (The client port Dynomite provides instead of directly accessing redis or memcache) | ||
Default is: {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of formatting the string ourselves, let's do |
||
|
||
Your redis or memcache clients should connect to this port | ||
""".format(DEFAULT_CLIENT_PORT) | ||
) | ||
|
||
parser.add_argument( | ||
'-o', | ||
dest='output_dir', | ||
type=str, | ||
default='./', | ||
help=""" | ||
Output directory for the YAML files, if does not exist will be created, Default is current directory (.) | ||
""" | ||
) | ||
|
||
parser.add_argument( | ||
'-sp', | ||
dest='server_port', | ||
type=str, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be an int type? |
||
default=REDIS_PORT, | ||
help=""" | ||
The port your redis or memcache will run locally on each node, assuming it's uniform, (default is: {}) | ||
""".format(REDIS_PORT) | ||
) | ||
|
||
parser.add_argument( | ||
'-pp', | ||
dest='peer_port', | ||
type=str, | ||
default=DYN_PEER_PORT, | ||
help=""" | ||
The port Dynamo clients will use to communicate with each other, (default is: {}) | ||
""".format(DYN_PEER_PORT) | ||
) | ||
|
||
parser.add_argument( | ||
'-rc', | ||
dest='read_consistency', | ||
type=str, | ||
default=READ_CONSISTENCY, | ||
choices=set(('DC_ONE', 'DC_QUORUM', 'DC_SAFE_QUORUM')), | ||
help=""" | ||
Sets the read_consistency of the cluster operation mode (default is: DC_ONLY) | ||
""" | ||
) | ||
|
||
parser.add_argument( | ||
'-sso', | ||
dest='secure_server_option', | ||
type=str, | ||
default=SECURE_SERVER_OPTION, | ||
choices=set(('none', 'rack', 'datacenter')), | ||
help=""" | ||
Type of communication between Dynomite nodes, Must be one of 'none', 'rack', 'datacenter', or 'all' (default is: {}) | ||
""".format(SECURE_SERVER_OPTION) | ||
) | ||
|
||
|
||
parser.add_argument( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and |
||
'--redis', | ||
action="store_true", | ||
default=True, | ||
help=""" | ||
Sets the data_store property to use redis (0), Default is 0. | ||
""" | ||
) | ||
|
||
parser.add_argument( | ||
'--mem', | ||
action="store_true", | ||
default=False, | ||
help=""" | ||
Sets the data_store property to use memcache (1), Default is 0. | ||
""" | ||
) | ||
|
||
|
||
args = parser.parse_args() | ||
|
||
|
||
dir = os.path.dirname(__file__) | ||
|
||
output_path = args.output_dir | ||
|
||
if os.path.isabs(dir): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error message doesn't match the test condition, which checks whether the path is absolute. |
||
print "path exists:{}".format(dir) | ||
else: | ||
output_path = os.path.join(dir, args.output_dir) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To me, if I specify |
||
if (not os.path.exists(output_path)): | ||
os.makedirs(output_path) | ||
print "creating output path %s" % output_path | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Following the Python convention of EAFP, I would do (in Python 3):
|
||
|
||
|
||
|
||
|
||
if (args.mem): | ||
data_store = 1 | ||
else: | ||
data_store = 0 | ||
|
||
# generate the equidistant tokens for the number of nodes given. max 4294967295 | ||
token_map = dict() | ||
total_nodes = len(args.nodes) | ||
token_item = (MAX_TOKEN // total_nodes) | ||
|
||
#print "token_item:{}".format(token_item) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you go through and remove any commented out code? |
||
for i in range(0, total_nodes): | ||
node = args.nodes[i] | ||
#print "Iterating node file ... > {}.yml".format(node) | ||
token_value = (token_item * (i+1)) | ||
if token_value > MAX_TOKEN: | ||
token_value = MAX_TOKEN | ||
|
||
token_map[node] = token_value | ||
|
||
for k,v in token_map.items(): | ||
# get the peers ready, and yank the current one from the dict | ||
#print "k:{} v:{}".format(k,v) | ||
dyn_seeds_map = token_map.copy() | ||
del dyn_seeds_map[k] | ||
dyn_seeds = [] | ||
for y,z in dyn_seeds_map.items(): | ||
key = y.split(':') | ||
dyn_seeds.append(key[0] + ':' + str(args.peer_port) + ':' + key[1] + ':' + key[2] + ':' + str(z)) | ||
|
||
ip_dc = k.split(':') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this would work better as |
||
#print ip_dc | ||
data = { | ||
'data_store': data_store, | ||
'listen': '0.0.0.0:' + args.client_port, | ||
'timeout': 150000, | ||
'servers': ['127.0.0.1:' + args.server_port + ':1'], | ||
'dyn_seed_provider': 'simple_provider', | ||
'read_consistency': 'DC_ONE', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this instead be |
||
'secure_server_option': args.secure_server_option, | ||
'dyn_port': args.peer_port, | ||
'dyn_listen': '0.0.0.0:' + args.peer_port, | ||
'datacenter': ip_dc[2], | ||
'rack': """{}""".format(ip_dc[1]), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason not to do just |
||
'tokens': """{}""".format(v), | ||
'dyn_seeds': dyn_seeds, | ||
} | ||
|
||
outer = {APPNAME: data} | ||
|
||
file_name = """{}.yml""".format(os.path.join(output_path, ip_dc[0])) | ||
|
||
with open(file_name, 'w') as outfile: | ||
outfile.write( yaml.dump(outer, default_flow_style=False)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just leave a reference to the fact that help is available, and not include the whole help text. Something like: