Files
puppet_openstack_builder/stack-builder/fragment.py
Michael Chapman d9253f14a6 Simplify signal/wait system to be more generic.
Scenario creators can now create a dependency between
nodes by adding fragments that specify a signal name
and which nodes need to wait for that signal. For an
example please see nodes/2_role.yaml
2013-10-22 15:21:26 +11:00

84 lines
3.3 KiB
Python

import os
import string
import yaml
from metadata import build_metadata
def signal_type(fragment):
if fragment[:5] == 'WAIT_':
return 'wait'
if fragment[:7] == 'SIGNAL_':
return 'signal'
return None
class PercentTemplate(string.Template):
delimiter='%'
def available_fragments(d='./stack-builder/fragments'):
return [d + '/' + f for f in os.listdir(d)]
# Create a deploy script from a list of fragments
def build_deploy(fragment_dir, frag_list, metadata):
deploy_script = ""
for f in frag_list:
sig = signal_type(f)
if sig == 'wait':
# Wait syntax is as follows:
# WAIT_signal hostname1 hostnameN
with open(fragment_dir + '/WAIT_TEMPLATE', 'r') as temp:
spl = f.split(' ')
nodes = ""
for node in spl[1:]:
# Handle debug case where there is none of this metadata
if 'ci_'+node.replace('-', '_') not in metadata:
metadata['ci_'+node.replace('-', '_')] = "{"+node+"_ip}"
print "Fragment creation: Node " + node + " IP not present in metadata: using " + "{" + node + "_ip}"
nodes = nodes + metadata['ci_'+node.replace('-', '_')] + " "
repl = { 'nodes': nodes, 'signal': spl[0].split('_')[1] }
frag = PercentTemplate(temp.read()).safe_substitute(repl)
deploy_script = deploy_script + frag + '\n'
elif sig == 'signal':
with open(fragment_dir + '/SIGNAL_TEMPLATE', 'r') as temp:
spl = f.split('_')
frag = PercentTemplate(temp.read()).safe_substitute({'signal': spl[1]})
deploy_script = deploy_script + frag + '\n'
else:
with open(fragment_dir + '/' + f, 'r') as frag:
deploy_script = deploy_script + frag.read() + '\n'
return deploy_script
def load_yaml_config(node_name, yaml_dir='./data', fragment_dir='./stack-builder/fragments', scenario='2_role'):
with open(yaml_dir+'/nodes/'+scenario+'.yaml', 'r') as yaml_file:
y = yaml.load(yaml_file.read())
if node_name not in y['nodes']:
print "No node listed for node " + node_name + " in scenario " + scenario
return None
if 'fragments' not in y['nodes'][node_name]:
print "No fragments listed for node " + node_name + " in scenario " + scenario
return None
available = available_fragments(fragment_dir)
for fragment in y['nodes'][node_name]['fragments']:
if fragment_dir + '/' + fragment not in available and not signal_type(fragment):
print "Fragment '" + fragment + "' specified in scenario " + scenario + "does not exist "
return [f for f in y['nodes'][node_name]['fragments']]
def compose(hostname, yaml_dir, fragment_dir, scenario, replacements):
fragments = load_yaml_config(hostname, yaml_dir, fragment_dir, scenario)
script = build_deploy(fragment_dir, fragments, replacements)
return PercentTemplate(script).safe_substitute(replacements)
def show(n, q, k, args):
hostname = args.node
yaml_dir = args.yaml_dir
fragment_dir = args.fragment_dir
scenario = args.scenario
print compose(hostname, yaml_dir, fragment_dir, scenario, build_metadata('./data', '2_role', 'config'))